【问题标题】:Declare maven dependency on tools.jar to work on JDK 9声明对 tools.jar 的 maven 依赖以在 JDK 9 上工作
【发布时间】:2016-02-06 10:51:42
【问题描述】:

我有一个使用 this technique 的项目,它在 JDK 8 及更早版本中运行良好。然而,在 JDK 9 中,这个 jar 被删除了,它不再工作了:

com.sun:tools:jar 的“dependencies.dependency.systemPath”指的是不存在的文件 /usr/lib/jvm/java-9-jdk/../lib/tools.jar。请确认您使用 JDK 而不仅仅是 JRE 运行 Maven。

(路径看起来很奇怪,虽然没有 tools.jar in JDK 9

适用于 JDK 版本甚至 JDK 供应商的最佳实践是什么?我什至没有在 OpenJDK 上找到任何适用于 JDK 9 的解决方法(同时保持项目可在 JDK 8 上构建)。

【问题讨论】:

    标签: java maven java-9 tools.jar


    【解决方案1】:

    您的问题是由您似乎使用过的 Java 9 EA 版本中的 Project Jigsaw 更改引起的。 JEP 220 描述了它们。

    已删除:rt.jartools.jar 部分更详细地描述了这一点,但 风险和假设 包含一个很好的总结:

    如上所述,JDK 和 JRE 映像将不再包含文件 lib/rt.jarlib/tools.jarlib/dt.jar 和其他内部 jar 文件。假设这些文件存在的现有代码可能无法正常工作。

    因此,正如您所观察到的,这些文件已经消失了。再往下:

    以前在lib/tools.jar 中找到的类和资源文件,只有在将该文件添加到类路径时才可见,现在,在 JDK 映像中,可通过系统类加载器或在某些情况下通过引导类加载器可见.但是,包含这些文件的模块不会在应用程序类路径中提及,,在系统属性java.class.path 的值中。

    所以tools.jar 中的类被移到模块中,但似乎它们可能对用户不可用。您应该使用最近 Jigsaw 构建中的 jdeps...

    • ... 确定您的模块依赖关系:$jdeps -M -s $your_JAR
    • ... 确定对 JDK 内部 API 的依赖关系:jdeps -jdkinternals $your_JAR

    如果您很幸运,您正在使用的 API 已发布(那么它不会出现在第二次分析中)或有一个公开的替代方案(第二次分析会列出)。否则,您应该考虑将其提交给 Jigsaw mailing list 并在那里寻求帮助,并明确指出您正在使用哪些 API 以及用于什么目的。

    【讨论】:

    • 谢谢,这有助于理解我究竟依赖什么,但如果是 tools.jar,如果我依赖于内置模块之一,它对构建 maven 没有帮助。
    • 这有助于了解其他情况,例如如果(像我一样)您有现有的自定义 Javadoc doclet 并且需要弄清楚如何使用 Java 9 编译它们。
    • “但似乎它们可能对用户不可用”这不是引用所说的。遍历类路径时,您将找不到他们的类文件,这就是它所说的。这总是适用于引导类,但现在,这也适用于所有模块,甚至是那些由应用程序加载器加载的模块,因为它们是通过模块路径而不是类路径加载的。
    【解决方案2】:

    事实证明,支持 JDK 9 的解决方案与 original trick 并没有什么不同:

      <profiles>
        <profile>
          <id>jigsaw</id>
          <activation>
            <jdk>[1.9,)</jdk>
          </activation>
          <!-- No dependencies needed by Jigsaw -->
          <dependencies/>
        </profile>
        <profile>
          <id>default-jdk</id>
          <activation>
            <file>
              <exists>${java.home}/../lib/tools.jar</exists>
            </file>
          </activation>
          <dependencies>
            <dependency>
              <groupId>com.sun</groupId>
              <artifactId>tools</artifactId>
              <scope>system</scope>
              <version>1.6</version>
              <systemPath>${java.home}/../lib/tools.jar</systemPath>
            </dependency>
          </dependencies>
        </profile>
        <profile>
          <id>osx-jdk</id>
          <activation>
            <file>
              <exists>${java.home}/../Classes/classes.jar</exists>
            </file>
          </activation>
          <dependencies>
            <dependency>
              <groupId>com.sun</groupId>
              <artifactId>tools</artifactId>
              <scope>system</scope>
              <version>1.6</version>
              <systemPath>${java.home}/../Classes/classes.jar</systemPath>
            </dependency>
          </dependencies>
        </profile>
      </profiles>
    

    如果将整个 dependency 声明移至 profile ,则不同的配置文件可以使用不同数量的依赖项。


    我创建了一个reusable module 来隐藏依赖于 tools.jar 的单个项目的复杂性:

    <dependency>
      <groupId>com.github.olivergondza</groupId>
      <artifactId>maven-jdk-tools-wrapper</artifactId>
      <version>0.1</version>
    </dependency>
    

    【讨论】:

      【解决方案3】:

      您的解决方案(仅仅是解决方法)被视为已损坏,并且适用于 Java 9。您所能做的就是运行 jdeps 并将您的代码移至公共 API。

      【讨论】:

      • 就理论而言,这是正确的。问题是“公共”API 通常由 tools.jar 中的类提供,因此保持项目可针对旧版 JDK 构建需要解决此问题。
      猜你喜欢
      • 2023-03-10
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-02
      • 2015-11-16
      • 1970-01-01
      • 2012-10-23
      相关资源
      最近更新 更多