[英]Detecting dependency conflicts with Maven
我有一个 maven 构建的 Java 应用程序,它引入了许多库。 应用程序在一个 git 仓库中(有自己的 Maven 构建),每个库都在自己的 git 仓库中(有自己的 Maven 构建)。 此外,应用程序和一些库都依赖于番石榴。
应用程序的 pom.xml 指定了 guava 版本 19.0:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
该应用程序还导入另一个名为 library1 的库。 library1 也依赖于番石榴。 但是 library1 的 pom.xml 指定了更高版本的 guava:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
在构建应用程序时,maven 选择了应用程序级别指定的 guava 版本。 但这导致 library1 失败,因为它期待更高版本的番石榴。
如果我们一直在使用 Grade 并试图指定这种番石榴版本的组合,我相信 gradle 会导致构建失败,这可能是正确的做法。
鉴于我们可能有具有这种版本差异的 pom.xml 文件,有没有办法设置 maven 以便它会注意到差异并且要么构建失败要么显示关于该问题的非常突出的警告?
要检测所有传递依赖项,您可以使用maven-dependency-plugin
:
mvn dependency:tree -Dverbose
它将显示项目的直接和传递依赖项。 -Dverbose
选项显示冲突。
[INFO] [dependency:tree]
[INFO] org.apache.maven.plugins:maven-dependency-plugin:maven-plugin:2.0-alpha-5-SNAPSHOT
[INFO] +- org.apache.maven.reporting:maven-reporting-impl:jar:2.0.4:compile
[INFO] | \- commons-validator:commons-validator:jar:1.2.0:compile
[INFO] | \- commons-digester:commons-digester:jar:1.6:compile
[INFO] | \- (commons-collections:commons-collections:jar:2.1:compile - omitted for conflict with 2.0)
[INFO] \- org.apache.maven.doxia:doxia-site-renderer:jar:1.0-alpha-8:compile
[INFO] \- org.codehaus.plexus:plexus-velocity:jar:1.1.3:compile
[INFO] \- commons-collections:commons-collections:jar:2.0:compile
对于不同版本的同一个库的选择:
依赖中介——这决定了当遇到多个版本作为依赖时将选择哪个版本的工件。 Maven 选择“最近的定义”。 也就是说,它使用依赖项树中与您的项目最接近的依赖项的版本。 您始终可以通过在项目的 POM 中明确声明来保证版本。 请注意,如果两个依赖版本在依赖树中的深度相同,则第一个声明获胜。
“最近的定义”意味着使用的版本将是依赖关系树中与您的项目最接近的版本。 例如,如果 A、B 和 C 的依赖关系定义为 A -> B -> C -> D 2.0 和 A -> E -> D 1.0,那么在构建 A 时将使用 D 1.0,因为来自 A 的路径到 D 到 E 较短。 您可以在 A 中显式添加对 D 2.0 的依赖以强制使用 D 2.0。
因此,如果您的库之一与其他版本的番石榴不兼容,则意味着您的依赖项不兼容。 应该更新它以使用较新的版本。
您可以在 Maven 中设置dependencyConvergence强制规则。 该规则要求依赖版本号收敛。
如果一个项目有两个依赖项 A 和 B,它们都依赖于同一个工件 C,如果 A 依赖的 C 版本与 B 依赖的 C 版本不同,则此规则将导致构建失败。
可以像这样添加规则。
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M2</version>
<executions>
<execution>
<id>enforce</id>
<configuration>
<rules>
<dependencyConvergence/>
</rules>
</configuration>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
...
</project>
可以在此处找到更多详细信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.