Как разрешить java.ленг.Noclassdeffounderror: javax/xml/bind/JAXBException в Java 9
У меня есть код, который использует классы API JAXB, которые были предоставлены как часть JDK в Java 6/7/8. Когда я запускаю тот же код с Java 9, во время выполнения я получаю ошибки, указывающие, что классы JAXB не могут быть найдены.
классы JAXB были предоставлены как часть JDK с Java 6, так почему Java 9 больше не может найти эти классы?
15 ответов
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.
к счастью, эти 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 молча игнорировал непризнанные параметры, а не взрывался. Но берегись! Любой другой используемые вами args командной строки больше не будут проверяться JVM. Эта опция работает с Oracle / OpenJDK, а также IBM JDK (начиная с JDK 8sr4)
альтернативное быстрое решение: (только JDK 9/10)
Обратите внимание, что вы можете сделать все вышеперечисленные модули Java EE доступными во время выполнения, указав . The 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 следующим образом:
<!-- Java 6 = JAX-B Version 2.0 -->
<!-- Java 7 = JAX-B Version 2.2.3 -->
<!-- Java 8 = JAX-B Version 2.2.8 -->
<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: модуль системы
в моем случае (spring boot fat jar) я просто добавляю следующее в pom.XML.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
ни одно из этих решений работал для меня в последние 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:
Maven
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.moxy</artifactId>
<version>2.7.3</version>
</dependency>
ш
compile group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.moxy', version: '2.7.3'
как зависимости для моего приложения Java 8, которое производит *.jar, который может выполняться как JRE 8, так и JRE 9 без дополнительных аргументов.
In кроме того, это должно быть выполнено где-то до того, как будет использоваться JAXB API:
System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
отлично работает до сих пор, как обходной путь. Не похоже на идеальное решение...
во время компиляции, а также во время выполнения добавьте переключатель --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
можно использовать --add-modules=java.xml.bind
опция JVM для добавления модуля привязки xml в среду выполнения JVM.
например: java --add-modules=java.xml.bind XmlTestClass
чтобы решить эту проблему, я импортировал некоторые файлы JAR в мой над файлами и скопируйте их в папку libs в проекте
для выполнения Java Web Start мы можем использовать предложение Энди Гиберта следующим образом:
<j2se version="1.6+"
java-vm-args="-XX:+IgnoreUnrecognizedVMOptions --add-modules=java.se.ee"/>
обратите внимание на дополнительные " = " в --add-modules. См.этот билет OpenJDK или последнее примечание в разделе "понимание предупреждений о доступе во время выполнения"платформа Java, Стандартное издание Oracle JDK 9 руководство по миграции.
это сработало для меня. Добавления только 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 и добавьте ниже зависимости для 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'
после какие артефакты я должен использовать для 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
чтобы использовать это в затмении, скажем, кислород.3a Release (4.7.3 a) или более поздней версии, Ctrl-Alt-P или щелкните правой кнопкой мыши на проекте, Maven, затем выберите профиль.
не ответ, а дополнение: я получил, потому что работает 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.Ио ( "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
и это работает!
Я следил за этим 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 8 и продолжал получать эту ошибку, я пробовал большинство решений. но оказывается, что мой maven все еще указывал на java 9, хотя я установил глобальную java как 8, поэтому, как только я исправил, что все это сработало, для любого тела, у которого может быть такая проблема, проверьте (как исправить Maven для использования Java по умолчанию ) https://blog.tompawlak.org/maven-default-java-version-mac-osx
я столкнулся с той же проблемой, используя Spring Boot 2.0.5.RELEASE
на Java 11.
добавлять javax.xml.bind:jaxb-api:2.3.0
в одиночку не удалось решить проблему. Мне также пришлось обновить Spring Boot до последней вехи 2.1.0.M2
, Так что я предполагаю, что это будет исправлено в следующем официальном релизе.