Имеется один дочерний модуль testA
, который зависит от vaadin-client-compiler, который зависит от commons-lang3 версии 3.1, он также зависит от другого дочернего модуля testB
, который зависит от commons-lang3 версии 3.4.
Я ожидаю, что testA
будет использовать версию 3.4, потому что testB
зависит от нее, но использует версию 3.1. Я могу решить эту проблему, добавив []
в версию проекта testB
, но почему это происходит? Почему maven не разрешает правильную версию без принуждения?
MCVE:
Родитель:
<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<packaging>pom</packaging>
<modules>
<module>testB</module>
<module>testA</module>
</modules>
</project>
Ребенок, который зависит
<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<version>7.6.8</version>
<artifactId>vaadin-client-compiler</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>testB</groupId>
<artifactId>testB</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<groupId>testA</groupId>
<artifactId>testA</artifactId>
</project>
И зависимый ребенок
<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>testB</groupId>
<artifactId>testB</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
</dependencies>
</project>
@PaulBastide Это MCVE, мои настоящие проекты более сложные. Как я уже сказал в своем вопросе, у меня есть решение, я спрашиваю, почему это происходит.
@PaulBastide Даже с этим примером я не согласен с вашим предложением. Я использую и мне нужна версия 3.4 в testB
, и именно там она должна быть указана, я не использую ее в других модулях. vaadin-client-compiler
, о котором я даже не подозревал, прежде чем столкнулся с этой проблемой.
Почему я получаю голоса против? Это действительно оскорбляет мои чувства.
Решение состоит в том, чтобы использовать dependencyManagement, как упомянуто @PaulBastide, объяснение дается в ответе ....
@khmarbaise Использование [3.4]
также является решением, упомянутым мной в моем вопросе.
Я не могу рекомендовать это использовать ... лучше определить его через dependencyManagement
@khmarbaise Да, я согласен с этим. Вам больше смысла определять его в testA
или в родительском поме?
Сделайте это в родительском pom, чтобы все дети могли использовать его без головной боли ...
Согласно Документация Maven:
[Maven] will use the version of the closest dependency to your project in the tree of dependencies.
а также
if two dependency versions are at the same depth in the dependency tree, until Maven 2.0.8 it was not defined which one would win, but since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins.
Итак, ответ на ваш вопрос - потому что вы определили зависимость vaadin-client-compiler
до зависимости testB
, а зависимость от commons-lang3
имеет такую же глубину в дереве из testA
.
Если вы измените порядок ваших зависимостей в testA
, вы увидите, что теперь он использует версию commons-lang3
3.4 (при условии, что вы используете версию Maven 2.0.9 или новее).
Спасибо, по какой-то причине я подумал, что maven принимает во внимание версию зависимости и использует более позднюю, вот как я бы ее реализовал. Если бы это было сделано таким образом, вероятность того, что что-то сломается, будет меньше.
Добро пожаловать, но я не уверен, что использование последней версии значительно снижает риск возникновения проблем. Это действительно зависит от того, как разработчики писали код и планировали ли они и тестировали ли они обратную совместимость.
вы должны установить dependencymanagement в родительском pom и управлять версией там.