12

Как устранить java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

13

У меня есть код, который использует классы API JAXB, предоставленные в составе JDK в Java 6/7/8. Когда я запускаю тот же код с Java 9, во время выполнения я получаю ошибки, указывающие на то, что классы JAXB не могут быть найдены.

Классы JAXB были включены в состав JDK с Java 6, так почему же в Java 9 эти классы больше не могут быть обнаружены?

5 ответ(ов)

4

В вашем случае (фет-джар Spring Boot) нужно просто добавить следующий код в ваш файл pom.xml:

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>

Это позволит вам использовать JAXB API в вашем приложении.

1

Чистое решение для всех JDK >= 9

Вам нужно добавить две зависимости в ваш сборочный файл:

  • jaxb-api
  • реализацию jaxb

В качестве реализации я выбрал ссылочную реализацию от GlassFish, чтобы избавиться от старых классов/библиотек com.sun. В результате я добавил в свой Maven проект следующее:

<dependency>
  <groupId>javax.xml.bind</groupId>
  <artifactId>jaxb-api</artifactId>
  <version>2.3.1</version>
</dependency>

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

Обратите внимание, что начиная с версии 2.3.1, вам больше не нужно добавлять javax.activation. (см. https://github.com/eclipse-ee4j/jaxb-ri/issues/1222)

0

Ни одно из предложенных решений не сработало для меня в актуальной версии JDK 9.0.1.

Я выяснил, что этот список зависимостей вполне достаточен для корректной работы, поэтому вам не нужно явно указывать --add-module (хотя он и прописан в pom этих зависимостей). Всё, что вам нужно сделать, это указать следующий список зависимостей:

<dependencies>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>javax.activation</groupId>
        <artifactId>activation</artifactId>
        <version>1.1.1</version>
    </dependency>
</dependencies>

Пробуйте этот подход, и, надеюсь, у вас всё получится!

0

Это сработало для меня:

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>eclipselink</artifactId>
    <version>2.7.0</version>
</dependency>

Обновление

Как подсказывал @Jasper, чтобы избежать зависимости от всей библиотеки EclipseLink, вы также можете просто подключить EclipseLink MOXy:

Maven

<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>org.eclipse.persistence.moxy</artifactId>
    <version>2.7.3</version>
</dependency>

Gradle

compile group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.moxy', version: '2.7.3'

Это зависимости для моего Java 8 приложения, которое создает *.jar, который может быть запущен как на JRE 8, так и на JRE 9 без дополнительных аргументов.

Кроме того, это необходимо выполнить где-то до того, как будет использован JAXB API:

System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");

Пока все работает отлично в качестве временного решения. Хотя это не выглядит как идеальный вариант...

0

Это связано с версией Java. Если вы используете JDK 9 или более позднюю версию, просто добавьте это в ваш pom.xml:

<dependency>
  <groupId>javax.xml.bind</groupId>
  <artifactId>jaxb-api</artifactId>
  <version>2.3.0</version>
</dependency>

Это должно решить проблему.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь