Maven选择间接依赖的不一致版本:为什么,以及如何预防?

时间:2013-01-24 07:04:51

标签: maven dependency-management

我们遇到Maven选择间接依赖的不一致版本的情况,我想了解原因,以及如何在将来阻止这种情况。

我们的pom.xml文件具有以下依赖项:

<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-jpa</artifactId>
  <version>1.1.0.RELEASE</version>
</dependency> 
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>3.1.2.RELEASE</version>
</dependency>

但没有直接依赖spring-core。

两者都依赖于spring-core:spring-web 3.1.2.RELEASE依赖于spring-core 3.1.2.RELEASE(参见its pom-file),而spring-data-jpa 1.1.0.RELEASE依赖于任意3.x版本的spring-core(准确[3.0.7.RELEASE,4.0.0.RELEASE],请参阅its pom-file)。

结合两者,我希望Maven选择spring-core版本3.1.2.RELEASE。但是,它。相反,它选择范围[3.0.7.RELEASE,4.0.0.RELEASE)中的最高值,目前为3.2.0.RELEASE。

(复制方案:将the above pom.xml file(gist)放在自己的目录中,然后运行mvn dependency:tree -Dverbose=true:对我来说,结果是this tree(gist)。我得到两个相同的结果Linux上的Maven 2.2.1和Windows上的Maven 3.0.4。)

这似乎是错误的,因为不一致:使用spring-web的pom文件不允许的spring-core版本。

(当spring-core 3.2.0.RC1可用时,我们就出现了这种情况:在下一次更新时突然被选中,我们很幸运,因为spring-core 3.1和spring之间的不兼容变化,我们遇到了构建错误3.2。但下次我们可能不那么幸运,并且运行时错误非常难以追踪。)

Urghh :我只是注意到 <dependency>声明的顺序很重要:如果我先将spring-web放入,那么spring-core 3.1.2。已选择RELEASE 。是什么给了什么?

问题:我们如何让Maven选择间接依赖的一致版本,或至少警告它是否做出与pom文件中指定的版本相反的选择?

更新:我在这里要求一般解决方案。对于这种特定情况,我知道我可以通过在<dependencyManagement>中添加依赖项来获得正确的行为,指定我总是需要spring-core 3.1.2.RELEASE。但是,我希望Maven在没有这些具体声明的情况下做Right Thing(TM)。

2 个答案:

答案 0 :(得分:7)

你所期待的似乎是逻辑,但Maven没有机会这样做。它只是在不知道spring-data-jpa可能与spring-core有关的情况下解析依赖关系。

依赖项解析的工作方式为描述here,并且是您已经描述的方式:

  

依赖关系中介 - 这决定了依赖关系的版本   将在遇到多个版本的工件时使用。   目前,Maven 2.0仅支持使用“最近定义”   这意味着它将使用最接近的依赖版本   您的项目在依赖树中。你可以随时保证   版本通过在项目的POM中明确声明它。请注意,如果   两个依赖版本在依赖关系树中处于相同的深度,   直到Maven 2.0.8没有定义哪一个会赢,但从那以后   Maven 2.0.9这是声明中的顺序:第一个   宣言获胜。

所以我认为防止这种情况的唯一方法就是要注意它并在你自己的pom中明确地设置你需要的版本。

顺便说一句,为什么你认为“这似乎是错误的,因为它是不一致的:使用spring-core的版本,弹簧网的pom文件不允许。”?< / p>

<version>x.y</version>的版本规范只是推荐使用此版本的推荐(请参阅“注释”here)。如果您打算强制使用此版本,则必须设置<version>[x.y]</version>

答案 1 :(得分:0)

在依赖项声明中,您可以添加部件以定义不为此依赖项导入的间接依赖项。