Maven的 dependency:tree -Dscope=compile返回为空,但在源代码中该类却可用——传递性作用域解析到底是如何工作的?

后端开发 2026-07-09

我有一个Maven项目,其中 jakarta.enterprise:jakarta.enterprise.cdi-api:4.0.1 可以在生产代码中使用(编译通过,@ApplicationScoped 也能工作),但执行:

mvn dependency:tree -Dscope=compile -Dincludes=jakarta.enterprise:jakarta.enterprise.cdi-api

返回 空输出。在不使用作用域过滤时运行会显示该工件,但最终路径通过一个 测试作用域 的依赖:

+- io.quarkus:quarkus-junit5:jar:3.8.6.1:test
|  \- io.quarkus:quarkus-core:jar:3.8.6.1:compile
|     \- jakarta.enterprise:jakarta.enterprise.cdi-api:jar:4.0.1:compile  ← WINNER

当使用 -Dverbose 运行时,所有编译作用域路径都显示为 omitted for duplicate

+- io.quarkus:quarkus-arc:jar:3.8.6.1:compile
|  \- (jakarta.enterprise:jakarta.enterprise.cdi-api:jar:4.0.1:compile - omitted for duplicate)

移除 quarkus-arc(compile)会导致编译失败。因此,实际能用的是编译作用域路径,而不是在最近胜出解析中得到的测试路径。

问题:

  1. 为什么在工件确实位于编译类路径上时,-Dscope=compile 仍然返回空?
  2. dependency:tree 的作用域过滤对于出现在混合作用域链中的传递依赖是否不可靠?
  3. 正确的命令是什么,能够可靠地判断一个传递依赖是否真的在编译类路径上,并且能“从哪里派生出它”?

Maven版本: 3.9.15

解决方案

几点注意:

  1. 如果在你的源代码中使用了某样东西,请在POM中将其声明为依赖。不要直接依赖传递依赖。
  2. 如果你想知道某个东西是否在类路径上,请使用 mvn dependency:list
  3. 如果你想知道它来自哪里,请使用 mvn dependency:tree,但不要进行过滤。通常在IDE中查看会更容易。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章