Comment résoudre java.lang.Noclassdeffonderror: javax / xml/ bind/JAXBException en Java 9
j'ai du code qui utilise des classes D'API JAXB qui ont été fournies dans le JDK en Java 6/7/8. Quand J'exécute le même code avec Java 9, à l'exécution j'obtiens des erreurs indiquant que les classes JAXB ne peuvent pas être trouvées.
les classes JAXB ont été fournies dans le cadre de JDK depuis Java 6, alors pourquoi Java 9 ne peut-il plus trouver ces classes?
15 réponses
les API JAXB sont considérées comme des API Java EE, et ne sont donc plus contenues sur le chemin de classe par défaut dans Java SE 9. En Java 11, Ils sont complètement retirés du JDK.
Java 9 introduit les concepts de modules, et par défaut le module agrégat java.se
est disponible sur le chemin de classe (ou plutôt, le chemin du module). Comme son nom l'indique, le module agrégat java.se
inclut les API Java EE qui sont traditionnellement associés à Java 6/7/8.
heureusement, ces API Java EE qui étaient fournies dans JDK 6/7/8 sont toujours dans le JDK, mais elles ne sont tout simplement pas sur le chemin de classe par défaut. Les API Java EE supplémentaires sont fournies dans les modules suivants:
java.activation
java.corba
java.transaction
java.xml.bind << This one contains the JAXB APIs
java.xml.ws
java.xml.ws.annotation
Rapide et sale solution: JDK (9/10)
Pour rendre les API JAXB disponibles à l'exécution, spécifiez la ligne de commande suivante: option:
--add-modules java.xml.bind
mais J'en ai encore besoin pour travailler avec Java 8!!!
Si vous essayez de spécifier --add-modules
avec un JDK plus ancien, il explosera car c'est une option non reconnue. Je suggère l'une des deux options:
- vous pouvez appliquer conditionnellement l'argument dans un script de lancement (si vous en avez un) en inspectant la version JDK en inspectant
$JAVA_HOME/release
pour la propriétéJAVA_VERSION
. - vous pouvez ajouter le
-XX:+IgnoreUnrecognizedVMOptions
pour que la JVM ignore silencieusement les options non reconnues, au lieu de faire exploser. Mais méfiez-vous! Toute autre args de ligne de commande que vous utilisez ne sera plus validée pour vous par la JVM. Cette option fonctionne avec Oracle / OpenJDK ainsi qu'IBM JDK (à partir de JDK 8sr4)
autre solution rapide: (JDK 9/10 seulement)
Notez que vous pouvez rendre tous les modules Java EE ci-dessus disponibles à l'exécution en spécifiant l'option --add-modules java.se.ee
. Le module java.se.ee
est un module agrégé qui inclut java.se.ee
ainsi que les modules API Java EE ci-dessus.
solution à long terme appropriée: (toutes les versions JDK)
les modules de L'API Java EE énumérés ci-dessus sont tous marqués @Deprecated(forRemoval=true)
, parce qu'ils sont prévus pour l'enlèvement dans Java 11 . Ainsi ,L'approche --add-module
ne fonctionnera plus en Java 11.
ce que vous aurez besoin de faire en Java 11 et forward est d'inclure votre propre copie des API Java EE sur le chemin de classe ou le chemin de module. Par exemple, vous pouvez ajouter les API JAX-B comme une dépendance maven comme ceci:
<!-- 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>
Pour plus de détails sur Java modularity, voir JEP 261: Module System
dans mon cas (spring boot fat jar) je viens d'ajouter ce qui suit à pom.XML.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
aucune de ces solutions n'a fonctionné pour moi dans la récente JDK 9.0.1.
j'ai trouvé que cette liste de dépendances est suffisante pour un bon fonctionnement, donc vous n'avez pas besoin de pour spécifier explicitement --add-module
(bien qu'il soit spécifié dans les pom de ces dépendances). La seule chose dont vous avez besoin est de spécifier cette liste de dépendances:
<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>
cela a fonctionné pour moi:
<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>
mise à Jour
comme @Jasper l'a suggéré, afin d'éviter de dépendre de toute la bibliothèque EclipseLink, vous pouvez aussi simplement dépendre de 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 app, qui produit un *.jar qui peut être exécuté par JRE 8 ou JRE 9 sans arguments supplémentaires.
en outre, cela doit être exécuté quelque part avant que L'API JAXB ne soit utilisée:
System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
fonctionne très bien jusqu'à présent, comme une solution. Ne ressemble pas à une solution parfaite...
au moment de la compilation ainsi que le temps d'exécution, ajouter le commutateur --add-modules java.xml.bind
javac --add-modules java.xml.bind <java file name>
java --add-modules java.xml.bind <class file>
une bonne introduction des modules JDK 9
peut également être trouvée à :
https://www.youtube.com/watch?v=KZfbRuvv5qc
vous pouvez utiliser l'option --add-modules=java.xml.bind
JVM pour ajouter le module XML bind à L'environnement D'exécution JVM.
par exemple: java --add-modules=java.xml.bind XmlTestClass
pour résoudre ce problème, j'ai importé des fichiers JAR dans mon projet:
- javax.activation-1.2.0.jar
- jaxb-api-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-core-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-impl-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
- Téléchargez les fichiers ci-dessus et copiez-les dans le dossier libs du projet
- ajouter les fichiers JAR importés dans Java Build Path
pour L'exécution Java Web Start Nous pouvons utiliser la suggestion D'Andy Guibert comme ceci:
<j2se version="1.6+"
java-vm-args="-XX:+IgnoreUnrecognizedVMOptions --add-modules=java.se.ee"/>
Note le "=" dans l' --ajouter des modules. Voir ce billet OpenJDK ou la dernière note dans" Understanding Runtime Access Warnings "de la plate-forme Java , Édition Standard Oracle JDK 9 Migration Guide .
ça a marché pour moi. Ajouter seulement JAXB-api n'était pas suffisant.
<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>
allez à votre Construction.grader et Ajouter ci-dessous les dépendances pour Java 9 ou 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'
après quels artefacts devrais-je utiliser pour JAXB RI dans mon projet Maven? dans Maven, vous pouvez utiliser un profil comme:
<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>
Arbre de dépendance montre:
[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
pour utiliser ceci dans Eclipse, dites oxygène.3a Release (4.7.3 a) ou plus tard, Ctrl-Alt-P, ou cliquez avec le bouton droit de la souris sur le projet, Maven, puis sélectionnez le profil.
N'est pas une réponse, mais un addendum: j'ai obtenu parce que l'exécution groovysh
(Groovy 2.4.13) si JAVA_HOME pointe à une installation Java 9 ( java version "9.0.1"
pour être précis) échoue abyssalement:
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
La solution était:
-
Aller à la JAXB Projet sur github.io ( "JAXB est sous une double licence CDDL 1.1 et GPL 2.0 avec le chemin de Classe d'Exception" )
-
télécharger
jaxb-ri-2.3.0.zip
-
Décompresser où vous mettez votre infrastructure java fichiers (dans mon cas,
/usr/local/java/jaxb-ri/
). D'autres solutions peuvent exister (peut-être via SDKMAN, Je ne sais pas) -
assurez-vous que les bocaux du sous-répertoire lib sont sur le
CLASSPATH
. Je le fais via un script lancé au démarrage de bash, appelé/etc/profile.d/java.sh
, où j'ai ajouté (entre autres)) la boucle suivante:
emballé dans une fonction...
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
et ça marche!
j'ai suivi cette URL et les paramètres ci-dessous m'ont vraiment aidé. J'utilise Java 10 avec STS IDE dans Macbook Pro. Il fonctionne comme un charme.
<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>
OK, j'ai eu le même genre de problème, mais j'ai utilisé java 8, et j'ai continué à obtenir cette erreur, j'ai essayé la plupart des solutions. mais il s'avère que mon maven pointait toujours vers java 9 même si j'ai mis le Global java comme 8, donc dès que j'ai corrigé que tout a fonctionné, pour n'importe quel corps qui pourrait avoir ce genre de problème, vérifier (comment corriger Maven pour utiliser Java par défaut) ) https://blog.tompawlak.org/maven-default-java-version-mac-osx
j'ai rencontré le même problème en utilisant la botte à ressort 2.0.5.RELEASE
sur Java 11.
L'ajout de javax.xml.bind:jaxb-api:2.3.0
à lui seul n'a pas réglé le problème. J'ai aussi dû mettre à jour la botte de printemps à la dernière étape 2.1.0.M2
, donc je suppose que ce sera corrigé dans la prochaine version officielle.