JAR Hell Hacks для разработчиков, не являющихся OSGi - PullRequest
2 голосов
/ 23 сентября 2011

Редактировать : После просмотра пьесы, пример, который я использовал ниже, является tad , вводящим в заблуждение. Я ищу случай, когда у меня есть две сторонних банки (не доморощенные банки, где у меня есть доступ к исходному коду), которые обе зависят от разных версий одной и той же банки.


Оригинал: Поэтому я недавно ознакомился с тем, что такое OSGi и какие проблемы («JAR Hell») он решает по своей сути. И, несмотря на то, что я заинтригован этим (и планирую мигрировать куда-то по дороге), у меня просто нет того, чтобы начать изучать, что потребуется, чтобы привести мои проекты к этому.

Итак, я сейчас оплакиваю: если со мной случится ад JAR, как мне решить эту проблему без OSGi?

Очевидно, что решение почти будет включать , чтобы написать свой собственный ClassLoader, но мне трудно представить, как это проявится, и, что более важно, как это решит проблему , Я провел некоторое исследование, и все согласились с тем, что вам нужно написать свой собственный ClassLoader для каждого создаваемого вами JAR-файла, но, поскольку мне уже трудно смотреть на этот лес сквозь деревья, это утверждение не затонуло для меня.

Может ли кто-нибудь привести конкретный пример того, как написание моего собственного ClassLoader повлияло бы на эту зияющую рану пластырем (я знаю, я знаю, единственное реальное решение - это OSGi)?

Скажем, я пишу новый JAR-файл под названием SuperJar-1.0.jar, который делает все виды удивительных вещей. Скажем, у моего SuperJar-1.0.jar есть две другие зависимости, Fizz-1.0.jar и Buzz-1.0.jar. Банки Fizz и Buzz зависят от log4j, за исключением того, что Fizz-1.0.jar зависит от log4j-1.2.15.jar, тогда как Buzz-1.0.jar зависит от log4j-1.2.16.jar. Две разные версии одной и той же банки.

Как решение на основе ClassLoader может решить эту проблему (в двух словах)?

Ответы [ 3 ]

4 голосов
/ 23 сентября 2011

Если вы задаете этот вопрос из «Я создаю приложение, как мне избежать этой» проблемы, а не «Мне нужно это конкретное решение», я бы настоятельно предпочел подход Maven, а именно: разрешить только одну версию любой данной зависимости. В случае log4j 1.2.15 -> 1.2.16 это будет работать нормально - вы можете включить только 1.2.16. Поскольку более старая версия совместима с API (это просто выпуск патча), весьма вероятно, что Fizz 1.0 даже не заметит, что использует более новую версию, чем ожидалось.

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

3 голосов
/ 29 сентября 2011

Но это как раз то, с чем должны работать все серверы приложений.Представьте, что ваши Fizz и Buzz - это веб-приложения (WAR), а Super-Jar - ваш сервер приложений.Super-Jar организует загрузчик классов для каждого веб-приложения, которое «нарушает» нормальную модель делегирования, то есть он будет смотреть локально (вниз), прежде чем искать иерархию.Читайте об этом в любой документации appservers.Например http://download.oracle.com/docs/cd/E19798-01/821-1752/beade/index.html.

0 голосов
/ 29 сентября 2011

Использовать log4j-1.2.16 . Он содержит только исправления ошибок в версии 1.2.15.

Если Fizz сломается с веткой 1.2.16, и исправит ее , отправьте эти исправления автору Fizz.

Альтернатива создания пользовательских загрузчиков классов со специальной логикой делегирования очень сложна и может вызвать много проблем. Я не понимаю, почему вы хотели бы сделать это, а не просто использовать OSGi. Рассматривали ли вы создание встроенного OSGi-фреймворка, чтобы вам не приходилось конвертировать все ваше приложение?

...