Java Classloader - как ссылаться на разные версии банки - PullRequest
19 голосов
/ 12 октября 2009

Это распространенная проблема. Я использую 2 библиотеки A.jar и B.jar , и они зависят от разных версий одной и той же банки.
Допустим, во время выполнения мне нужно THIS.x.x.x.jar

MY.jar   
     -> A.jar -> THIS.1.0.0.jar
     -> B.jar -> C.jar -> THIS.5.0.0.jar

Я могу скомпилировать конкретный jar (A.jar / B.jar) в зависимости от его зависимости, но во время выполнения мне нужно загрузить только 1 версию. Какой?
Загрузка только 1 зависимости (последняя версия) означает, что мой код, вероятно, будет выдавать исключения времени выполнения, если библиотеки не являются обратно совместимыми (есть ли там библиотеки с обратной совместимостью?).

В любом случае, я знаю, что что-то вроде OSGi может решить эту проблему.
Мне интересно, каков старый способ решения подобных проблем ...

Большое спасибо

Ответы [ 5 ]

7 голосов
/ 12 октября 2009

«Старый способ», который вы упомянули (и тот, который OSGI, безусловно, использует под капотом), заключается в установке собственного ClassLoader для обеих ветвей ваших зависимостей. Так, например, серверы приложений могут запускать как старые, так и более новые версии одного и того же приложения внутри одной JVM.

Читайте об иерархии загрузчиков классов.

В вашей настройке сложная часть - это точка соединения, где встречаются классы из обеих ветвей. Ни одна из ветвей не может использовать классы, загруженные в другую. Чтобы заставить его работать, убедитесь, что только классы, загруженные загрузчиком загрузчиков классов (классы JRE) или загрузчик классов MY.jar, передаются в обе ветви.

4 голосов
/ 12 октября 2009

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

Посмотрите эту вводную статью Javaworld для получения дополнительной информации.

Чтобы решить эту проблему без OSGi, необходимо вручную компилировать и запускать совместимые файлы jar. Как вы обнаружили, это не обязательно тривиальная задача. Поскольку банки не обязательно идентифицируют свои версии, единственный надежный способ сделать это для записи / сравнения контрольных сумм или подписей.

1 голос
/ 13 февраля 2016

Для ссылки на базовую проверку «старой» реализации https://github.com/atulsm/ElasticsearchClassLoader

Это обеспечивает подход для работы с несовместимыми версиями использования клиентаasticsearch.

1 голос
/ 12 октября 2009

Как упомянуто KLE, подход по умолчанию должен зависеть от более новой версии. Там нет никаких гарантий, но большую часть времени это работает. Вероятно, лучший способ (будучи раздутым) - использовать OSGI, чтобы преодолеть это.

1 голос
/ 12 октября 2009

Многие библиотеки обратно совместимы. Но не все ..


Старый способ - пытаться зависеть только от одной версии.

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

При необходимости вы можете немного изменить свою библиотеку, которая работает со старой зависимостью ...
Для этого потребуется доступ к источнику ...


Обратите внимание, что совместимость во время компиляции также не гарантирует правильного поведения во время выполнения. Это один шаг, тогда вы можете:

  • прочитайте файл WhatsNew для новой версии jar
  • поищите в Интернете пользователей, сообщающих о проблемах совместимости
  • написать JUnits
  • сравнить коды в обоих банках
...