Что происходит, когда двум Java-фреймворкам нужен третий, а каждому из двух нужна своя версия третьего? - PullRequest
13 голосов
/ 11 января 2010

В моем Java-проекте я использую две разные фреймворки (скажем, A.jar и B.jar), и обе они требуют одну общую фреймворк (скажем, Log4j.jar), но в двух разных версиях. Как это лечится Java, если фреймворку A нужен Log4J v1.1, а B нужен Log4j v1.2? Это вызовет какой-то конфликт / ошибку или будет каким-то образом (как?) Разрешено?

Если это не приведет к конфликту / ошибке (мой проект может быть скомпилирован и запущен) - могу ли я сам использовать любую версию Log4j в этом проекте? Или я вынужден выбрать меньшую / большую версию Log4j?

Обновление: , чтобы быть более конкретным ... Что если некоторая часть API Log4j изменилась в v1.2 (скажем, изменилась сигнатура одного метода doIt ()), и A и B вызывают doIt. Что произойдет? Будет ли запущен мой проект? Будет ли сбой при первом использовании doIt? Какую версию Log4j я должен поставить на classpath - v1.2 или обе?

Ответы [ 4 ]

11 голосов
/ 11 января 2010

В схеме загрузки плоского класса отсутствует поддержка версий библиотеки. Вам необходимо использовать самую последнюю версию библиотеки и удалить другие версии из пути к классам.

Некоторые платформы, такие как OSGi, предоставляют механизмы для обработки этих случаев, но неясно, что вы полагаетесь на плагинную структуру.


Edit:

Что, если какая-то часть API Log4j изменилась в v1.2 (скажем, один единственный метод doIt() подпись изменилась), и A и B вызывают doIt. Что случится? Будет ли запущен мой проект? Сбой при первом использовании doIt?

Вызов, основанный на отсутствующей подписи, скорее всего, приведет к NoSuchMethodError. Это, вероятно, не произойдет, пока метод не будет вызван. Другие ошибки могут возникать, если другие механизмы полагаются на подпись (например, наследование класса).

Какую версию Log4j я должен поставить на classpath - v1.2 или обе?

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

3 голосов
/ 11 января 2010

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

Но я сомневаюсь, что это стоит того, так как несколько версий log4j напрямую не требуются вашему коду. В вашем случае я бы посоветовал начать с использования более новой версии log4j (v1.2) и проверить, не вызовет ли это каких-либо проблем для фреймворка A. Если это вызовет конфликт, то перейдите к log4j v1.1 проверьте еще раз. Если вам действительно не повезло, вам нужно испачкать руки ...

Обновление : для вашего конкретного описания нет способа использовать log4j v1.1 или v1.2, так как для фреймворка A и B каждая требует разной подписи. Вы должны накатить свою собственную версию любого из log4j или framework A или B.

3 голосов
/ 11 января 2010

Если вам повезет выбрать одну из сторонних банок, это просто сработает. В конце нужен контейнер, который понимает и позволяет сосуществовать версиям всех компонентов, что-то вроде OSGI.

0 голосов
/ 11 января 2010

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

Оптимальным решением будет получить последние версии как A, так и B, где обе используют последние общие библиотеки

...