声明对tools.jar的maven依赖以在JDK 9上工作

时间:2016-02-06 10:51:43

标签: maven tools.jar java-9

我有一个使用this technique的项目,可以在JDK 8及更早版本中正常运行。但是,在JDK 9中,这个jar被删除了,它不再起作用了:

  

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

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

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

3 个答案:

答案 0 :(得分:15)

您的问题是由您似乎使用过的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以及用于什么。

答案 1 :(得分:5)

事实证明,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>

答案 2 :(得分:0)

您的解决方案(仅仅是解决方法)被认为已被破坏,并且可以使用Java 9.您只需运行jdeps并将代码移至公共API。