it-swarm.com.de

So lösen Sie Java.lang.NoClassDefFoundError auf: javax/xml/bind/JAXBException in Java 9

Ich habe Code, der JAXB-API-Klassen verwendet, die als Teil des JDK in Java 6/7/8 bereitgestellt wurden. Wenn ich denselben Code mit Java 9 ausführte, erhalte ich zur Laufzeit Fehler, die darauf hinweisen, dass JAXB-Klassen nicht gefunden werden können.

Die JAXB-Klassen werden seit Java 6 als Teil des JDK bereitgestellt. Warum kann Java 9 diese Klassen nicht mehr finden?

493
Andy Guibert

Die JAXB-APIs werden als Java EE-APIs betrachtet und sind daher nicht mehr im Standardklassenpfad von Java SE 9 enthalten. In Java 11 werden sie vollständig aus dem JDK entfernt.

Java 9 führt die Konzepte von Modulen ein, und standardmäßig ist das Java.se-Aggregatmodul im Klassenpfad (bzw. Modulpfad) verfügbar. Wie der Name schon sagt, enthält das Java.se-Aggregatmodul nicht die Java EE-APIs, die traditionell in Java 6/7/8 enthalten sind.

Glücklicherweise befinden sich diese Java EE-APIs, die in JDK 6/7/8 bereitgestellt wurden, immer noch im JDK, sie befinden sich jedoch standardmäßig nicht im Klassenpfad. Die zusätzlichen Java EE-APIs werden in den folgenden Modulen bereitgestellt:

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

Schnelle und schmutzige Lösung: (nur JDK 9/10)
Geben Sie die folgende Befehlszeilenoption an, um die JAXB-APIs zur Laufzeit verfügbar zu machen:
--add-modules Java.xml.bind

Aber ich brauche das immer noch, um mit Java 8 zu arbeiten !!!
Wenn Sie versuchen, --add-modules mit einem älteren JDK anzugeben, wird es explodieren, da es sich um eine nicht erkannte Option handelt. Ich schlage eine von zwei Möglichkeiten vor:

  1. Sie können das Argument in einem Startskript (falls vorhanden) bedingt anwenden, indem Sie die JDK-Version überprüfen, indem Sie $Java_HOME/release auf die Java_VERSION-Eigenschaft überprüfen.
  2. Sie können den -XX:+IgnoreUnrecognizedVMOptions hinzufügen, damit die JVM nicht erkannte Optionen ignoriert, anstatt zu blasen. Aber Vorsicht! Alle anderen Befehlszeilenargumente, die Sie verwenden, werden von der JVM nicht mehr für Sie validiert. Diese Option funktioniert mit Oracle/OpenJDK sowie mit IBM JDK (ab JDK 8sr4).

Alternative, schnelle Lösung: (nur JDK 9/10)
Beachten Sie, dass Sie alle obigen Java EE-Module zur Laufzeit verfügbar machen können, indem Sie die Option --add-modules Java.se.ee angeben. Das Java.se.ee-Modul ist ein Aggregatmodul, das Java.se.ee sowie die obigen Java EE-API-Module enthält.


Richtige Langzeitlösung: (Alle JDK-Versionen)

Die oben aufgeführten Java EE-API-Module sind alle mit @Deprecated(forRemoval=true) gekennzeichnet, da sie zur Entfernung geplant sind in Java 11 . Der --add-module-Ansatz funktioniert daher in Java 11 nicht mehr standardmäßig. 

Was Sie in Java 11 tun und weiterleiten müssen, ist Ihre eigene Kopie der Java EE-APIs im Klassenpfad oder Modulpfad. Sie können beispielsweise die JAX-B-APIs als Maven-Abhängigkeit wie folgt hinzufügen:

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

Ausführliche Informationen zur Java-Modularität finden Sie unter JEP 261: Modul System

761
Andy Guibert

In meinem Fall (Spring Boot Fat Jar) füge ich einfach pom.xml folgendes hinzu.

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

Im jüngsten JDK 9.0.1 hat keine dieser Lösungen für mich funktioniert.

Ich habe festgestellt, dass diese Liste von Abhängigkeiten für ein einwandfreies Funktionieren ausreicht, sodass Sie brauchen nicht explizit --add-module angeben müssen (obwohl dies in den pom's dieser Abhängigkeiten angegeben ist). Sie müssen nur diese Liste der Abhängigkeiten angeben:

<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

Das hat für mich funktioniert:

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

Aktualisieren

Wie von @Jasper vorgeschlagen, können Sie sich auch auf EclipseLink MOXy verlassen, um nicht von der gesamten EclipseLink-Bibliothek abhängig zu sein:

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'

Als Abhängigkeiten für meine Java 8-App, die eine * .jar erzeugt, die sowohl von JRE 8 als auch von JRE 9 ohne zusätzliche Argumente ausgeführt werden kann.

Außerdem muss dies irgendwo ausgeführt werden, bevor die JAXB-API verwendet wird:

System.setProperty("javax.xml.bind.JAXBContextFactory", "org.Eclipse.persistence.jaxb.JAXBContextFactory");

Funktioniert bisher hervorragend als Workaround. Sieht zwar nicht nach einer perfekten Lösung aus ...

35

es ist weil Java Version, wenn Sie jdk 9 oder eine neuere Version verwenden, fügen Sie dies einfach zu Ihrem Pom hinzu

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

Fügen Sie zum Zeitpunkt der Kompilierung sowie zur Laufzeit den Schalter --add-modules Java.xml.bind hinzu.

javac --add-modules Java.xml.bind <Java file name>

Java --add-modules Java.xml.bind <class file>

Eine gute Einführung in die JDK 9-Module finden Sie auch unter: https://www.youtube.com/watch?v=KZfbRuvv5qc

15
Pallavi Sonal

Sie können die JVM-Option --add-modules=Java.xml.bind verwenden, um der JVM-Laufzeitumgebung ein XML-Bindemodul hinzuzufügen.

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

11

Um dieses Problem zu lösen, habe ich einige JAR-Dateien in mein Projekt importiert:

  • 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. Laden Sie die oben genannten Dateien herunter und kopieren Sie sie in den libs-Ordner des Projekts
  2. Fügen Sie die importierten JAR-Dateien unter Java Build Path hinzu
10
fnascimento

Gehen Sie zu Your Build.gradle und fügen Sie die folgenden Abhängigkeiten für Java 9 oder Java 10 hinzu.

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

Das hat bei mir funktioniert. Nur Jaxb-api hinzuzufügen, war nicht genug.

        <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

Für die Ausführung von Java Web Start können wir den Vorschlag von Andy Guibert wie folgt verwenden:

<j2se version="1.6+" 
      Java-vm-args="-XX:+IgnoreUnrecognizedVMOptions --add-modules=Java.se.ee"/>

Beachten Sie das zusätzliche "=" in den --add-modules. Siehe dieses OpenJDK-Ticket oder den letzten Hinweis in "Grundlegendes zur Laufzeitwarnung" der Java-Plattform, Standard Edition Oracle JDK 9-Migrationshandbuch .

8
mvw
7
Sebastian Thees

Folgen Welche Artefakte sollte ich für JAXB RI in meinem Maven-Projekt verwenden? In Maven können Sie ein Profil wie folgt verwenden:

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

Abhängigkeitsbaum zeigt:

[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

Um dies in Eclipse zu verwenden, sagen Sie Oxygen.3a Release (4.7.3a) oder höher, Strg-Alt-P oder klicken Sie mit der rechten Maustaste auf das Projekt Maven und wählen Sie das Profil aus.

7
JasonPlutext

Ich folgte dieser URL und die unten aufgeführten Einstellungen hatten mir wirklich geholfen. Ich verwende Java 10 mit STS IDE in Macbook Pro. Es wirkt wie ein Zauber.

   <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

fügen Sie javax.xml.bind-Abhängigkeit in pom.xml hinzu

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

Das gleiche Problem ist bei der Verwendung von Spring Boot 2.0.5.RELEASE auf Java 11 aufgetreten.

Das Hinzufügen von javax.xml.bind:jaxb-api:2.3.0 allein hat das Problem nicht behoben. Ich musste auch Spring Boot auf den neuesten Meilenstein 2.1.0.M2 aktualisieren, daher gehe ich davon aus, dass dies in der nächsten offiziellen Version behoben wird.

3
Javide

Da JavaEE jetzt von https://jakarta.ee/ gesteuert wird, lauten die neuen Maven-Koordinaten ab 2.3.2:

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

Die erste veröffentlichte jaxb.version ist 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

Keine Antwort, sondern ein Nachtrag: Ich bekam, weil das Ausführen von groovysh (Groovy 2.4.13), wenn Java_HOME auf eine Java 9-Installation verweist (Java version "9.0.1", um genau zu sein) fehlschlägt:

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

Die Lösung war:

  • Gehen Sie zum JAXB-Projekt bei github.io ("JAXB ist unter einer Doppellizenz lizenziert - CDDL 1.1 und GPL 2.0 mit Klassenpfadausnahme").

  • jaxb-ri-2.3.0.Zip herunterladen

  • Entpacken Sie, wo immer Sie Ihre Java-Infrastrukturdateien ablegen (in meinem Fall /usr/local/Java/jaxb-ri/). Andere Lösung kann existieren (vielleicht über SDKMAN, ich weiß nicht)

  • Stellen Sie sicher, dass sich die Jars im lib-Unterverzeichnis auf der CLASSPATH befinden. Ich mache es über ein Skript, das beim bash-Start mit dem Namen /etc/profile.d/Java.sh gestartet wurde, wobei ich (neben vielen anderen Zeilen) die folgende Schleife hinzufügte:

In eine Funktion verpackt ...

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

Und es funktioniert!

2
David Tonhofer

OK, ich hatte die gleiche Art von Problem, aber ich verwendete Java 8, und dieser Fehler wurde immer wieder angezeigt. Ich habe die meisten Lösungen ausprobiert. aber es stellt sich heraus, dass mein maven immer noch auf java 9 zeigte, obwohl ich das globale java auf 8 gesetzt habe. Sobald ich also festgestellt habe, dass alles funktioniert hat, sollten Sie (für alle Personen, die dieses problem haben könnten) zu beheben, dass Maven Standard-Java verwendet) https://blog.tompawlak.org/maven-default-Java-version-mac-osx

1
Ipkiss

Alte Antwort "Problem durch Umstieg auf amazoncorretto behoben" Antwort in der Nachricht: Ich habe Corretto zuletzt verwendet, ist aber ähnlich jdk 1.8. Wir müssen also Abhängigkeiten manuell hinzufügen

1

Ich weiß, dass ich zu spät auf die Party komme, aber mein Fehler musste eine andere Lösung erfordern ... super einfach

Ursprünglich entledigte ich mich Tomcat 9 und stellte fest, dass ich 7 brauchte

Hoffentlich wird dies in Zukunft einen Fehler beheben, der dieses einfache Problem wie ich übersieht.

0
Tyler Miles

Die Abhängigkeitsversionen, die ich beim Kompilieren für Java 8-Ziel verwenden musste. Getestete Anwendung in Java 8, 11 und 12 JREs.

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

Das hat bei mir geklappt, ich habe ein Spring-Boot-Projekt, das in Java 8 kompiliert wird, aber ich weiß nicht, warum mein Maven eines Tages mit dem Kompilieren mit Java 11 begonnen hat. In Ubuntu habe ich dieses Problem behoben:

Sudo update-Java-alternatives  -l

Das hat mir das verfügbare JDK auf meinem PC gezeigt:

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

Also führe ich endlich diesen Befehl aus, um den gewünschten auszuwählen:

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

Und das wars auch schon, werfen Sie einen Blick auf Wie verwende ich den Befehl update alternatives

0

Sie müssen maven jaxb-Abhängigkeiten hinzufügen. Die Version 2.3.2 der Glassfish-Implementierung ist perfekt mit der neuen jakarta EE jaxb api-Version 2.3.2 kompatibel.

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

Für mich in Java 11 und gradle hat das geklappt:

plugins {
      id 'Java'
}

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

Dies löste meine Probleme mit Abhängigkeiten, die Apache Camel 2.24.1 auf Java 12 ausführen:

    <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