声明 maven 对工具的依赖性.jar在 JDK 9 上工作

2022-09-03 05:20:12

我有一个使用这种技术的项目,在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。

(路径看起来很奇怪,尽管没有工具.jar在JDK 9中)

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


答案 1

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

已删除:rt.jar工具.jar部分对此进行了更详细的描述,但风险和假设包含一个很好的摘要:

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

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

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

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

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

如果幸运的话,您正在使用的API已经发布(那么它不会出现在第二个分析中)或有一个公共替代方案(第二个分析将列出)。否则,您应该考虑将其带到Jigsaw邮件列表并在那里寻求帮助,并明确说明您正在使用哪些API以及用于什么。


答案 2

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

如果将整个声明移动到 它允许不同的配置文件使用不同数量的依赖项。dependencyprofile


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

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

推荐