Разрешение зависимостей Maven (противоречие)
допустим, у меня есть четыре проекта:
- проект A (имеет зависимость от B и D)
- проект B (имеет зависимость от D)
- Проект C (имеет зависимость от D)
- Проект D
в этом случае, если я запускаю проект A, Maven правильно разрешит зависимость до D. Если я правильно понимаю, что Maven всегда принимает зависимость с кратчайшим путем. Поскольку D является прямой зависимостью от A, он будет использоваться скорее затем D, который указан в Б.
но теперь предположим, что это structre:
- проект A (имеет зависимость от B и C)
- проект B (имеет зависимость от D)
- Проект C (имеет зависимость от D)
- Проект D
в этом случае пути к разрешению D имеют одинаковую глубину. Что происходит, так это то, что у Maven будет конфликт. Я знаю, что можно сказать Maven, что он должен исключить зависимости. Но мой вопрос в том, как решить такого рода проблемы. Я имею в виду, что в реальном приложении у вас есть много depenendcies и, возможно, много конфликтов.
является ли лучшим практическим решением действительно исключить материал или есть другие возможные решения для этого? Мне очень трудно справиться с тем, когда я внезапно получаю исключение ClassNotFound, потому что некоторые версии изменились, что заставило Maven принять зависимость differend. Конечно, зная этот факт, становится немного легче предположим, что проблема заключается в конфликте зависимостей.
Я использую Maven 2.1-SNAPSHOT.
5 ответов:
maven способ разрешения подобных ситуаций заключается в том, чтобы включить
<dependencyManagement>раздел в корневом pom вашего проекта, где вы указываете, какая версия какой библиотеки будет использоваться.EDIT:
<dependencyManagement> <dependencies> <dependency> <groupId>foo</groupId> <artifactId>bar</artifactId> <version>1.2.3</version> </dependency> </dependencies> </dependencyManagement>теперь независимо от того, какая версия библиотеки foo:bar запрашивается зависимостью, версия 1.2.3 всегда будет использоваться для этого проекта и всех подпроектов.
ссылки:
Maven может обрабатывать обе ситуации без каких-либо конфликтов. Конфликты будут существовать, когда требуются две версии транзитивной зависимости. Элемент
ClassNotFoundExceptionвы описываете результаты приложения (или зависимости), пытающегося использовать класс, недоступный в версии конфликтной зависимости, которая фактически используется. Существует несколько способов решить эту проблему.
- обновите версии библиотек, которые вы используете, которые зависят от конфликтной зависимости, чтобы они все зависит от одной и той же версии версии этой зависимости
- объявите конфликтную зависимость как прямую зависимость вашего проекта от версии, которую вы хотите включить (в Примере с отсутствующим классом, включенным в него)
- укажите, какую версию конфликтной зависимости должны использовать транзитивные зависимости, через ПМ
- явно исключить нежелательные версии конфликтной зависимости из бытия входит в зависимости, которые полагаются на них с помощью
<exclusion>
это принципиально не проблема maven, а проблема java. Если проект B и Проект C нуждаются в двух несовместимых версиях проекта D, то вы не можете использовать их оба в проекте A.
Maven способ разрешения подобных конфликтов, к сожалению, как вы уже знаете, чтобы выбрать, какие из них исключить.
используя
mvn dependency:analyzeиmvn dependency:treeпомогает в поиске, какие конфликты у вас есть.
вы можете исполнение последовательные зависимости во всем проекте с правилом Сходимость Зависимостей.
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.3.1</version> <executions> <execution> <id>enforce</id> <configuration> <rules> <DependencyConvergence/> </rules> </configuration> <goals> <goal>enforce</goal> </goals> </execution> </executions> </plugin>
одна из возможных стратегий-указать для основного проекта, какую версию D использовать (самую новую f.g.). Однако, если библиотека D не является обратно совместимой, у вас есть проблема, как указано kukudas - невозможно использовать обе библиотеки в вашем проекте.
в такой ситуации может потребоваться использовать либо B, либо C в более старой версии, так что оба будут зависеть от совместимых версий D.
Comments