2014-09-10 6 views
1

Представьте, что a пишут приложение, которое имеет 2 зависимости; позволяет называть их зависимостью A и зависимость B. Вы не контролируете ни одну из этих зависимостей; они не являются вашими библиотеками, но ваше приложение от них зависит от них. Оказывается, что зависимость A имеет зависимость от зависимостей X (версия 1.0); и B имеет зависимость от X (версия 2.0).Почему невозможно включить несколько версий одной и той же зависимости в Maven?

Согласно Maven documentation, будет использоваться Dependency посредничества решить, какие зависимости использовать:

Dependency посредничества - это определяет, какая версию зависимости будет использоваться, когда несколько версий артефакта встречается. В настоящее время Maven 2.0 поддерживает только «ближайшее определение» , что означает, что он будет использовать версию ближайшей зависимости от вашего проекта в дереве зависимостей. Вы всегда можете гарантировать версию , объявив ее явно в POM вашего проекта. Обратите внимание, что если две версии зависимостей находятся на одной и той же глубине в дереве зависимостей, , пока Maven 2.0.8 не определил, какой из них выиграть, но с Maven 2.0.9 это порядок в объявлении, который считается: первый Победа в объявлении.

Таким образом, предполагая, мы объявляем зависимость A, а затем X версия 1.0 будет использоваться в нашем приложении. Это означает, что зависимость B будет использовать X версии 1.0 во время выполнения, где она была скомпилирована против X версии 2.0. Если B использует только некоторые функции 2.0, тогда мы получим ошибку времени выполнения (NoSuchMethodError, ClassNotFoundException и т. Д.), Это не хорошо.

Чтобы «исправить» это, мы можем исключить зависимость X от зависимости A, так что вместо этого используется X версия 2.0. Но о нет! X версия 2.0 не совместима в обратном направлении, поэтому в итоге мы получаем ошибки времени выполнения от A.

Насколько я могу судить, нет способа исправить это правильно с помощью Maven. Все, что вы можете сделать, это надеяться получить исходный код одной из библиотек и исправить ее самостоятельно. Это верно?

Почему не представляется возможным для обеих версий X быть упакованы в моем приложении, так что A использует X версии 1.0, B использует X версии 2.0 и версии X имеющейся в моем приложении является то, что Maven выбирает через зависимость. Является ли это ограничением Java или ограничением Maven? Является ли эта ситуация распространенной? Есть ли другие возможные решения? Должны ли все библиотеки гарантировать обратную совместимость, чтобы избежать этой проблемы?

ответ

2

Два класса с одинаковым именем не могут быть загружены в один загрузчик классов. Если бы Maven разрешил вам иметь несколько версий одного и того же артефакта, это, несомненно, произойдет. Итак, это проблема Java, которую Maven поддерживает.

Я не уверен, что есть все это.Если вы контролировали A или B, вы можете использовать затенение, чтобы переименовать ваше использование X в нечто такое, что не столкнулось бы, как описано в What is the maven-shade-plugin used for, and why would you want to relocate java packages?.

В целом, нужно надеяться, что обратная совместимость поддерживается между библиотеками и хорошо проверит полученное приложение, чтобы убедиться, что проблем нет. Очевидно, вы хотели бы настроить Maven на включение x-2.0, а не x-1.0, либо путем перечисления B сначала, либо путем перечисления X в вашем POM.

Слово предупреждения: большинство версий именования позволяют прерывать изменения между 1.x.x и 2.x.x, так что вы можете столкнуться с проблемами. Некоторые проекты Maven (например, Apache Commons Lang) будут использовать новый идентификатор артефакта и структуру пакета, когда они изменят основную версию, чтобы избежать этих конфликтов.

Смежные вопросы