默认规范应组成以下:java
<major>.<minor>.<revision>([ -<qualififer> ] | [ -<build> ])
git
这里:github
对于排序,将依次进行如下操做,直到找到不相等的元素:web
限定词不区分大小写的字符串比较api
Maven根据最近胜利策略(nearest wins strategy)的原则工做,同时解决依赖冲突,这意味着它在依赖树中找到更接近的版本,它将采用该版本并忽略其余版本。实际上Maven有点懒,因此每当它开始寻找依赖时,它就会从根目录开始遍历树,不管它先前找到哪一个版本,它都会选择它并从它们返回而不进一步。若是它进一步寻找依赖版本,可能会有机找到一些更新的版本,但它从第一个发现的版本那里返回,并采用旧版本并用它来解决依赖关系。maven
能够用下面的命令显示依赖树:ide
mvn dependency:tree
老实说,这不是maven的错,由于它想尽快完成这项工做。最重要的是,maven 不知道你的应用程序指望哪一个版本,因此Maven会告诉你,嘿,你有责任让我知道你想要哪一个版本,若是你不告诉我,我会以本身的方式工做,即更近更好。ui
请下载本文的github源代码:spa
https://github.com/yujiaao/maven-dependency-conflict-demorest
咱们有一个 web 应用 resolve-web
,该工程依赖于 project-A
和project-B
,project-A
依赖于 project-common
的 1.0 版本并调用其中的 sayHello()
方法。project-B
依赖于project-C
,而project-C
又进一步依赖于project-common
的2.0 版本并调用其中的 sayGoodBye()
方法。project-common
的 1.0 和 2.0 版本是不一样的,1.0 中之包含sayHello()
方法,而2.0 中包含了sayHello()
和sayGoodBye()
两个方法。整个项目的依赖关系以下图:
根据Maven的transitive依赖机制,resolve-web 将同时依赖于project-common 的 1.0 和 2.0 版本,这就形成了依赖冲突。而根据最近获胜策略,Maven 将选择 project-common 的 1.0 版本做为最终的依赖。
这和 Gradle 不一样,Gradle 在默认状况下将选择最新的版本做为获胜版本。
而对于Maven,因为proejct-common的1.0版本比2.0版本在依赖树中离resolve-web更近,故 1.0 版本获胜。在 resolve-web 中执行mvn dependency:tree -Dverbose
能够看到 resolve-web 的依赖关系:
[INFO] resolve-web:resolve-web:war:1.0-SNAPSHOT [INFO] +- junit:junit:jar:3.8.1:test [INFO] +- project-B:project-B:jar:1.0:compile [INFO] | \- project-C:project-C:jar:1.0:compile [INFO] | \- (project-common:project-commmon:jar:2.0:compile - omitted for conflict with 1.0) [INFO] +- project-A:project-A:jar:1.0:compile [INFO] | \- project-common:project-commmon:jar:1.0:compile [INFO] \- javax.servlet:servlet-api:jar:2.4:provided