Объявите зависимость maven от tools.jar для работы с JDK 9.

У меня есть проект, в котором используется этот метод, который отлично работает в JDK 8 и старше. . Однако в JDK 9 этот jar был удален и больше не работает:

'dependencies.dependency.systemPath' для com.sun:tools:jar ссылается на несуществующий файл /usr/lib/jvm/java-9-jdk/../lib/tools.jar. Убедитесь, что вы запускаете Maven с помощью JDK, а не только JRE.

(Путь выглядит странно, хотя там нет tools.jar в JDK 9)

Как лучше всего работать с версиями JDK и, возможно, даже с поставщиками JDK? Я даже не нашел обходного пути для JDK 9 на OpenJDK (при сохранении возможности сборки проекта на JDK 8).


person Oliver Gondža    schedule 06.02.2016    source источник


Ответы (3)


Ваши проблемы вызваны изменениями Project Jigsaw, внесенными в сборку Java 9 EA, которая, по вашему мнению, использовали. JEP 220 описывает их.

В разделе Удалено: rt.jar и tools.jar это описано более подробно, но в разделе Риски и предположения содержится хорошее резюме:

Образы JDK и JRE, как отмечалось выше, больше не будут содержать файлы lib/rt.jar, lib/tools.jar, lib/dt.jar и другие внутренние файлы jar. Существующий код, предполагающий существование этих файлов, может работать некорректно.

Итак, как вы заметили, эти файлы исчезли. Дальше:

Файлы классов и ресурсов, ранее найденные в lib/tools.jar и видимые только тогда, когда этот файл был добавлен в путь к классам, теперь в образе JDK будут видны через системный загрузчик классов или, в некоторых случаях, загрузчик классов начальной загрузки. Однако модули, содержащие эти файлы, не будут упомянуты в пути к классу приложения, т.е., в значении системного свойства java.class.path.

Таким образом, классы из tools.jar перемещены в модули, но, похоже, они могут быть недоступны пользователю. Вам следует использовать jdeps из недавней сборки Jigsaw. ...

  • ... чтобы определить зависимости вашего модуля: $jdeps -M -s $your_JAR
  • ... для определения зависимостей от внутренних API JDK: jdeps -jdkinternals $your_JAR

Если вам повезло, API, который вы используете, был опубликован (тогда он не будет отображаться во втором анализе) или имел общедоступную альтернативу (которая будет указана во втором анализе). В противном случае вам следует обратиться к списку рассылки Jigsaw и обратиться за помощью. там, явно отметив, какие API вы используете и для чего.

person Nicolai Parlog    schedule 06.02.2016
comment
Спасибо, это полезно для понимания того, от чего именно я завишу, но в случае с tools.jar это не помогает заставить maven собираться, если я завишу от одного из встроенных модулей. - person Oliver Gondža; 07.02.2016
comment
Это полезно знать в других контекстах, например, если (как и я) у вас есть существующие пользовательские доклеты Javadoc и вам нужно выяснить, как их скомпилировать с помощью Java 9. - person mhucka; 22.11.2017
comment
«но похоже, что они могут быть недоступны для пользователя» Это не то, что сказано в цитате. Вы не найдете их файлы классов при переборе пути к классу, вот что он сказал. Это всегда применялось к классам начальной загрузки, но в настоящее время это также относится ко всем модулям, даже к тем, которые загружаются загрузчиком приложения, поскольку они загружаются через путь модуля, а не путь класса. - person Holger; 24.10.2019

Оказывается, решение с поддержкой 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, это позволяет разным профилям использовать разное количество зависимостей.


Я создал модуль многократного использования, чтобы скрыть сложность отдельного проекта, зависящего от инструментов. банка:

<dependency>
  <groupId>com.github.olivergondza</groupId>
  <artifactId>maven-jdk-tools-wrapper</artifactId>
  <version>0.1</version>
</dependency>
person Oliver Gondža    schedule 07.02.2016

Ваше решение (простое временное решение) считается неработоспособным и не работает с Java 9. Все, что вы можете сделать, это запустить jdeps и перенести свой код в общедоступные API.

person Michael-O    schedule 06.02.2016
comment
Это верно, насколько теория идет. Проблема в том, что общедоступные API-интерфейсы часто предоставляются классами в tools.jar, поэтому сохранение возможности сборки проекта для старых JDK требует решения этой проблемы. - person Oliver Gondža; 02.01.2018