web-dev-qa-db-fra.com

Comment résoudre Java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException en Java 9

J'ai du code qui utilise les classes de l'API JAXB qui ont été fournies avec JDK dans Java 6/7/8. Lorsque j'exécute le même code avec Java 9, des erreurs apparaissent lors de l'exécution, indiquant que les classes JAXB sont introuvables.

Les classes JAXB sont fournies avec JDK depuis Java 6, alors pourquoi Java 9 ne les trouve-t-il plus?

493
Andy Guibert

Les API JAXB sont considérées comme des API Java EE et ne sont donc plus contenues dans le chemin de classe par défaut de Java SE 9. Dans Java 11, elles sont complètement supprimées du JDK.

Java 9 introduit les concepts de modules et, par défaut, le module d'agrégation Java.se est disponible sur le chemin de classe (ou plutôt, le chemin de module). Comme son nom l'indique, le module d'agrégation Java.se inclut non les API Java EE qui ont été traditionnellement associées à Java 6/7/8.

Heureusement, ces API Java EE fournies dans JDK 6/7/8 sont toujours présentes dans le JDK, mais elles ne figurent tout simplement pas dans 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

Solution rapide et sale: (JDK 9/10 uniquement)
Pour rendre les API JAXB disponibles au moment de l'exécution, spécifiez l'option de ligne de commande suivante:
--add-modules Java.xml.bind

Mais j'ai toujours besoin de ça pour travailler avec Java 8 !!!
Si vous essayez de spécifier --add-modules avec un JDK plus ancien, il explose car il s'agit d'une option non reconnue. Je suggère l'une des deux options suivantes:

  1. Vous pouvez appliquer conditionnellement l'argument dans un script de lancement (si vous en avez un) en inspectant la version du JDK en inspectant $Java_HOME/release pour la propriété Java_VERSION.
  2. Vous pouvez ajouter le -XX:+IgnoreUnrecognizedVMOptions pour que la machine virtuelle Java ignore en silence les options non reconnues, au lieu d’exploser. Mais méfiez-vous! Les autres arguments de ligne de commande que vous utilisez ne seront plus validés pour vous par la machine virtuelle Java. Cette option fonctionne avec Oracle/OpenJDK et IBM JDK (à partir du JDK 8sr4).

Autre solution rapide: (JDK 9/10 uniquement)
Notez que vous pouvez rendre tous les modules Java EE ci-dessus disponibles au moment de l'exécution en spécifiant l'option --add-modules Java.se.ee. Le module Java.se.ee est un module global qui inclut Java.se.ee ainsi que les modules d'API Java EE ci-dessus.


Solution appropriée à long terme: (toutes les versions du JDK)

Les modules de l'API Java EE répertoriés ci-dessus sont tous marqués @Deprecated(forRemoval=true), car ils sont sont programmés pour être supprimés in Java 11 . L’approche --add-module ne fonctionnera donc plus prête à l’emploi avec Java 11. 

Dans Java 11 et les versions suivantes, vous devez inclure votre propre copie des API Java EE dans le chemin de classe ou le chemin de module. Par exemple, vous pouvez ajouter les API JAX-B en tant que dépendance maven comme ceci:

<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 la modularité Java, voir JEP 261: Système de modules

761
Andy Guibert

Dans mon cas (pot de graisse pour bottes de printemps), j’ajoute ce qui suit au fichier pom.xml.

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

Aucune de ces solutions ne fonctionnait bien pour moi dans le récent JDK 9.0.1.

J'ai trouvé que cette liste de dépendances est suffisante pour un fonctionnement correct. Ainsi, vous n'avez pas besoin 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>
57
Andremoniy

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>

Mettre à jour

Comme @Jasper l'a suggéré, afin d'éviter de dépendre de la totalité de la bibliothèque EclipseLink, vous pouvez également compter uniquement sur 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'

En tant que dépendances pour mon application Java 8, qui génère un fichier * .jar pouvant être exécuté à la fois par JRE 8 ou JRE 9 sans argument supplémentaire.

De plus, 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 solution de contournement. Cela ne semble pas être une solution parfaite cependant ...

35
Mikhail Kholodkov

c’est parce que la version Java si vous utilisez jdk 9 ou une version ultérieure ajoutez-la simplement

<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
18
Cesar Rodriguez T

Au moment de la compilation et de l'exécution, ajoutez 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 est également disponible à l’adresse: https://www.youtube.com/watch?v=KZfbRuvv5qc

15
Pallavi Sonal

Vous pouvez utiliser l'option JVM --add-modules=Java.xml.bind pour ajouter un module de liaison xml à l'environnement d'exécution JVM.

Exemple: Java --add-modules=Java.xml.bind XmlTestClass

11

Pour résoudre ce problème, j'ai importé des fichiers JAR dans mon projet:

  • javax.activation-1.2.0.jar

http://search.maven.org/remotecontent?filepath=com/Sun/activation/javax.activation/1.2.0/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

  1. Téléchargez les fichiers ci-dessus et copiez-les dans le dossier libs du projet
  2. Ajouter les fichiers JAR importés dans le chemin de construction Java
10
fnascimento

Accédez à Votre build.gradle et ajoutez les dépendances ci-dessous 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'
9
Kumar Abhishek

Cela a fonctionné 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>
9
Mr Jedi

Pour l'exécution de 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"/>

Notez le "=" supplémentaire dans les --add-modules. Voir ce ticket OpenJDK ou la dernière note de la section "Présentation des avertissements d'accès au runtime" de la plate-forme Java Platform, Standard Edition Oracle JDK 9 .

8
mvw

solution propre pour tous les JDK> = 9

Vous devez ajouter deux dépendances à votre construction

  • le jaxb-api
  • une implémentation jaxb

En tant qu'implémentation, j'ai choisi d'utiliser l'implémentation de référence de glassfish pour supprimer les anciennes classes/bibliothèques com.Sun . C'est pourquoi j'ai ajouté à ma construction 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>

Notez que depuis la version 2.3.1, vous n’avez plus besoin d’ajouter javax.activation. (voir https://github.com/Eclipse-ee4j/jaxb-ri/issues/1222 )

7
Sebastian Thees

Après Quels artefacts dois-je utiliser pour JAXB RI dans mon projet Maven? dans Maven, vous pouvez utiliser un profil tel que:

<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> 

L'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 cela dans Eclipse, utilisez Oxygen.3a Release (4.7.3a) ou une version ultérieure, Ctrl-Alt-P ou cliquez-droit sur le projet, Maven, puis sélectionnez le profil.

7
JasonPlutext

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>
4
itsraghz

ajouter une dépendance javax.xml.bind dans pom.xml

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

J'ai rencontré le même problème en utilisant Spring Boot 2.0.5.RELEASE sur Java 11.

L'ajout de javax.xml.bind:jaxb-api:2.3.0 seul n'a pas résolu le problème. Je devais également mettre à jour Spring Boot avec la dernière version de Milestone 2.1.0.M2; je suppose donc que cela sera corrigé dans la prochaine version officielle.

3
Javide

Puisque JavaEE est maintenant régi par https://jakarta.ee/ , les nouvelles coordonnées Maven à partir de la version 2.3.2 sont les suivantes:

https://github.com/Eclipse-ee4j/jaxb-ri#maven-artifacts

La première version jaxb.version publiée est 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>
3
dschulten

Pas une réponse, mais un additif: j'ai eu parce que courir groovysh (Groovy 2.4.13) si Java_HOME pointe vers une installation de Java 9 (le Java version "9.0.1" pour être précis) échoue complètement:

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 de:

  • Accédez au Projet JAXB à github.io ("JAXB est sous licence double licence - CDDL 1.1 et GPL 2.0 avec exception de chemin d'accès de classe")

  • Télécharger jaxb-ri-2.3.0.Zip

  • Décompressez où que vous mettiez vos fichiers d'infrastructure Java (dans mon cas, /usr/local/Java/jaxb-ri/). Une autre solution peut exister (peut-être via SDKMAN, je ne sais pas)

  • Assurez-vous que les fichiers jars du sous-répertoire lib sont sur la variable CLASSPATH. Je le fais via un script démarré au démarrage de bash, appelé /etc/profile.d/Java.sh, où j'ai ajouté (parmi beaucoup d'autres lignes) 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 il fonctionne!

2
David Tonhofer

D'accord, j'ai eu le même genre de problème, mais j'utilisais Java 8 et n'arrêtais pas de recevoir cette erreur, j'ai essayé la plupart des solutions. mais il se trouve que mon navigateur pointait toujours sur Java 9 même si j’ai défini le code mondial Java à 8, donc dès que j’ai réglé le problème, pour tout organisme susceptible de rencontrer ce type de problème pour que Maven utilise Java par défaut) https://blog.tompawlak.org/maven-default-Java-version-mac-osx

1
Ipkiss

Ancienne réponse "Problème résolu en passant à amazoncorretto" Réponse de la réponse: J'ai utilisé le corretto le plus récent, mais jdk 1.8 est similaire. de toute façon nous avons besoin d'ajouter des dépendances manuellement

1
Armen Arzumanyan

Je sais que je suis en retard à la fête, mais mon erreur a fini par nécessiter une solution différente ... super simple aussi

À l’origine, je me suis installé sur Tomcat 9 et j’ai réalisé que j’avais besoin de 7 ... j’ai oublié de mapper mon chemin de classe vers la version 7 dans build.xml

Espérons que cela corrigera l’erreur d’elses à l’avenir, qui parvient à ignorer ce problème aussi simple que moi!

0
Tyler Miles

Les versions de dépendance que je devais utiliser lors de la compilation pour Java 8 cible. Application testée dans les JRE Java 8, 11 et 12.

        <!-- replace dependencies that have been removed from JRE's starting with Java v11 -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.2.8</version>
        </dependency>
        <dependency>
            <groupId>com.Sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.2.8-b01</version>
        </dependency>
        <dependency>
            <groupId>com.Sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.2.8-b01</version>
        </dependency>
        <!-- end replace dependencies that have been removed from JRE's starting with Java v11 -->
0
Chris

Cela a fonctionné pour moi. J'ai un projet de démarrage printanier qui compile en Java 8 mais je ne sais pas pourquoi un jour mon inventeur a commencé à compiler avec Java 11;

Sudo update-Java-alternatives  -l

Cela m'a montré le JDK disponible sur mon pc:

Java-1.11.0-openjdk-AMD64      1111       /usr/lib/jvm/Java-1.11.0-openjdk-AMD64

Java-1.8.0-openjdk-AMD64 1081 /usr/lib/jvm/Java-1.8.0-openjdk-AMD64

J'ai donc finalement lancé cette commande pour choisir celle que vous souhaitez:

Sudo update-Java-alternatives  -s Java-1.8.0-openjdk-AMD64 

Et voilà, pour plus d'informations, jetez un œil à Comment utiliser les alternatives de mise à jour de commande

0
AlvaroCachoperro

Vous devez ajouter les dépendances jaxb à maven. La version 2.3.2 de Glassfish est parfaitement compatible avec la nouvelle version jakarta EE jaxb api 2.3.2.

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

<!-- Runtime -->
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.2</version>
</dependency>
0
krishna Telgave

Pour moi dans Java 11 et voici ce qui a fonctionné:

plugins {
      id 'Java'
}

dependencies {
      runtimeOnly 'javax.xml.bind:jaxb-api:2.3.1'
}
0
silver_mx

Cela a résolu mes problèmes avec les dépendances sous Apache Camel 2.24.1 sur 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>
0
kachanov