Один и тот же файл класса в нескольких файлах .jar. Насколько это плохо?

#java #jar #duplicates

#java #jar #дубликаты

Вопрос:

У меня есть библиотека, которая записывает данные либо в текстовом, либо в двоичном формате. Он состоит из следующих трех компонентов:

  1. общие структуры данных
  2. средство записи текста (зависит от 1)
  3. запись двоичных файлов (зависит от 1)

Очевидный способ распространить это в виде файлов 3 .jar, чтобы пользователи могли включать только то, что им нужно.

Однако компонент «общие структуры данных» на самом деле состоит всего из двух небольших классов, поэтому я рассматриваю возможность создания только двух файлов .jar и включения файлов common .class в оба.

Мой вопрос: каковы потенциальные проблемы при выполнении этого?

Ответ №1:

Потенциальное несоответствие версий, о котором упоминали другие, на самом деле является одним из случаев большего набора проблем с загрузкой классов, с которыми вы можете столкнуться при развертывании одного и того же класса (ов) в разных jar.

Ошибки при загрузке классов, скорее всего, будут возникать на сервере приложений / EJB-контейнере или аналогичной установке, где несколько компонентов / приложений загружаются иерархией загрузчиков классов. Однако, если один и тот же класс загружается двумя разными загрузчиками классов, они рассматриваются JVM как совершенно разные классы! Что может привести к различным ошибкам во время выполнения, таким как LinkageError (например, если сталкиваются две разные версии одного и того же определения класса — как описано в других ответах), ClassCastException (если выполняется приведение между двумя определениями классов, загруженными разными загрузчиками классов) и т.д. Поверьте мне, ад при загрузке классов — это место, которое вы не хотите видеть.

Я бы поместил всю библиотеку в один jar, чтобы минимизировать этот риск.

Ответ №2:

Если вы выпускаете новую версию своей библиотеки, пользователь, который использует обе библиотеки (одну старую и одну новую), может получить исключения во время выполнения, когда новая библиотека получает класс от 1 из старой библиотеки (или наоборот, если она не имеет обратной совместимости). Проще всего было бы выпустить все в одном jar, чтобы у вас не возникло проблемы с этой версией.

Ответ №3:

Потенциальные проблемы заключаются в том, что в будущих версиях структуры данных между этими двумя файлами jar могут возникнуть несоответствия (скажем, из-за исправления ошибки или незначительного выпуска). В этом случае вы могли бы получить ClassDefNotFoundException, если вам нужно включить оба jar в приложение. Я бы рекомендовал либо разделить его на три файла jar, либо просто на один побольше.

Ответ №4:

Я рекомендую использовать JarJar, который представляет собой библиотеку для упаковки нескольких файлов jar в один файл jar.

Существует Ant-задача для интеграции в вашу сборку, и поэтому ваша среда сборки может просто сохранить необработанные jars, и вы можете просто выполнить простое развертывание (но не забудьте включить license.txt файлы из различных библиотек вашего дистрибутива).