在我看来,maven依赖插件在计算依赖列表时行为不端。
假设这3个项目:
BASE1:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>base1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
</project>
BASE2:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>base2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
组合:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>combined</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>mygroup</groupId>
<artifactId>base1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>base2</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
base1和base2都依赖于commons-lang,但每个都在不同的版本上! 组合取决于base1和base2。
在组合上调用mvn dependency:list
时,我希望在版本2.3和2.6中看到base1,base2和commons-lang,因为两者都被使用。
但实际输出是:
[INFO] The following files have been resolved:
[INFO] commons-lang:commons-lang:jar:2.3:compile
[INFO] mygroup:base1:jar:1.0-SNAPSHOT:compile
[INFO] mygroup:base2:jar:1.0-SNAPSHOT:compile
它甚至没有使用版本号最高的普通版,而只是它首先找到的版本。
我该如何避免这种情况?我需要所有依赖项。
答案 0 :(得分:3)
根据此official documentation(相关部分以粗体突出显示):
依赖关系中介 - 这决定了在遇到多个版本的工件时将使用哪个版本的依赖项。目前,Maven 2.0仅支持使用&#34;最近的定义&#34;这意味着它将在依赖树中使用与项目最接近的依赖项的版本。您可以通过在项目的POM中明确声明版本来保证版本。 请注意,如果两个依赖项版本在依赖关系树中处于相同的深度,那么直到Maven 2.0.8没有定义哪一个会赢,但是从Maven 2.0.9开始,它就是声明中的顺序。计数:第一个声明获胜。
因此,Maven选择版本2.3,因为在依赖项解析过程中首先遇到它。请注意,如果您在// map an array of promises
var deferreds = urllist.map(function(url){
// return the promise that `$.ajax` returns
return $.ajax({
url: url,
dataType: 'jsonp'
}).then(function(data){
return data.value;
})
});
$.when.apply($, deferreds).then(function(results){
// results will be array of each `data.value` in proper order
var datalist = results;
// now do whatever you were doing with original datalist
$.each(datalist....
}).fail(function(){
// Probably want to catch failure
}).always(function(){
// Or use always if you want to do the same thing
// whether the call succeeds or fails
});
模块上运行mvn dependency:tree
,它将显示使用的版本以及省略了哪个版本。
最好的解决方案是通过在其POM中声明依赖关系来明确选择combined
工件中所需的版本,以便Maven比其他版本更喜欢它:
combined
请注意,Maven不能选择两个版本,因为在这种情况下,项目的类路径上会有两个相同类的定义,这可能会在运行时导致意外问题。
答案 1 :(得分:1)
Maven从上到下扫描pom并使用它遇到的第一个版本。
假设你真的需要两个版本的commons-lang,你可以将这两个版本放在你的项目中并使用maven将它们打包到你的jar中。
然而,编译器如何知道对StringUtils.isEmpty()
的调用是否调用版本2.3或2.6?
答案 2 :(得分:1)
Maven总是使用&#34;最近的胜利来解决冲突&#34;战略。您可以运行以下命令来查看使用特定版本的原因:
mvn dependency:tree -Dverbose -Dincludes=commons-lang
有关详情,请参阅以下内容: https://maven.apache.org/plugins/maven-dependency-plugin/examples/resolving-conflicts-using-the-dependency-tree.html