假设我有四个项目:
在这种情况下,如果我运行项目 A,Maven 将正确解析对 D 的依赖关系。如果我理解正确,Maven 总是采用最短路径的依赖关系。由于 D 是 A 的直接依赖项,因此将使用 B 中指定的 D。
但现在假设这个结构:
在这种情况下,解析 D 的路径具有相同的深度。发生的情况是 Maven 会发生冲突。我知道可以告诉 Maven 他应该排除依赖项。但我的问题是如何解决此类问题。我的意思是,在现实世界的应用程序中,您有很多依赖项,也可能有很多冲突。
最佳实践解决方案真的是排除某些东西还是有其他可能的解决方案?当我突然收到 ClassNotFound Exception 时,我发现很难处理,因为某些版本已更改,这导致 Maven 采用不同的依赖项。当然,了解这个事实可以更容易地猜测问题是依赖冲突。
我正在使用 maven 2.1-SNAPSHOT。
<dependencyManagement>
部分,您可以在其中指定将使用哪个库的版本。编辑:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
</dependencyManagement>
现在,无论依赖项请求哪个版本的库 foo:bar,该项目和所有子项目都将始终使用版本 1.2.3。
参考:
ClassNotFoundException
是应用程序(或依赖项)尝试使用实际使用的冲突依赖项版本中不可用的类的结果。 有多种方法可以解决该问题。
<dependencyManagement>
部分指定传递依赖项应使用哪个版本的冲突依赖项
<exclusion>
显式排除冲突依赖项的不需要版本,使其不包含在依赖它们的依赖项中
不幸的是,正如您所知,解决此类冲突的 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>
在这种情况下,可能需要在旧版本中使用 B 或 C,以便两者都依赖于 D 的兼容版本。