Maven 依赖调解原则失效?

都知道 Maven 在出现依赖版本冲突问题时,会用最短路径原则和第一声明原则来解决冲突。但在自己电脑上引入如下依赖,却产生了与期望违背的效果:

<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.6</version>
</dependency>

<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.4</version>
</dependency>

按照两个原则的话,最终引入的应该是版本为 2.6 的包,但实际却引入了版本为 2.4 的包。分析如下:

> mvn dependency:tree
[INFO] ------------------------------------------------------------------------
[INFO] Building mvn-test 1.0.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ mvn-yilaitest ---
[INFO] com.ariclee:mvn-yilaitest:jar:1.0.0
[INFO] \- commons-io:commons-io:jar:2.4:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.068 s
[INFO] Finished at: 2019-05-11T16:45:38+08:00
[INFO] Final Memory: 12M/245M
[INFO] ------------------------------------------------------------------------

为什么依赖后声明的却被引入了,这不是违背了第一声明原则吗?

网友的相似疑问:https://stackoverflow.com/questions/41479316/maven-dependency-management-the-first-declaration-wins,但是没人去回答他....

其实这个是 dependency 插件的功能,默认采用的是复写的策略,当构建声明处于同一 pom 中,且 groupid 和 artifactId 一致时,以**最新声明为准**,后面的覆盖前面的。注意这里没涉及到依赖调解的功能。我的理解是依赖调解只发生于构建来自不同 pom 时,而此时构建声明处于同一 pom,故不会触发依赖调解。

参考:
https://maven.apache.org/plugins/maven-dependency-plugin/usage.html
https://juejin.im/post/5cbf27a95188250a505c2cd2#heading-18
https://stackoverflow.com/questions/42113542/figuring-out-duplicate-dependency-in-war

你说的原则是针对多个包相互依赖的情况下的冲突,按当前这个问题,同一个 pom.xml 中统一模块不同版本应该是以后一个声明为主。
你可以调整下顺序再看看会怎么样。