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?
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:
$Java_HOME/release
auf die Java_VERSION
-Eigenschaft überprüfen.-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
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>
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>
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>
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 ...
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>
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
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
Um dieses Problem zu lösen, habe ich einige JAR-Dateien in mein Projekt importiert:
http://search.maven.org/remotecontent?filepath=javax/xml/bind/jaxb-api/2.3.0/jaxb-api-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
http://search.maven.org/remotecontent?filepath=com/Sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0.jar
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'
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>
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 .
clean Lösung für alle JDKs> = 9
Sie müssen Ihrem Build zwei Abhängigkeiten hinzufügen
Als Implementierung entschied ich mich, die Referenzimplementierung von glassfish zu verwenden, um alte com.Sun-Klassen Bibliotheken zu entfernen ..__ Als Ergebnis fügte ich meinem Maven-Build hinzu
<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>
Beachten Sie, dass Sie ab Version 2.3.1 die javax.activation nicht mehr hinzufügen müssen. (siehe/- https://github.com/Eclipse-ee4j/jaxb-ri/issues/1222 )
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.
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>
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>
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.
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>
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!
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
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
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.
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 -->
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
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>
Für mich in Java 11 und gradle hat das geklappt:
plugins {
id 'Java'
}
dependencies {
runtimeOnly 'javax.xml.bind:jaxb-api:2.3.1'
}
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>