maven-dependency-plugin dependency:tree 打印问题

2,829 阅读2分钟

在工作中难免会遇到包引用问题,出现包引用问题时,相信老铁问用的最多的工具就是 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 scopescope介绍。这里主要在强调下 scope 的 传递依赖,我们先来看下官方截图:

image.png

总结上图的依赖

  1. B 依赖 C 的是 provided 或者 test 那么 A 无法依赖 C
  2. B 依赖 C 的是 compile 那么 A 依赖 C的就直接继承 A依赖B的 scope
  3. B 依赖 C 的是 runtime 那么 除了 A 依赖 B 在 compile的情况是 是runtime 之外,其它的就是继承 A依赖B的 scope

根据上页面的结论我们很容易能够得出,下图的依赖图

graph LR
A -- scope=test --> B -- scope=compile --> C

执行mvn dependency:tree 得出

image.png

问题解析

我们搞清楚 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 确是下面的结果。

\- 表示同一层的最后一个节点

image.png

而后我又调整了 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>

结果如下

image.png

根据上面的试验可以确定的是,mvn dependency:tree 的打印结果我们想像的不一样,不知道是否maven原本设计就是如此?

结论

根据前面的试验可以大概得到 mvn dependency:tree 下面的结论

  1. dependency执行的打印顺序 与我们写的 dependency顺序有关
  2. dependency在打印时,是不会按我们主观理解的完整 tree 结构打印
  3. 在同一层依赖相同资源时,只会在第一个依赖下打印,且打印的 scope以最终依赖的为准 按 compile>runtime > provided > test 顺序取优。

后续

后续希望可以有机会研究 maven-dependency-plugin 源码,来证明以上结论。如果已经有研究的老铁们欢迎留言,谢谢!

感谢

欢迎留言指正! 内容持续更新!