Как решить java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException в Java 9
У меня есть некоторый код, который использует классы JAXB API, которые были предоставлены как часть JDK в Java 6/7/8. Когда я запускаю тот же код с Java 9, во время выполнения я получаю ошибки, указывающие, что классы JAXB не могут быть найдены.
Классы JAXB предоставляются как часть JDK начиная с Java 6, так почему же Java 9 больше не может найти эти классы?
45 ответов
API-интерфейсы JAXB считаются API-интерфейсами Java EE и поэтому больше не содержатся в пути к классам по умолчанию в Java SE 9. В Java 11 они полностью удалены из JDK.
Java 9 вводит понятия модулей, и по умолчанию java.se
Агрегатный модуль доступен по пути к классу (точнее, по пути к модулю). Как следует из названия, java.se
Агрегатный модуль не включает API-интерфейсы Java EE, которые традиционно поставляются в комплекте с Java 6/7/8.
К счастью, эти API Java EE, которые были предоставлены в JDK 6/7/8, все еще находятся в JDK, но они просто не находятся на пути к классам по умолчанию. Дополнительные 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 он взорвется, потому что это нераспознанный вариант. Я предлагаю один из двух вариантов:
- Вы можете условно применить аргумент в сценарии запуска (если он у вас есть), проверив версию JDK, проверив
$JAVA_HOME/release
дляJAVA_VERSION
имущество. - Вы можете добавить
-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.
Правильное долгосрочное решение: (Все версии JDK)
Все перечисленные выше модули API Java EE помечены @Deprecated(forRemoval=true)
, потому что они запланированы для удаления в Java 11. Итак --add-module
подход больше не будет работать в Java 11 из коробки.
То, что вам нужно будет сделать в Java 11 и более поздних версиях, - это включить свою собственную копию API Java EE в путь к классу или к модулю. Например, вы можете добавить API JAX-B в виде зависимости maven, например так:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
Для получения полной информации о модульности Java см. JEP 261: Модульная система
В моем случае (весенний загрузочный толстый кувшин) я просто добавляю следующее в pom.xml.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
чистое решение для всех 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)
Ни одно из этих решений не помогло мне в недавнем выпуске 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>
Это сработало для меня:
<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:
специалист
<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");
Прекрасно работает до сих пор, как обходной путь. Не похоже на идеальное решение, хотя...
Это потому, что Java-версия, если вы используете JDK 9 или более позднюю версию, просто добавьте это в свой POM
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
Чтобы решить эту проблему, я импортировал несколько файлов JAR в свой проект:
- javax.activation-1.2.0.jar
- JAXB-апи-2.3.0.jar
http://search.maven.org/remotecontent?filepath=javax/xml/bind/jaxb-api/2.3.0/jaxb-api-2.3.0.jar
- JAXB-ядро-2.3.0.jar
http://search.maven.org/remotecontent?filepath=com/sun/xml/bind/jaxb-core/2.3.0/jaxb-core-2.3.0.jar
- JAXB-осущ-2.3.0.jar
http://search.maven.org/remotecontent?filepath=com/sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0.jar
- Скачайте вышеуказанные файлы и скопируйте их в папку libs в проекте
- Добавьте импортированные файлы JAR в Java Build Path
Во время компиляции, а также во время выполнения, добавьте переключатель --add-modules java.xml.bind
javac --add-modules java.xml.bind <java file name>
java --add-modules java.xml.bind <class file>
Хорошее введение JDK 9
модули также можно найти по адресу: https://www.youtube.com/watch?v=KZfbRuvv5qc
Я столкнулся с этой проблемой при работе над Java-проектом в Debian 10.
Каждый раз, когда я запускаю приложение, оно выдает ошибку в файле журнала:
java.lang.NoClassDefFoundError: javax / xml / bind / JAXBException
Вот как я это решил:
Проблема часто возникает, когда в пути к классам отсутствует библиотека JAXB (Java Architecture for XML Binding). JAXB включен в Java SE 10 или более ранней версии, но удален из Java SE из Java 11 или новее - перемещен в Java EE в рамках проекта Jakarta EE.
Итак, я проверил свою версию Java, используя:
java --version
И это дало мне этот результат
openjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+10-post-Debian-1deb10u1)
OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Debian-1deb10u1, mixed mode, sharing)
Итак, я столкнулся с ошибкой JAXBException, потому что я использовал Java 11, в которой отсутствует библиотека JAXB (Java Architecture for XML Binding) в пути к классам. В него включен JAXB.
Чтобы устранить эту проблему, я должен был добавить JAXB API библиотеку в Lib (/opt/tomcat/lib
) каталог моей установки tomcat:
sudo wget https://repo1.maven.org/maven2/javax/xml/bind/jaxb-api/2.4.0-b180830.0359/jaxb-api-2.4.0-b180830.0359.jar
Затем я переименовал его из
jaxb-api-2.4.0-b180830.0359.jar
к
jaxb-api.jar
:
sudo mv jaxb-api-2.4.0-b180830.0359.jar jaxb-api.jar
Примечание. Убедитесь, что вы изменили разрешение, позволяющее Tomcat получить доступ к файлу, а также изменили владельца на
tomcat
:
sudo chown -R tomcat:tomcat /opt/tomcat
sudo chmod -R 777 /opt/tomcat/
Затем я перезапустил сервер tomcat:
sudo systemctl restart tomcat
Ресурсы: [решено] java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
Это все.
надеюсь, это поможет
Я также наткнулся на ClassNotFoundException:javax.xml.bind.DatatypeConverter с использованием Java 11 и
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
Я пробовал все это, добавляя javax.xml.bind:jaxb-api или spring boot jakarta.xml.bind-api.. Я нашел подсказку для исправлений в jjwt версии 0.10.0.. но, что самое главное, пакет jjwt - это теперь раскол!
Таким образом, проверьте эту ссылку: https://github.com/jwtk/jjwt/issues/510
Просто, если вы используете
Java11 и jjwt 0.9.x, и вы столкнетесь с проблемой ClassNotFoundException:javax.xml.bind.DatatypeConverter,
пойти на
jjwt версии 0.11.x, но используйте разделенные пакеты: https://github.com/jwtk/jjwt
Вы, maven, не найдете более высокую версию для зависимости jjwt, поскольку они разделяют пакеты.
Ура.
При использовании JDK 9+ вам необходимо добавить зависимости JAX-B. Для пользователя Android Studio вам нужно добавить это в свойbuild.gradle
с dependencies {}
блок:
// Add missing dependencies for JDK 9+
if (JavaVersion.current().ordinal() >= JavaVersion.VERSION_1_9.ordinal()) {
// If you're using @AutoValue or any libs that requires javax.annotation (like Dagger)
compileOnly 'com.github.pengrad:jdk9-deps:1.0'
compileOnly 'javax.annotation:javax.annotation-api:1.3.2'
// If you're using Kotlin
kapt "com.sun.xml.bind:jaxb-core:2.3.0.1"
kapt "javax.xml.bind:jaxb-api:2.3.1"
kapt "com.sun.xml.bind:jaxb-impl:2.3.2"
// If you're using Java
annotationProcessor "com.sun.xml.bind:jaxb-core:2.3.0.1"
annotationProcessor "javax.xml.bind:jaxb-api:2.3.1"
testAnnotationProcessor "com.sun.xml.bind:jaxb-core:2.3.0.1"
testAnnotationProcessor "javax.xml.bind:jaxb-api:2.3.1"
}
После Какие артефакты я должен использовать для JAXB RI в моем проекте Maven? в Maven вы можете использовать профиль как:
<profile>
<id>java-9</id>
<activation>
<jdk>9</jdk>
</activation>
<dependencies>
<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>
</profile>
Дерево зависимостей показывает:
[INFO] +- org.glassfish.jaxb:jaxb-runtime:jar:2.3.0:compile
[INFO] | +- org.glassfish.jaxb:jaxb-core:jar:2.3.0:compile
[INFO] | | +- javax.xml.bind:jaxb-api:jar:2.3.0:compile
[INFO] | | +- org.glassfish.jaxb:txw2:jar:2.3.0:compile
[INFO] | | \- com.sun.istack:istack-commons-runtime:jar:3.0.5:compile
[INFO] | +- org.jvnet.staxex:stax-ex:jar:1.7.8:compile
[INFO] | \- com.sun.xml.fastinfoset:FastInfoset:jar:1.2.13:compile
[INFO] \- javax.activation:activation:jar:1.1.1:compile
Чтобы использовать это в Eclipse, скажем, Oxygen.3a Release (4.7.3a) или новее, Ctrl-Alt-P или щелкните правой кнопкой мыши проект Maven, затем выберите профиль.
Это сработало для меня. Добавление только jaxb-api было недостаточно.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb-api.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb-api.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>${jaxb-api.version}</version>
</dependency>
Основная причина этой проблемы заключается в том, что Gradle Daemon использует JDK11, либо вы устанавливаете JAVA_HOME на JDK11, либо запускаете свою задачу Gradle в общем демоне, который работает с JDK11.
Для Android:
Проверьте настройки структуры проекта, вы можете изменить JDK на JDK8 оттуда.
Вы также можете установить JAVA_HOME и указать на java8 home.
Перейдите в Your Build.gradle и добавьте ниже зависимости для Java 9 или Java 10.
sourceCompatibility = 10 // You can also decrease your souce compatibility to 1.8
//java 9+ does not have Jax B Dependents
compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.0'
compile group: 'com.sun.xml.bind', name: 'jaxb-core', version: '2.3.0'
compile group: 'com.sun.xml.bind', name: 'jaxb-impl', version: '2.3.0'
compile group: 'javax.activation', name: 'activation', version: '1.1.1'
Ты можешь использовать --add-modules=java.xml.bind
Опция JVM для добавления модуля связывания xml в среду выполнения JVM.
Например: java --add-modules=java.xml.bind XmlTestClass
Добавление приведенной ниже зависимости сработало для меня.
<!-- 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>
Для Java Web Start Execution мы можем использовать предложение Энди Гиберта, как это:
<j2se version="1.6+"
java-vm-args="-XX:+IgnoreUnrecognizedVMOptions --add-modules=java.se.ee"/>
Обратите внимание на дополнительные "=" в --add-modules. См. Этот билет OpenJDK или последнюю заметку в разделе "Общие сведения о предупреждениях доступа во время выполнения" платформы Java, Standard Edition Oracle JDK 9, Руководство по миграции.
Это решило мои проблемы с зависимостями, работающими под управлением Apache Camel 2.24.1 на Java 12:
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0.1</version>
</dependency>
Добавить зависимость javax.xml.bind в pom.xml
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
Поскольку JavaEE теперь регулируется https://jakarta.ee/, новые координаты Maven с 2.3.2:
https://github.com/eclipse-ee4j/jaxb-ri
Первый выпущенный jaxb.version - 2.3.2.
<properties>
<jaxb.version>2.3.2</jaxb.version>
</properties>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>${jaxb.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>${jaxb.version}</version>
</dependency>
Я следовал по этому URL, и приведенные ниже настройки действительно помогли мне. Я использую Java 10 с STS IDE в Macbook Pro. Отлично работает.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
Как говорится в официальной документации:
При обновлении вы можете столкнуться со следующим:
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
Для Hibernate обычно требуется JAXB, который больше не предоставляется по умолчанию. Вы можете добавить модуль java.xml.bind, чтобы восстановить эту функциональность с помощью Java9 или Java10 (даже если модуль устарел).
Начиная с Java11, модуль недоступен, поэтому ваш единственный вариант - добавить JAXB RI (вы можете сделать это с Java9 вместо добавления модуля java.xml.bind:
Maven
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
Gradle (build.gradle.kts):
implementation("org.glassfish.jaxb:jaxb-runtime")
Градл (build.gradle)
implementation 'org.glassfish.jaxb:jaxb-runtime'
Если вы предпочитаете указывать конкретную версию, загляните сюда:https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime
Я столкнулся с той же проблемой, используя Spring Boot 2.0.5.RELEASE
на Java 11.
Добавление javax.xml.bind:jaxb-api:2.3.0
одиночество не решило проблему. Мне также пришлось обновить Spring Boot до последней Milestone 2.1.0.M2
, поэтому я предполагаю, что это будет исправлено в следующем официальном релизе.
вы можете использовать эту зависимость
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
Не ответ, а дополнение: Я получил, потому что работает groovysh
(Groovy 2.4.13), если JAVA_HOME указывает на установку Java 9 (java version "9.0.1"
если быть точным) терпит неудачу
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:107)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:129)
Caused by: java.lang.NoClassDefFoundError: Unable to load class groovy.xml.jaxb.JaxbGroovyMethods due to missing dependency javax/xml/bind/JAXBContext
at org.codehaus.groovy.vmplugin.v5.Java5.configureClassNode(Java5.java:400)
at org.codehaus.groovy.ast.ClassNode.lazyClassInit(ClassNode.java:277)
at org.codehaus.groovy.ast.ClassNode.getMethods(ClassNode.java:397)
...
..
.
..
...
at org.codehaus.groovy.tools.shell.Groovysh.<init>(Groovysh.groovy:135)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:232)
at org.codehaus.groovy.tools.shell.Main.<init>(Main.groovy:66)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:232)
at org.codehaus.groovy.tools.shell.Main.main(Main.groovy:163)
... 6 more
Решением было:
Перейдите к проекту JAXB по адресу github.io ("JAXB лицензируется по двойной лицензии - CDDL 1.1 и GPL 2.0 с исключением Class-path")
Скачать
jaxb-ri-2.3.0.zip
Разархивируйте, куда бы вы ни поместили файлы инфраструктуры Java (в моем случае,
/usr/local/java/jaxb-ri/
). Другое решение может существовать (возможно, через SDKMAN, я не знаю)Убедитесь, что банки в подкаталоге lib находятся на
CLASSPATH
, Я делаю это через скрипт, запускаемый при запуске bash, называемый/etc/profile.d/java.sh
где я добавил (среди многих других строк) следующий цикл:
Упакован в функцию...
function extend_qzminynshg {
local BASE="/usr/local/java"
for LIB in jaxb-api.jar jaxb-core.jar jaxb-impl.jar jaxb-jxc.jar jaxb-xjc.jar; do
local FQLIB="$BASE/jaxb-ri/lib/$LIB"
if [[ -f $FQLIB ]]; then
export CLASSPATH=$FQLIB:$CLASSPATH
fi
done
}
extend_qzminynshg; unset extend_qzminynshg
И это работает!
Если вы используете JDK 11, вы можете просто добавить в свое приложение Gradle следующее:
dependencies {
...
annotationProcessor "javax.xml.bind:jaxb-api:2.3.1"
...
}
Меня устраивает.
Вам нужна только 1 зависимость:
dependencies {
implementation ("jakarta.xml.bind:jakarta.xml.bind-api:2.3.2")
ОК, у меня была такая же проблема, но я использовал Java 8 и продолжал получать эту ошибку, я попробовал большинство решений. но оказывается, что мой maven все еще указывал на java 9, хотя я установил глобальную java равной 8, так что, как только я установил, что все это работает, для любого тела, которое может иметь такую проблему, проверьте (как исправить Maven для использования Java по умолчанию) https://blog.tompawlak.org/maven-default-java-version-mac-osx
Я хочу дать простое и легкое решение по поводу этого исключения, просто понизьте версию студии Android до 4.1.1 или меньше . Убедитесь, что у вас нет версии android studio arctic fox (2020.3.1) , потому что последняя версия не поддерживает старый проект android.