16

我有一个使用这种技术的项目,该技术在 JDK 8 及更早版本中运行良好。但是,在 JDK 9 中,此 jar 已被删除,并且不再起作用:

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

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

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

4

3 回答 3

17

您的问题是由您似乎使用过的 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 邮件列表并在那里寻求帮助,并明确指出您正在使用哪些 API 以及用于什么目的。

于 2016-02-06T17:35:13.867 回答
10

事实证明,支持 JDK 9 的解决方案与原来的技巧并没有什么不同:

  <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它使不同的配置文件能够使用不同数量的依赖项。


我创建了一个可重用的模块来隐藏依赖于 tools.jar 的单个项目的复杂性:

<dependency>
  <groupId>com.github.olivergondza</groupId>
  <artifactId>maven-jdk-tools-wrapper</artifactId>
  <version>0.1</version>
</dependency>
于 2016-02-07T05:33:11.873 回答
0

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

于 2016-02-06T16:24:12.260 回答