如何修复pom.xml文件中缺失com.sun:tools:jar构件错误
[LOADING...]
1. 概述
在处理较旧的 Java 仓库时,尤其是为 Java 8 或更早版本创建的 Maven 项目,Eclipse 可能会报告与 com.sun:tools 依赖相关的错误:
类似地,Ant 构建可能会失败,并给出类似消息:
在命令行中,Maven 会报告缺失的依赖及其预期路径:
在本教程中,我们将研究 com.sun:tools:jar 工件为何可能缺失,以及如何解决该问题。
2. 理解问题
较旧的库和 Maven 项目有时会将 tools.jar 声明为系统依赖项:
在 JDK 8 上,java.home 是 JDK 的 jre 目录,因此 ${java.home}/../lib/tools.jar 指向 JDK 路径 lib/tools.jar。相反,独立的 JRE 实例中没有此文件。
与普通 Maven 依赖不同,作用域为 system 的依赖并不来自 Maven Central 或其他仓库。 相反,Maven 期望该 JAR 存在于 systemPath 指定的位置。
在 JDK 8 及更早版本中,tools.jar 是 JDK 安装的一部分,包含 Java 开发工具使用的类。
3. 使用 JRE 而不是 JDK
独立的 Java 8 JRE 不包含 tools.jar。
首先确认 Maven 使用的是哪个 Java 安装:
较新的 Maven 版本会将运行时路径标记为 runtime:,而较旧版本使用 Java home:。类似 jre1.8.0_301 的独立 JRE 路径说明可能存在问题。另一方面,对于 JDK 8,jdk1.8.0_301/jre 应该是正常的。
要纠正这种情况,我们可以设置 JAVA_HOME 为相关 JDK 目录。下面看一个 Linux 或 macOS 上的示例:
在这种情况下,JAVA_HOME 指向 JDK 根目录,而不是其 bin 目录。
4. IDE 使用了错误的 Java 安装
在 Eclipse 中,我们可以先在 Preferences > Java > Installed JREs 下检查已配置的 Java 安装,并确保选择了合适的 JDK。对于支持 Java 8 的较旧 Eclipse 版本,我们可以通过 eclipse.ini 中的 -vm 选项显式配置 Eclipse 的 JVM:
重启 Eclipse 后,我们更新或重新导入 Maven 项目。值得注意的是,各个 Maven 运行配置可以有自己的 JRE 设置。
5. 使用 JDK 9 或更高版本构建
从 JDK 9 开始,tools.jar 不再存在。公共工具 API 仍可通过 jdk.compiler(javac 和 Compiler Tree API)以及 jdk.attach(Attach API)等模块使用,而无需额外的 JAR 依赖。
Maven 还会打印一条警告,但这里建议的修复方式是错误的:
由于即使完整的 JDK 9 或更高版本也没有 tools.jar,因此切换到 JDK 并不能解决该问题。
对于同时支持 JDK 8 和更新版本的项目,我们可以将该依赖项移入仅适用于 JDK 8 的 profile:
如果第三方库、Maven 插件或框架声明了 com.sun:tools,我们应将该组件升级到与较新 Java 版本兼容的版本。
6. 排除过时依赖
要定位该声明,我们检查有效 POM:
这会包含来自项目、其父项目以及活动 profile 的声明,但不包含传递依赖。对于传递依赖,我们使用另一个命令:
如果较新的 JDK 已经提供了该库所需的功能,并且对 tools.jar 的依赖已经过时,我们或许可以将其排除:
仅当该库能与目标 JDK API 正常工作时,此解决方案才适用。 否则,Maven 错误可能会被编译错误或运行时错误取代。
7. 避免手动处理 tools.jar 的变通方案
复制或手动安装 tools.jar 会使构建依赖于本地修改,并导致开发机器与 CI 环境之间的行为不一致。Maven 支持系统作用域依赖项,但不鼓励使用它们。
8. 结论
本文中,我们探讨了 Missing artifact com.sun:tools:jar 和 Unable to locate tools.jar 错误。
对于 Java 8 及更早版本,该问题通常意味着 Maven 或 IDE 使用的是 JRE,而不是所需的 JDK,因此配置 JAVA_HOME 和 IDE 的 JVM 即可解决该问题。从 Java 9 开始,tools.jar 不再存在,因此需要升级、移除那些依赖它的旧依赖项,或使用合适的旧版 JDK 进行构建。