Как выразить зависимость в maven от функций Java Java для перехода на Java 9?
Мы используем maven
и иметь артефакты, которые в свою очередь зависят от других внутренних артефактов. Я нахожусь в процессе перехода на java-9, и намереваюсь сначала перенести все на Java 9 без модуляции кода (т.е. в безымянном модуле).
Проблема, с которой я сталкиваюсь, заключается в том, что мы зависим от java.xml.bind
, который теперь не включен в модули по умолчанию. Есть ли "правильный" способ выразить эту зависимость от java.xml.bind
с мавеном?
4 ответа
Система модулей говорит о том, как неназванные модули, как в вашем случае загрузки приложения из classpath, строят граф модулей. Далее из самой документации:
Когда компилятор компилирует код в неназванном модуле или запускается программа запуска Java, и основной класс приложения загружается из пути к классу в неназванный модуль загрузчика класса приложения, тогда набор корневых модулей по умолчанию для неназванного модуля рассчитывается следующим образом:
java.se
Модуль является корнем, если он существует. Если его не существует, то каждыйjava.*
модуль на пути модуля обновления или среди системных модулей, которыеexports
по крайней мере один пакет без квалификации является рутом.каждый
non-java.*
модуль на пути модуля обновления или среди системных модулей, которыеexports
по крайней мере один пакет, без квалификации, также является рутом.В противном случае набор корневых модулей по умолчанию зависит от фазы:
Во время компиляции это обычно набор компилируемых модулей (подробнее об этом ниже);
Во время ссылки он пуст; а также
Во время выполнения это основной модуль приложения, как указано в
--module
(или -m для краткости) опция запуска.Иногда необходимо добавить модули к корневому набору по умолчанию, чтобы гарантировать, что в графе модулей будут присутствовать определенные модули платформы, библиотеки или поставщика услуг. На любом этапе вариант
--add-modules <module>(,<module>)*
где<module>
является именем модуля, добавляет именованные модули в набор корневых модулей по умолчанию.
Подобная проблема встречалась в jetty.project, где обсуждалась та же тема из списка рассылки jdk, и исправление должно было использоваться:
--add-modules java.se.ee
который предоставил им доступ ко всем модулям Java SE и в вашем случае просто:
--add-modules java.xml.bind
Чтобы использовать это в Maven, вы можете вставить то же самое в maven-compiler-plugin
с помощью
<compilerArgs>
<arg>--add-modules</arg>
<arg>java.xml.bind</arg>
</compilerArgs>
как подсказал Жека Козлов здесь.
Важно отметить, что пометка устаревшего API также означает, что вы, возможно, захотите отказаться от его использования. Чтобы приспособиться к этому, вы, вероятно, можете начать использовать зависимость от jaxb-api:2.3.0
который теперь может быть загружен как модуль и также может быть выполнен из classpath. Вам нужно внести следующие изменения в список зависимостей:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
Обновление:- В конце концов, с уже выпущенной Java-10 и следующей JDK/11, в идеале следует перейти по ссылке на JEP 320: удалить модули Java EE и CORBA и вместо этого заменить такие зависимости их автономными библиотеками.
Да, ты должен пройти --add-modules
в компилятор Java:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<release>9</release>
<compilerArgs>
<arg>--add-modules</arg>
<arg>javax.xml.bind</arg>
</compilerArgs>
</configuration>
</plugin>
Тогда ваш проект должен хорошо скомпилироваться.
JAXB вместе с другими API, совместно используемыми с Java EE (JAX-WS, JAF, JTA и так называемыми "общими аннотациями"), устарела в Java SE 9 и предлагается удалить в будущем выпуске Java SE и JDK. Каждый из этих API имеет отдельную версию / загрузку. Каждый API имеет свой собственный JSR, который также поддерживает его. Переход от API, включенных в JDK, к автономным версиям, конечно, будет немного разрушительным.
Первый шаг к удалению этих API из Java SE и JDK - не разрешать модули, содержащие эти API по умолчанию. Когда вы компилируете или запускаете код на пути к классам с помощью JDK 9, первоначально будет казаться, что API не существует. Быстрый обходной путь, как отмечено в другом ответе, состоит в том, чтобы скомпилировать или запустить с --add-modules java.xml.bind
, Эта опция CLI добавляет модуль "java.xml.bind" к набору корневых модулей для разрешения при запуске, и он работает с JDK 9, потому что этот модуль включен в образ времени выполнения JDK.
Помимо быстрого обходного пути, приложения или библиотеки, использующие JAXB, должны будут перейти на использование автономной версии API/ реализации. JAXB 2.3.0 скоро будет опубликован в Maven Central и содержит изменения для работы с JDK 9 и более поздними версиями. Автономная версия может быть развернута на пути к классам, как и другие файлы JAR. В конечном итоге можно будет развернуть автономную версию по пути (обновления) модуля и использовать ее как модуль. В Руководстве по миграции JDK 9 будет больше информации о вариантах переноса кода, который использует JAXB или другие API, совместно используемые с Java EE.
Хорошо, я надеюсь, что это кому-то поможет. Если вы случайно установили Java 9 или 10 и обнаружили, что не можете обойти эту ошибку javax.xml.bind, возможно, вы используете Java 8 в виде jenv для каждой папки (на самом деле мне жаль, что я такой расплывчатый, но это все, на что у меня есть время на данный момент)?
Но добавление правильной настройки для JAVA_HOME устранило мою проблему: export JAVA_HOME="$(/usr/libexec/java_home -v 1.8)"
на MacOS.