问题
I have some code that uses JAXB API classes which have been provided as a part of the JDK in Java 6/7/8. When I run the same code with Java 9, at runtime I get errors indicating that JAXB classes can not be found.
The JAXB classes have been provided as a part of the JDK since Java 6, so why can Java 9 no longer find these classes?
回答1:
The JAXB APIs are considered to be Java EE APIs, and therefore are no longer contained on the default class path in Java SE 9. In Java 11 they are completely removed from the JDK.
Java 9 introduces the concepts of modules, and by default the java.se
aggregate module is available on the class path (or rather, module path). As the name implies, the java.se
aggregate module does not include the Java EE APIs that have been traditionally bundled with Java 6/7/8.
Fortunately, these Java EE APIs that were provided in JDK 6/7/8 are still in the JDK, but they just aren't on the class path by default. The extra Java EE APIs are provided in the following modules:
java.activation
java.corba
java.transaction
java.xml.bind << This one contains the JAXB APIs
java.xml.ws
java.xml.ws.annotation
Quick and dirty solution: (JDK 9/10 only)
To make the JAXB APIs available at runtime, specify the following command-line option:--add-modules java.xml.bind
But I still need this to work with Java 8!!!
If you try specifying --add-modules
with an older JDK, it will blow up becase it's an unrecognized option. I suggest one of two options:
- You can set any Java 9+ only options using the
JDK_JAVA_OPTIONS
environment variable. This environment variable is automatically read by thejava
launcher for Java 9+. - You can add the
-XX:+IgnoreUnrecognizedVMOptions
to make the JVM silently ignore unrecognized options, instead of blowing up. But beware! Any other command line args you use will no longer be validated for you by the JVM. This option works with Oracle/OpenJDK as well as IBM JDK (as of JDK 8sr4)
Alternate quick solution: (JDK 9/10 only)
Note that you can make all of the above Java EE modules available at run time by specifying the --add-modules java.se.ee
option. The java.se.ee
module is an aggregate module that includes java.se.ee
as well as the above Java EE API modules. Note, this doesn't work on Java 11 because java.se.ee
was removed in Java 11.
Proper long-term solution: (JDK 9 and beyond)
The Java EE API modules listed above are all marked @Deprecated(forRemoval=true)
, because they are scheduled for removal in Java 11. So the --add-module
approach will no longer work in Java 11 out of the box.
What you will need to do in Java 11 and forward is include your own copy of the Java EE APIs on the class path or module path. For example, you can add the JAX-B APIs as a maven dependency like this:
<!-- API, java.xml.bind module -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.2</version>
</dependency>
<!-- Runtime, com.sun.xml.bind module -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>
See the JAXB Reference Implementation page for more details on JAXB.
For full details on Java modularity, see JEP 261: Module System
For Gradle or Android Studio developer: (JDK 9 and beyond)
Add the following dependencies to your build.gradle file:
dependencies {
// JAX-B dependencies for JDK 9+
implementation "jakarta.xml.bind:jakarta.xml.bind-api:2.3.2"
implementation "org.glassfish.jaxb:jaxb-runtime:2.3.2"
}
回答2:
In my case (spring boot fat jar) I just add the following to pom.xml.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
回答3:
None of these solutions worked fine for me in the recent JDK 9.0.1.
I found that this list of dependencies is enough for a proper functioning, so you don't need to explicitly specify --add-module
(though it is specified within these dependencies's pom's). The only you need is to specify this list of dependencies:
<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>
回答4:
This worked for me:
<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>
Update
As @Jasper suggested, in order to avoid depending on the entire EclipseLink library, you can also just depend on 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'
As dependencies for my Java 8 app, which produces a *.jar which can be run by both JRE 8 or JRE 9 with no additional arguments.
In addition, this needs to be executed somewhere before JAXB API will be used:
System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
Works great so far, as a workaround. Doesn't look like a perfect solution though...
回答5:
it´s because java version if you are using jdk 9 or a later version just add this to your pom
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
回答6:
At the time of compilation as well as run time, add the switch --add-modules java.xml.bind
javac --add-modules java.xml.bind <java file name>
java --add-modules java.xml.bind <class file>
A good introduction of the JDK 9
modules can also be found at :
https://www.youtube.com/watch?v=KZfbRuvv5qc
回答7:
To solve this, I have imported some JAR files in my project:
- 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
- Download above files and copy them into libs folder in the project
- Add the imported JAR files in Java Build Path
回答8:
clean solution for all JDKs >= 9
You need to add two dependencies to your build
- the jaxb-api
- a jaxb implementation
As an implementation I chose to use the reference implementation by glassfish to get rid of old com.sun classes / libraries. So as a result I added in my maven build
<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>
Note that from version 2.3.1 you don't need to add the javax.activation any longer. (see https://github.com/eclipse-ee4j/jaxb-ri/issues/1222)
回答9:
You can use --add-modules=java.xml.bind
JVM option to add xml bind module to JVM run-time environment.
Eg: java --add-modules=java.xml.bind XmlTestClass
回答10:
Update April 2019
Changelong for JAXB releases is at https://javaee.github.io/jaxb-v2/doc/user-guide/ch02.html
excerpts:
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
Authoritative link is at https://github.com/eclipse-ee4j/jaxb-ri#maven-artifacts
Maven coordinates for JAXB artifacts
jakarta.xml.bind:jakarta.xml.bind-api: API classes for JAXB. Required to compile against JAXB.
org.glassfish.jaxb:jaxb-runtime: Implementation of JAXB, runtime used for serialization and deserialization java objects to/from xml.
JAXB fat-jar bundles:
com.sun.xml.bind:jaxb-impl: JAXB runtime fat jar.
In contrast to org.glassfish.jaxb artifacts, these jars have all dependency classes included inside. These artifacts does not contain JPMS module descriptors. In Maven projects org.glassfish.jaxb artifacts are supposed to be used instead.
org.glassfish.jaxb:jaxb-runtime:jar:2.3.2 pulls in:
[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
Original Answer
Following Which artifacts should I use for JAXB RI in my Maven project? in Maven, you can use a profile like:
<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>
Dependency tree shows:
[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
To use this in Eclipse, say Oxygen.3a Release (4.7.3a) or later, Ctrl-Alt-P, or right-click on the project, Maven, then select the profile.
回答11:
This worked for me. Adding only jaxb-api wasn't enough.
<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>
回答12:
Go to Your Build.gradle and add below dependencies for both Java 9 or 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'
回答13:
For Java Web Start Execution we can use Andy Guibert's suggestion like this:
<j2se version="1.6+"
java-vm-args="-XX:+IgnoreUnrecognizedVMOptions --add-modules=java.se.ee"/>
Note the extra "=" in the --add-modules. See this OpenJDK Ticket or the last note in "Understanding Runtime Access Warnings" of the Java Platform, Standard Edition Oracle JDK 9 Migration Guide.
回答14:
add javax.xml.bind dependency in pom.xml
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
回答15:
I followed this URL and the below settings had really helped me. I use Java 10 with STS IDE in Macbook Pro. It works like a charm.
<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>
回答16:
I encountered the same issue using Spring Boot 2.0.5.RELEASE
on Java 11.
Adding javax.xml.bind:jaxb-api:2.3.0
alone did not fix the problem. I also had to update Spring Boot to the latest Milestone 2.1.0.M2
, so I assume this will be fixed in the next official release.
回答17:
This solved my problems with dependencies running Apache Camel 2.24.1 on 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>
回答18:
Not an answer, but an addendum: I got because running groovysh
(Groovy 2.4.13) if JAVA_HOME points to a Java 9 installation (java version "9.0.1"
to be precise) fails abysmally:
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
The solution was to:
Go to the JAXB Project at github.io ("JAXB is licensed under a dual license - CDDL 1.1 and GPL 2.0 with Class-path Exception")
Download
jaxb-ri-2.3.0.zip
Unzip wherever you put your java infrastructure files (in my case,
/usr/local/java/jaxb-ri/
). Other solution may exist (maybe via SDKMAN, I dunno)Make sure the jars in the lib subdirectory are on the
CLASSPATH
. I do it via a script started on bash startup, called/etc/profile.d/java.sh
, where I added (among many other lines) the following loop:
Packed into a function...
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
And it works!
回答19:
Since JavaEE is now governed by https://jakarta.ee/, the new Maven coordinates as of 2.3.2 are:
https://github.com/eclipse-ee4j/jaxb-ri#maven-artifacts
The first released jaxb.version is 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>
回答20:
OK, I have been having the same kind of issue, but I was using Java 8, and kept getting this error, I tried most of the solutions. but it turns out that my maven was still pointing to java 9 even-though I set the global Java version to 8, as soon as I fixed that it all worked.
For anybody who might have this kind of problem, check out How to fix Maven to use default Java
回答21:
Old answer "Problem resolved by switching to amazoncorretto" News answer: I used corretto latest , but is similar jdk 1.8. so anyway we need add dependencies manually
回答22:
For me in Java 11 and gradle this is what worked out:
plugins {
id 'java'
}
dependencies {
runtimeOnly 'javax.xml.bind:jaxb-api:2.3.1'
}
回答23:
You need to add jaxb dependancies to maven. The glassfish implementation version 2.3.2 is perfectly compatible with new jakarta EE jaxb api version 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>
回答24:
i had similar issues after upgrading my project to java 11, then what fixed it was upgrading to spring boot 2.1.1 which apparently has support for java 11, this helped
回答25:
I know I'm late to the party, but my error ended up needing a diffrent solution... super simple too
I originally depoloyed to Tomcat 9 and realised I needed 7... I forgot to map my class path back to the 7 version in build.xml
Hopefully this will fix someone elses error in the future, who manages to overlook this simple issue as I did!
回答26:
The dependency versions that I needed to use when compiling for Java 8 target. Tested application in Java 8, 11, and 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 -->
回答27:
If you are calling SOAP web services (for example, using jaxws-maven-plugin
) just by adding this dependency all JAXB errors disappear:
<dependency>
<groupId>org.glassfish.metro</groupId>
<artifactId>webservices-rt</artifactId>
<version>2.4.3</version>
</dependency>
Tested with Java 13
回答28:
Solution for SBT
libraryDependencies += "javax.xml.bind" % "jaxb-api" % "2.3.1"
回答29:
This worked for me, I have an spring boot project that compiles in Java 8 but I don't know why one day my maven started compiling with Java 11, in Ubuntu I used to fix it:
sudo update-java-alternatives -l
That showed me the availave JDK on my 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`
So I finally run this command to choose the desired one:
sudo update-java-alternatives -s java-1.8.0-openjdk-amd64
And that's it, for more into take a look at How to use the command update alternatives
来源:https://stackoverflow.com/questions/43574426/how-to-resolve-java-lang-noclassdeffounderror-javax-xml-bind-jaxbexception-in-j