为什么Eclipse会把maven运行时依赖变成编译依赖?

Why does Eclipse turn a maven runtime dependency into a compile dependency?

我有一个导入到 Eclipse Oxygen 中的 Maven 项目。 Eclipse 报告没有编译问题 (Alt + F5)。当我从命令行 运行 maven 时,我得到

[ERROR] /home/dean/src/TAP3UIs/TAP3Desktop/src/main/java/com/ms/tap3/controller/RequestAccessController.java:[8,30] package com.google.common.base does not exist

我的 .m2/repository in guava-15.0.jar 中确实存在该软件包。我也可以在 Eclipse mvn dependencies 中看到它。当我检查项目的 mvn dependency:tree 时,我看到

[INFO] | | | +- com.google.guava:guava:jar:15.0:runtime

它是对命令行的运行时间传递依赖,这解释了为什么它不能在命令行上编译。 Eclipse 以某种方式将传递依赖从 运行 时间转换为编译。

有谁知道为什么会发生这种情况以及我如何使 Eclispe m2e 遵守传递依赖项的范围?

目前,JDT nor m2e 都不支持每个项目的多个类路径,这是支持不同范围所必需的。

参见:Eclipse bug 486035 - Different classpath containers for different scopes

更新:

自 2018 年 6 月发布的 Eclipse Photon (4.8) 以来,现在支持。参见 Eclipse bug 526858 and my video showing this in action

要点是:如果你在源代码中导入外部类,你必须将它们设置为编译依赖,并且永远不要相信它们可能已经是传递依赖(因为,由于它们是传递的,你不能直接控制它们,所以在未来的版本中它们也可能消失)。

这是怎么回事:

  • 您需要 com.google.common.base 包中的一些 类,因此您需要将 com.google.guava:guava:jar:15.0 设置为依赖项。
  • 相反,你没有这样做,因为你意识到它已经是一个传递依赖,但你错过了一个 运行时 依赖的事实。
  • Eclipse M2 不区分不同的 Maven 标准类路径,因此它将所有依赖项视为 "compile" 范围。所以Eclipse在编译中包含guava-15.0.jar,项目编译成功。
  • Maven 相反,不会在编译阶段包含 runtime 依赖项,因此会引发编译错误。

简而言之:您应该将 guava-15.0(以及您的代码需要的任何其他工件)作为 直接依赖项(使用 编译 范围)在你的 pom 文件中。