在工作中难免会遇到包引用问题,出现包引用问题时,相信老铁问用的最多的工具就是 mvn dependency:tree 来查找问题。但是笔者在工作中发现,打印有个问题。
在【多依赖 + 层级】依赖情况下 maven只会按顺序打印依赖,如果前面已经有依赖打印,后续结节依赖就没有打印。
这样说有点抽象,我举一个例子
graph LR
A -- scope=test --> B -- scope=compile --> C
A -- scope=compile --> B-1 -- scope=compile --> C
maven如下
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>maven-b</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>maven-b-1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
如果依照上面的依赖,我们执行mvn dependency:tree 大家觉得会打印什么也?
解决上面的问题我们先来进行问题拆解
maven scope 传递依赖
这里我就不赘述 scope 的详细功能和取值了,忘记了的老铁 可以看这里dependency scope 的 scope介绍。这里主要在强调下 scope 的 传递依赖,我们先来看下官方截图:
总结上图的依赖
- B 依赖 C 的是
provided或者test那么 A 无法依赖 C- B 依赖 C 的是
compile那么 A 依赖 C的就直接继承 A依赖B的scope- B 依赖 C 的是
runtime那么 除了 A 依赖 B 在compile的情况是 是runtime之外,其它的就是继承 A依赖B的scope
根据上页面的结论我们很容易能够得出,下图的依赖图
graph LR
A -- scope=test --> B -- scope=compile --> C
执行mvn dependency:tree 得出
问题解析
我们搞清楚 scope 传递依赖后,是不是很主观的能够判断我们最开始问的问题?下图的依赖关系
graph LR
A -- scope=test --> B -- scope=compile --> C
A -- scope=compile --> B-1 -- scope=compile --> C
不瞒老铁们,我当时也是这样想的结果。
我认为的结果
[INFO] org.example:maven-a:jar:1.0-SNAPSHOT
[INFO] +- org.example:maven-b:jar:1.0-SNAPSHOT:test
[INFO] | \- org.example:maven-c:jar:1.0-SNAPSHOT:test
[INFO] \- org.example:maven-b-1:jar:1.0-SNAPSHOT:compile
[INFO] | \- org.example:maven-c:jar:1.0-SNAPSHOT:compile
可是我执行 mvn denpendency:tree 确是下面的结果。
\-表示同一层的最后一个节点
而后我又调整了 A 依赖 B B-1 的顺序 如下
<dependency>
<groupId>org.example</groupId>
<artifactId>maven-b-1</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>maven-b</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
结果如下
根据上面的试验可以确定的是,
mvn dependency:tree的打印结果我们想像的不一样,不知道是否maven原本设计就是如此?
结论
根据前面的试验可以大概得到 mvn dependency:tree 下面的结论
- dependency执行的打印顺序 与我们写的
dependency顺序有关- dependency在打印时,是不会按我们主观理解的完整
tree结构打印- 在同一层依赖相同资源时,只会在第一个依赖下打印,且打印的
scope以最终依赖的为准 按compile>runtime>provided>test顺序取优。
后续
后续希望可以有机会研究 maven-dependency-plugin 源码,来证明以上结论。如果已经有研究的老铁们欢迎留言,谢谢!
感谢
欢迎留言指正! 内容持续更新!