我们遇到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)。
答案 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)
在依赖项声明中,您可以添加部件以定义不为此依赖项导入的间接依赖项。