java - thread - jaxb-api
Cómo resolver java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException en Java 9 (23)
Tengo un código que usa clases de API JAXB que se han proporcionado como parte del JDK en Java 6/7/8. Cuando ejecuto el mismo código con Java 9, en tiempo de ejecución obtengo errores que indican que no se pueden encontrar las clases JAXB.
Las clases JAXB se han proporcionado como parte del JDK desde Java 6, entonces, ¿por qué Java 9 ya no puede encontrar estas clases?
Dado que JavaEE ahora se rige por https://jakarta.ee/ , las nuevas coordenadas de Maven a partir de 2.3.2 son:
github.com/eclipse-ee4j/jaxb-ri#maven-artifacts
El primer jaxb.version lanzado es 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>
En el momento de la compilación y el tiempo de ejecución, agregue el
--add-modules java.xml.bind
javac --add-modules java.xml.bind <java file name>
java --add-modules java.xml.bind <class file>
También puede encontrar una buena introducción de los módulos
JDK 9
en:
https://www.youtube.com/watch?v=KZfbRuvv5qc
En mi caso (spring boot fat jar) solo agrego lo siguiente a pom.xml.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
Encontré el mismo problema usando Spring Boot
2.0.5.RELEASE
en Java 11.
Agregar
javax.xml.bind:jaxb-api:2.3.0
solo no solucionó el problema.
También tuve que actualizar Spring Boot al último Milestone
2.1.0.M2
, así que supongo que esto se solucionará en la próxima versión oficial.
Esto funcionó para mí, tengo un proyecto de arranque de primavera que se compila en Java 8 pero no sé por qué un día mi experto comenzó a compilar con Java 11, en Ubuntu solía solucionarlo:
sudo update-java-alternatives -l
Eso me mostró el JDK disponible en mi 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
Entonces finalmente ejecuto este comando para elegir el deseado:
sudo update-java-alternatives -s java-1.8.0-openjdk-amd64
Y eso es todo, para más información sobre cómo usar las alternativas de actualización de comandos
Esto funcionó para mí. Agregar solo jaxb-api no fue suficiente.
<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>
Esto funcionó para mí:
<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>
Actualizar
Como sugirió @Jasper, para evitar depender de toda la biblioteca EclipseLink, también puede depender 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''
Como dependencias para mi aplicación Java 8, que produce un * .jar que puede ejecutar JRE 8 o JRE 9 sin argumentos adicionales.
Además, esto debe ejecutarse en algún lugar antes de que se use la API JAXB:
System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
Funciona muy bien hasta ahora, como una solución alternativa. Sin embargo, no parece una solución perfecta ...
Las API JAXB se consideran API Java EE y, por lo tanto, ya no se encuentran en la ruta de clase predeterminada en Java SE 9. En Java 11, se eliminan por completo del JDK.
Java 9 presenta los conceptos de módulos y, de forma predeterminada, el módulo agregado
java.se
está disponible en la ruta de clase (o más bien, ruta de módulo).
Como su nombre lo indica, el módulo agregado
java.se
no
incluye las API Java EE que se han incluido tradicionalmente con Java 6/7/8.
Afortunadamente, estas API Java EE que se proporcionaron en JDK 6/7/8 todavía están en el JDK, pero simplemente no están en la ruta de clase de forma predeterminada. Las API extra de Java EE se proporcionan en los siguientes módulos:
java.activation
java.corba
java.transaction
java.xml.bind << This one contains the JAXB APIs
java.xml.ws
java.xml.ws.annotation
Solución rápida y sucia: (solo JDK 9/10)
Para que las API JAXB estén disponibles en tiempo de ejecución, especifique la siguiente opción de línea de comandos:
--add-modules java.xml.bind
¡Pero todavía necesito esto para trabajar con Java 8!
Si intenta especificar
--add-modules
con un JDK anterior, explotará porque es una opción no reconocida.
Sugiero una de dos opciones:
-
Puede establecer cualquier opción de Java 9+ solamente utilizando la variable de entorno
JDK_JAVA_OPTIONS
. El lanzador de Java lee automáticamente esta variable de entorno para Java 9+. -
Puede agregar
-XX:+IgnoreUnrecognizedVMOptions
para hacer que la JVM ignore silenciosamente las opciones no reconocidas, en lugar de explotar. ¡Pero cuidado! La JVM ya no validará ningún otro argumento de línea de comando que utilice. Esta opción funciona con Oracle / OpenJDK así como con IBM JDK (a partir de JDK 8sr4)
Solución rápida alternativa: (solo JDK 9/10)
Tenga en cuenta que puede hacer que todos los módulos Java EE anteriores estén disponibles en tiempo de ejecución especificando la
--add-modules java.se.ee
El módulo
java.se.ee
es un módulo agregado que incluye
java.se.ee
, así como los módulos API Java EE anteriores.
Solución adecuada a largo plazo: (JDK 9 y más allá)
Todos los módulos de API Java EE enumerados anteriormente están marcados con
@Deprecated(forRemoval=true)
, porque están
programados para su eliminación
en
Java 11
.
Por lo tanto, el enfoque
--add-module
ya no funcionará en Java 11 fuera de la caja.
Lo que deberá hacer en Java 11 y en adelante es incluir su propia copia de las API de Java EE en la ruta de clase o la ruta del módulo. Por ejemplo, puede agregar las API JAX-B como una dependencia maven como esta:
<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>
Para obtener detalles completos sobre la modularidad de Java, consulte JEP 261: Sistema de módulos
Para desarrolladores de Gradle o Android Studio: (JDK 9 y más allá)
Agregue las siguientes dependencias a su archivo build.gradle:
dependencies {
// JAX-B dependencies for JDK 9+
implementation "javax.xml.bind:jaxb-api:2.2.11"
implementation "com.sun.xml.bind:jaxb-core:2.2.11"
implementation "com.sun.xml.bind:jaxb-impl:2.2.11"
implementation "javax.activation:activation:1.1.1"
}
Las versiones de dependencia que necesitaba usar al compilar para el destino Java 8. Aplicación probada en Java 8, 11 y 12 JRE.
<!-- 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 -->
Ninguna de estas soluciones funcionó bien para mí en el reciente JDK 9.0.1.
Descubrí que esta lista de dependencias es suficiente para un funcionamiento adecuado, por lo
que no necesita
especificar explícitamente
--add-module
(aunque se especifica dentro de los pom de estas dependencias).
Lo único que necesita es especificar esta lista de dependencias:
<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>
No es una respuesta, sino un apéndice: obtuve porque ejecutar
groovysh
(Groovy 2.4.13) si JAVA_HOME apunta a una instalación de Java 9 (la
java version "9.0.1"
para ser precisos) falla abismalmente:
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 solución fue:
-
Vaya al Proyecto JAXB en github.io ( "JAXB tiene licencia bajo una licencia dual: CDDL 1.1 y GPL 2.0 con excepción de ruta de clase" )
-
Descargar
jaxb-ri-2.3.0.zip
-
Descomprima donde sea que haya puesto sus archivos de infraestructura de Java (en mi caso,
/usr/local/java/jaxb-ri/
). Puede existir otra solución (tal vez a través de SDKMAN, no sé) -
Asegúrese de que los frascos en el subdirectorio lib estén en
CLASSPATH
. Lo hago a través de un script iniciado en el inicio de bash, llamado/etc/profile.d/java.sh
, donde agregué (entre muchas otras líneas) el siguiente ciclo:
Empaquetado en una función ...
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
¡Y funciona!
OK, he tenido el mismo tipo de problema, pero estaba usando Java 8 y seguí recibiendo este error, probé la mayoría de las soluciones. Pero resulta que mi experto todavía apuntaba a Java 9, aunque configuré la versión global de Java en 8, tan pronto como solucioné que todo funcionaba.
Para cualquiera que pueda tener este tipo de problema, consulte Cómo arreglar Maven para usar Java predeterminado
Para Java Web Start Execution podemos usar la sugerencia de Andy Guibert de esta manera:
<j2se version="1.6+"
java-vm-args="-XX:+IgnoreUnrecognizedVMOptions --add-modules=java.se.ee"/>
Tenga en cuenta el "=" extra en los módulos --add. Consulte este Ticket de OpenJDK o la última nota en "Descripción de las advertencias de acceso en tiempo de ejecución" de la docs.oracle.com/javase/9/migrate .
Para resolver esto, he importado algunos archivos JAR en mi proyecto:
- 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
- Descargue los archivos anteriores y cópielos en la carpeta libs en el proyecto
- Agregue los archivos JAR importados en Java Build Path
Puede usar la
--add-modules=java.xml.bind
JVM para agregar el módulo de
--add-modules=java.xml.bind
xml al entorno de tiempo de ejecución JVM.
Por ejemplo:
java --add-modules=java.xml.bind XmlTestClass
Respuesta anterior "Problema resuelto cambiando a amazoncorretto" Respuesta de noticias: Utilicé corretto más reciente, pero es similar a jdk 1.8. así que de todos modos necesitamos agregar dependencias manualmente
Sé que llego tarde a la fiesta, pero mi error terminó necesitando una solución diferente ... super simple también
Originalmente utilicé Tomcat 9 y me di cuenta de que necesitaba 7 ... Olvidé asignar mi ruta de clase a la versión 7 en build.xml
¡Esperemos que esto solucione el error de alguien más en el futuro, que logra pasar por alto este simple problema como lo hice yo!
Seguí esta URL y la configuración a continuación realmente me ayudó. Yo uso Java 10 con STS IDE en Macbook Pro. Funciona a las mil maravillas.
<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>
Vaya a Your Build.gradle y agregue las siguientes dependencias para Java 9 o 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''
agregar dependencia javax.xml.bind en pom.xml
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
es porque la versión de Java si está utilizando jdk 9 o una versión posterior simplemente agregue esto a su pom
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
Actualización de abril de 2019
Changelong para los lanzamientos de JAXB está en https://javaee.github.io/jaxb-v2/doc/user-guide/ch02.html
extractos:
4.1. Changes between 2.3.0.1 and 2.4.0
JAXB RI is now JPMS modularized:
All modules have native module descriptor.
Removed jaxb-core module, which caused split package issue on JPMS.
RI binary bundle now has single jar per dependency instead of shaded fat jars.
Removed runtime class weaving optimization.
4.2. Changes between 2.3.0 and 2.3.0.1
Removed legacy technology dependencies:
com.sun.xml.bind:jaxb1-impl
net.java.dev.msv:msv-core
net.java.dev.msv:xsdlib
com.sun.xml.bind.jaxb:isorelax
4.3. Changes between 2.2.11 and 2.3.0
Adopt Java SE 9:
JAXB api can now be loaded as a module.
JAXB RI is able to run on Java SE 9 from the classpath.
Addes support for java.util.ServiceLoader mechanism.
Security fixes
El enlace autorizado está en github.com/eclipse-ee4j/jaxb-ri#maven-artifacts
Coordenadas de Maven para artefactos JAXB
jakarta.xml.bind: jakarta.xml.bind-api: clases de API para JAXB. Necesario para compilar contra JAXB.
org.glassfish.jaxb: jaxb-runtime: Implementación de JAXB, tiempo de ejecución utilizado para serialización y deserialización de objetos java a / desde xml.
Paquetes JAXB fat-jar:
com.sun.xml.bind: jaxb-impl: JAXB runtime fat jar.
A diferencia de los artefactos org.glassfish.jaxb, estos frascos tienen todas las clases de dependencia incluidas dentro. Estos artefactos no contienen descriptores de módulo JPMS. En los proyectos de Maven, se supone que se deben utilizar los artefactos org.glassfish.jaxb.
org.glassfish.jaxb: jaxb-runtime: jar: 2.3.2 extrae:
[INFO] +- org.glassfish.jaxb:jaxb-runtime:jar:2.3.2:compile
[INFO] | +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.2:compile
[INFO] | +- org.glassfish.jaxb:txw2:jar:2.3.2:compile
[INFO] | +- com.sun.istack:istack-commons-runtime:jar:3.0.8:compile
[INFO] | +- org.jvnet.staxex:stax-ex:jar:1.8.1:compile
[INFO] | +- com.sun.xml.fastinfoset:FastInfoset:jar:1.2.16:compile
[INFO] | /- jakarta.activation:jakarta.activation-api:jar:1.2.1:compile
Respuesta original
Siguiente ¿Qué artefactos debo usar para JAXB RI en mi proyecto Maven? en Maven, puedes usar un perfil como:
<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>
El árbol de dependencias muestra:
[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
Para usar esto en Eclipse, diga Oxygen.3a Release (4.7.3a) o posterior, Ctrl-Alt-P, o haga clic derecho en el proyecto, Maven, luego seleccione el perfil.
solución limpia para todos los JDK> = 9
Necesita agregar dos dependencias a su compilación
- el jaxb-api
- una implementación jaxb
Como implementación, elegí usar la implementación de referencia de glassfish para deshacerme de las antiguas clases / bibliotecas com.sun. Como resultado, agregué mi construcción 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>
Tenga en cuenta que desde la versión 2.3.1 ya no necesita agregar javax.activation. (ver https://github.com/eclipse-ee4j/jaxb-ri/issues/1222 )