Maven依赖parsing(冲突)
假设我有四个项目:
- 项目A(依赖于B和D)
- B项目(依赖于D)
- 项目C(依赖于D)
- D项目
在这种情况下,如果我运行项目A,Maven将正确地解决依赖关系到D.如果我正确地理解这个Maven总是以最短的path依赖。 由于D是A的直接依赖关系,因此将使用B中指定的D。
但现在假设这个结构:
- 项目A(依赖于B和C)
- B项目(依赖于D)
- 项目C(依赖于D)
- D项目
在这种情况下,parsingD的path具有相同的深度。 发生什么事是Maven会有冲突。 我知道有可能告诉Maven他应该排除依赖关系。 但是我的问题是如何解决这样的问题。 我的意思是在现实世界的应用程序中,你有很多的依赖,可能还有很多冲突。
最佳实践解决scheme是真的排除东西还是有其他可能的解决scheme吗? 我发现很难处理,当我突然得到一个ClassNotFoundexception,因为一些版本已经改变,这导致Maven采取differend依赖。 因为知道这个事实使得猜测问题是一个依赖性冲突有点容易。
我正在使用maven 2.1-SNAPSHOT。
解决像这样的情况的maven方法是在项目的根目录中包含一个<dependencyManagement>
部分,在这里指定使用哪个版本的库。
编辑:
<dependencyManagement> <dependencies> <dependency> <groupId>foo</groupId> <artifactId>bar</artifactId> <version>1.2.3</version> </dependency> </dependencies> </dependencyManagement>
现在无论哪个版本的库foo:bar都被一个依赖项请求,版本1.2.3将始终用于这个项目和所有的子项目。
参考:
- 依赖pipe理
Maven可以处理这两种情况没有任何冲突。 当需要传递依赖关系的两个版本时,冲突将会存在。 ClassNotFoundException
描述了应用程序(或依赖项)的结果,尝试使用实际得到使用的冲突依赖项版本中不可用的类。 有多种方法可以解决这个问题。
- 根据冲突的依赖关系更新正在使用的库的版本,以便它们都依赖于该依赖关系的相同版本版本
- 将冲突的依赖项声明为你的项目与你想要包含的版本的直接依赖关系(在这个例子中,包含缺失类的那个)
- 通过POM的
<dependencyManagement>
部分指定传递依赖关系应使用哪个版本的冲突依赖项 - 显式地排除不需要的版本的冲突依赖项,使其不依赖于依赖项,这些依赖项使用
<exclusion>
这从根本上不是一个maven问题,而是一个java问题。 如果项目B和项目C需要项目D的两个不兼容版本,则不能在项目A中使用它们。
不幸的是,正如你所知,Maven解决冲突的方式是select排除哪些。
使用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(最新的fg)。 但是,如果库D不是向后兼容的,那么kukudas就说明了一个问题 – 在你的项目中不可能同时使用这两个库。
在这种情况下,可能需要在旧版本中使用B或C,这样两者都将取决于D的兼容版本。