Как выразить зависимость в 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.

Другие вопросы по тегам