Вопрос-ответ

How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

Как разрешить java.lang.NoClassDefFoundError: javax / xml/bind /JAXBException

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

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

Переведено автоматически
Ответ 1

API-интерфейсы JAXB считаются API-интерфейсами Java EE и, следовательно, больше не содержатся в пути к классам по умолчанию в Java SE 9. В Java 11 они полностью удалены из JDK.

Java 9 вводит концепции модулей, и по умолчанию java.se модуль aggregate доступен по пути к классу (или, скорее, пути к модулю). Как следует из названия, java.se модуль aggregate не включает API Java EE, которые традиционно поставляются в комплекте с Java 6/7/8.

К счастью, эти Java EE API, которые были предоставлены в JDK 6/7/8, все еще находятся в JDK, но их просто нет в classpath по умолчанию. Дополнительные API Java EE предоставляются в следующих модулях:

java.activation
java.corba
java.transaction
java.xml.bind << This one contains the JAXB APIs
java.xml.ws
java.xml.ws.annotation

Быстрое и грязное решение: (только JDK 9/10)

Чтобы сделать API JAXB доступными во время выполнения, укажите следующий параметр командной строки:

--add-modules java.xml.bind

Но мне все еще нужно это для работы с Java 8!!!

Если вы попытаетесь указать --add-modules с помощью более старого JDK, это приведет к сбою, потому что это нераспознанный параметр. Я предлагаю один из двух вариантов.:


  1. Вы можете установить любые параметры только для Java 9+, используя JDK_JAVA_OPTIONS переменную окружения. Эта переменная окружения автоматически считывается программой java запуска для Java 9+.

  2. Вы можете добавить -XX:+IgnoreUnrecognizedVMOptions, чтобы заставить JVM молча игнорировать нераспознанные параметры, вместо того, чтобы взрываться. Но будьте осторожны! Любые другие используемые вами аргументы командной строки больше не будут проверяться для вас JVM. Этот параметр работает с Oracle / OpenJDK, а также с IBM JDK (начиная с JDK 8sr4).


Альтернативное быстрое решение: (только JDK 9/10)

Обратите внимание, что вы можете сделать все вышеупомянутые модули Java EE доступными во время выполнения, указав параметр --add-modules java.se.ee. java.se.ee Модуль представляет собой агрегированный модуль, который включает в себя java.se.ee, а также вышеупомянутые модули Java EE API. Обратите внимание, это не работает на Java 11, потому что java.se.ee было удалено в Java 11.


Правильное долгосрочное решение: (JDK 9 и выше)

Все перечисленные выше модули Java EE API помечены, @Deprecated(forRemoval=true) потому что они запланированы к удалению в Java 11. Таким образом, --add-module готовый подход больше не будет работать в Java 11.

Что вам нужно будет сделать в Java 11 и далее, так это включить вашу собственную копию Java EE API в classpath или module path . Например, вы можете добавить API JAXB в качестве зависимости Maven следующим образом:

<!-- API, java.xml.bind module -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.2</version>
</dependency>

<!-- Runtime, com.sun.xml.bind module -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>

Смотрите Страницу справочной реализации JAXB для получения более подробной информации о JAXB.

Для получения полной информации о модульности Java см. JEP 261: Модульная система

По состоянию на июль 2022 года последней версией bind-api и jaxb-runtime является 4.0.0. Поэтому вы также можете использовать

    <version>4.0.0</version>

...в этих предложениях зависимостей. Но если вы это сделаете, имена пакетов изменятся с javax.xml.bind... на jakarta.xml.bind.... Вам нужно будет изменить исходный код, чтобы использовать эти более поздние версии JARS.

Для разработчика Gradle или Android Studio: (JDK 9 и выше)

Добавьте следующие зависимости в свой build.gradle файл:

dependencies {
// JAX-B dependencies for JDK 9+
implementation "jakarta.xml.bind:jakarta.xml.bind-api:2.3.2"
implementation "org.glassfish.jaxb:jaxb-runtime:2.3.2"
}
Ответ 2

В моем случае (spring boot fat jar) Я просто добавляю следующее в pom.xml.

<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
Ответ 3

Чистое решение для всех 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)

Ответ 4

Ни одно из этих решений не работало нормально для меня в недавнем 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>
java jaxb