Java 11: Реализация JAXB-API не найдена на пути к модулю или пути к классам

У меня есть небольшой проект, который выдает исключение, когда я его запускаю.

Проблема здесь (TestObject.java):

final JAXBContext jaxbContext = JAXBContext.newInstance(...);

Я действительно не понимаю, почему это исключение. Я также создал тест, который работает как брелок (TestTest.java). Пожалуйста, простите мне имена, но это всего лишь небольшое тестовое приложение, чтобы работать с java 11.

Я следовал этому: javax.xml.bind.JAXBException Реализация JAXB-API не была найдена на пути к модулю или пути к классам и добавлена

compile('javax.xml.bind:jaxb-api:2.3.0')
compile('javax.activation:activation:1.1')
compile('org.glassfish.jaxb:jaxb-runtime:2.3.0')

на мой build.gradle, но потом жалуется, что

Error:java: module not found: java.activation

пропал, отсутствует. Поскольку это также удалено из Java 11, я добавил:

compile 'com.sun.activation:javax.activation:1.2.0'

но тогда это выдает много ошибок:

Error:java: the unnamed module reads package com.sun.xml.bind from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.util from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.marshaller from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.api from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.v2 from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.v2.util from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.v2.model.impl from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.v2.model.annotation from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.v2.runtime from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.v2.runtime.unmarshaller from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.unmarshaller from both jaxb.runtime and jaxb.core
Error:java: module jaxb.runtime reads package com.sun.xml.bind from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.util from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.marshaller from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.api from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.v2 from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.v2.util from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.v2.model.impl from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.v2.model.annotation from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.v2.runtime from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.v2.runtime.unmarshaller from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.unmarshaller from both jaxb.core and jaxb.runtime
Error:java: module jaxb.core reads package com.sun.xml.bind from both jaxb.core and jaxb.runtime

Что меня так смущает: тест работает. Похоже, что в среде junit5 есть какая-то jaxb-реализация. Я также нашел некоторую другую информацию о том, как перенести приложение Java 8 в модули Java 9, где я нашел это:

compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.4.0-b180830.0359'
compile group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.4.0-b180830.0438'
compile group: 'org.glassfish.jaxb', name: 'jaxb-xjc', version: '2.4.0-b180830.0438'

Но это тоже не работает. Я был бы очень рад, если бы кто-нибудь мог помочь мне в этом. Я использую java-openjdk-11.0.1.13-11.rolling.fc29.x86_64 на Fedora 29, 64 бит.

PS: я хотел написать все это в комментарии к сообщению с темой "javax.xml.bind.JAXBException...", но мне не разрешили это сделать. Итак, я создал этот новый пост.

edit: исключение, которое выбрасывается в этом примере приложения, это:

Exception in thread "main" java.lang.RuntimeException: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
 - with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory]
    at test/com.example.TestObject.doSomething(TestObject.java:21)
    at test/com.example.TestObject.main(TestObject.java:12)
Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
 - with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory]
    at java.xml.bind/javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:269)
    at java.xml.bind/javax.xml.bind.ContextFinder.find(ContextFinder.java:412)
    at java.xml.bind/javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
    at java.xml.bind/javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
    at test/com.example.TestObject.doSomething(TestObject.java:17)
    ... 1 more
Caused by: java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at java.xml.bind/javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122)
    at java.xml.bind/javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155)
    at java.xml.bind/javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:267)
    ... 5 more

9 ответов

Решение очень простое. Во-первых, используйте jaxb 2.3.1. Бета-версия предназначена только для тестирования. Настоящей проблемой был модуль-info.java. Требуется иметь 2 записи для jaxb:

requires java.xml.bind;
requires com.sun.xml.bind;

Первый требует определяет реализацию, второй - API.

Требуются только две зависимости:

compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
compile group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.1'

При обновлении до SpringBoot 2.5 я получил такое же исключение. Добавление следующей зависимости (Maven) решило мои проблемы:

      <dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
</dependency>

Чтобы заполнить другие ответы:

JAXB использует загрузчик классов, привязанный к текущему потоку, чтобы найти JAXB ContextFactory класс ( Thread.currentThread().getContextClassLoader()), а в некоторых случаях (например, с прямыми потоками) связанный загрузчик классов является a, особенностью которого является незнание пути к классам , в отличие от AppClassLoader.

Чтобы решить эту проблему, JAXB API и среда выполнения должны находиться в пути к модулю (который доступен через PlatformClassLoader).

Например, приложение упаковано со следующими зависимостями:

      <dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>2.3.3</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.3</version>
</dependency>

Итак, приложение следует запускать с jaxb-runtime и его зависимости модуля, как показано ниже:

      ### Set the module-path
MODULEPATH="./lib/jaxb-runtime-2.3.3.jar"
MODULEPATH="${MODULEPATH}:./lib/jakarta.activation-1.2.2.jar"
MODULEPATH="${MODULEPATH}:./lib/jakarta.xml.bind-api-2.3.3.jar"
MODULEPATH="${MODULEPATH}:./lib/txw2-2.3.3.jar"
MODULEPATH="${MODULEPATH}:./lib/istack-commons-runtime-3.0.11.jar"

java --module-path ${MODULEPATH} --add-modules ALL-MODULE-PATH [...]

Примечание: ALL-MODULE-PATH можно заменить конкретными именами модулей.

Я обнаружил, что есть ошибка ClassLoader, особенно если вы выполняете работу в потоке через ForkJoinPool или аналогичный. Ошибка указана здесь: https://github.com/eclipse-ee4j/jaxb-api/issues/78.

Статическое создание JaxbContext заставит использовать правильный ClassLoader, но это хакерский метод. : /

Я верю java.lang.ClassNotFoundException приходит из-за того, что несколько версий не могут определить определение.

Решение: удалить com.sun.xml папку из локального репозитория m2 и загрузите только одну зависимость.

javax.xml.bind:jaxb-api:"последняя версия" в pom/gradle.

Для реализации OAuth2 в Spring 2.5.3 вместе с зависимостью от OAuth2

      <dependency>
        <groupId>org.springframework.security.oauth</groupId>
        <artifactId>spring-security-oauth2</artifactId>
        <version>2.5.1.RELEASE</version>
</dependency>

использование следующей зависимости устранит ошибку Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:822) ~[na:na] at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:182) ~[na:na]

              <dependency>
        <groupId>jakarta.xml.bind</groupId>
        <artifactId>jakarta.xml.bind-api</artifactId>
        <version>2.3.3</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
        <version>2.3.3</version>
    </dependency>

Удалена зависимость от maven com.sun.xml.bind из моей внешней библиотеки, которая не является модульной, и много ошибок, таких как the unnamed module reads package com.sun.xml.bind.util ушел.

Я использовал и получал эту ошибку даже после добавления файла. Поэтому я должен был убедиться в следующем:

Ниже приведены dependency:

          <dependency>
      <groupId>jakarta.xml.bind</groupId>
      <artifactId>jakarta.xml.bind-api</artifactId>
      <version>3.0.1</version>
    </dependency>

    <dependency>
      <groupId>org.eclipse.persistence</groupId>
      <artifactId>eclipselink</artifactId>
      <version>3.0.0</version>
    </dependency>

Наряду с зависимостью важно убедиться, что Moxy использует jaxb.properties файл во время compilatationкоторый присутствует в той же упаковке. Итак, добавьте следующее выше dependencies в пределах pom.xml:

        <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>8</source>
          <target>8</target>
        </configuration>
      </plugin>
    </plugins>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <excludes>
          <exclude>**/*.java</exclude>
        </excludes>
      </resource>
    </resources>
  </build>

Все вместе было бы примерно так:

        <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>8</source>
          <target>8</target>
        </configuration>
      </plugin>
    </plugins>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <excludes>
          <exclude>**/*.java</exclude>
        </excludes>
      </resource>
    </resources>
  </build>

<dependencies>
    <dependency>
      <groupId>jakarta.xml.bind</groupId>
      <artifactId>jakarta.xml.bind-api</artifactId>
      <version>3.0.1</version>
    </dependency>

    <dependency>
      <groupId>org.eclipse.persistence</groupId>
      <artifactId>eclipselink</artifactId>
      <version>3.0.0</version>
    </dependency>

</dependencies>

Я столкнулся с той же проблемой для Java 11 - Gradle и ниже зависимости разрешили ее

      compileOnly 'javax.xml.bind:jaxb-api:2.3.1'
compileOnly 'org.glassfish.jaxb:jaxb-runtime:2.3.1' code here
Другие вопросы по тегам