maven 依赖插件忽略依赖版本?
maven dependency plugin ignores dependency versions?
在我看来,maven 依赖插件在计算依赖列表时出现了错误。
假设这 3 个项目:
base1:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>base1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
</project>
base2:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>base2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
合并:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>combined</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>mygroup</groupId>
<artifactId>base1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>base2</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
base1 和 base2 都依赖于 commons-lang,但每个都依赖于不同的版本!
组合取决于 base1 和 base2。
在组合调用 mvn dependency:list
时,我希望在版本 2.3 和 2.6 中看到 base1、base2 和 commons-lang,因为它们都被使用了。
然而实际输出是:
[INFO] The following files have been resolved:
[INFO] commons-lang:commons-lang:jar:2.3:compile
[INFO] mygroup:base1:jar:1.0-SNAPSHOT:compile
[INFO] mygroup:base2:jar:1.0-SNAPSHOT:compile
它甚至没有使用版本号最高的通用语言,而是使用它首先找到的那个。
我怎样才能避免这种情况?我需要所有依赖项。
Maven 从上到下扫描 pom,并使用它遇到的第一个版本。
假设您确实需要 commons-lang 的两个版本,您可以将这两个版本放在您的项目中,然后使用 maven 将它们打包到您的 jar 中。
然而,编译器如何知道对 StringUtils.isEmpty()
的调用调用的是版本 2.3 还是 2.6?
Same discussion here.
Maven 总是使用 "nearest wins" 策略解决冲突。您可以运行以下命令查看为什么使用特定版本:
mvn dependency:tree -Dverbose -Dincludes=commons-lang
有关详细信息,请参阅以下内容:
https://maven.apache.org/plugins/maven-dependency-plugin/examples/resolving-conflicts-using-the-dependency-tree.html
据此official documentation(相关部分以粗体突出显示):
Dependency mediation - this determines what version of a dependency will be used when multiple versions of an artifact are encountered. Currently, Maven 2.0 only supports using the "nearest definition" which means that it will use the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that 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.
因此,Maven 选择了 2.3 版本,因为它是在依赖解析过程中最先遇到的。请注意,如果您在 combined
模块上 运行 mvn dependency:tree
,它将显示使用了哪个版本以及省略了哪个版本。
最好的解决方案是在 combined
工件中明确选择您想要的版本,方法是在其 POM 中声明依赖关系,以便 Maven 比其他版本更喜欢它:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>combined</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>mygroup</groupId>
<artifactId>base1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>base2</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency> <!-- This will override the versions in base1 and base2 -->
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
请注意,Maven 无法选择两个版本,因为在这种情况下,您项目的类路径中的同一个 类 会有两个定义,这可能会在 运行 时导致意外问题。
在我看来,maven 依赖插件在计算依赖列表时出现了错误。
假设这 3 个项目:
base1:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>base1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
</project>
base2:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>base2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
合并:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>combined</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>mygroup</groupId>
<artifactId>base1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>base2</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
base1 和 base2 都依赖于 commons-lang,但每个都依赖于不同的版本! 组合取决于 base1 和 base2。
在组合调用 mvn dependency:list
时,我希望在版本 2.3 和 2.6 中看到 base1、base2 和 commons-lang,因为它们都被使用了。
然而实际输出是:
[INFO] The following files have been resolved:
[INFO] commons-lang:commons-lang:jar:2.3:compile
[INFO] mygroup:base1:jar:1.0-SNAPSHOT:compile
[INFO] mygroup:base2:jar:1.0-SNAPSHOT:compile
它甚至没有使用版本号最高的通用语言,而是使用它首先找到的那个。
我怎样才能避免这种情况?我需要所有依赖项。
Maven 从上到下扫描 pom,并使用它遇到的第一个版本。
假设您确实需要 commons-lang 的两个版本,您可以将这两个版本放在您的项目中,然后使用 maven 将它们打包到您的 jar 中。
然而,编译器如何知道对 StringUtils.isEmpty()
的调用调用的是版本 2.3 还是 2.6?
Same discussion here.
Maven 总是使用 "nearest wins" 策略解决冲突。您可以运行以下命令查看为什么使用特定版本:
mvn dependency:tree -Dverbose -Dincludes=commons-lang
有关详细信息,请参阅以下内容: https://maven.apache.org/plugins/maven-dependency-plugin/examples/resolving-conflicts-using-the-dependency-tree.html
据此official documentation(相关部分以粗体突出显示):
Dependency mediation - this determines what version of a dependency will be used when multiple versions of an artifact are encountered. Currently, Maven 2.0 only supports using the "nearest definition" which means that it will use the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that 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.
因此,Maven 选择了 2.3 版本,因为它是在依赖解析过程中最先遇到的。请注意,如果您在 combined
模块上 运行 mvn dependency:tree
,它将显示使用了哪个版本以及省略了哪个版本。
最好的解决方案是在 combined
工件中明确选择您想要的版本,方法是在其 POM 中声明依赖关系,以便 Maven 比其他版本更喜欢它:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>combined</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>mygroup</groupId>
<artifactId>base1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>base2</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency> <!-- This will override the versions in base1 and base2 -->
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
请注意,Maven 无法选择两个版本,因为在这种情况下,您项目的类路径中的同一个 类 会有两个定义,这可能会在 运行 时导致意外问题。