How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException in Java 9
我有一些代码使用JAXB API类,它们是作为Java 6/7/8中JDK的一部分提供的。 当我使用Java 9运行相同的代码时,在运行时我得到错误,指示无法找到JAXB类。
自Java 6以来,JAXB类已作为JDK的一部分提供,为什么Java 9不再能够找到这些类?
JAXB API被认为是Java EE API,因此不再包含在Java SE 9中的默认类路径中。在Java 11中,它们完全从JDK中删除。
Java 9引入了模块的概念,默认情况下,
幸运的是,JDK 6/7/8中提供的这些Java EE API仍然在JDK中,但它们默认情况下不在类路径上。以下模块中提供了额外的Java EE API:
1 2 3 4 5 6 | java.activation java.corba java.transaction java.xml.bind << This one contains the JAXB APIs java.xml.ws java.xml.ws.annotation |
快速而肮脏的解决方案:(仅限JDK 9/10)
要在运行时使JAXB API可用,请指定以下命令行选项:
但我仍然需要这个与Java 8一起工作!
如果您尝试使用较旧的JDK指定
替代快速解决方案:(仅限JDK 9/10)
请注意,您可以通过指定
适当的长期解决方案:(JDK 9及更高版本)
上面列出的Java EE API模块都标记为
您需要在Java 11和转发中执行的操作是在类路径或模块路径上包含您自己的Java EE API副本。例如,您可以将JAX-B API添加为maven依赖项,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <dependency> <groupId>javax.xml.bind</groupId> jaxb-api</artifactId> <version>2.2.11</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> jaxb-core</artifactId> <version>2.2.11</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> jaxb-impl</artifactId> <version>2.2.11</version> </dependency> <dependency> <groupId>javax.activation</groupId> activation</artifactId> <version>1.1.1</version> </dependency> |
有关Java模块化的完整详细信息,请参阅JEP 261:模块系统
对于Gradle或Android Studio开发人员:(JDK 9及更高版本)
将以下依赖项添加到build.gradle文件中:
1 2 3 4 5 6 7 | 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" } |
在我的情况下(spring boot fat jar)我只是将以下内容添加到pom.xml中。
1 2 3 4 5 | <dependency> <groupId>javax.xml.bind</groupId> jaxb-api</artifactId> <version>2.3.0</version> </dependency> |
在最近的JDK 9.0.1中,这些解决方案都不适用于我。
我发现这个依赖项列表足以实现正常运行,因此您不需要显式指定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <dependencies> <dependency> <groupId>javax.xml.bind</groupId> jaxb-api</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> jaxb-impl</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> jaxb-runtime</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>javax.activation</groupId> activation</artifactId> <version>1.1.1</version> </dependency> </dependencies> |
这对我有用:
1 2 3 4 5 6 7 8 9 10 | <dependency> <groupId>javax.xml.bind</groupId> jaxb-api</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> eclipselink</artifactId> <version>2.7.0</version> </dependency> |
更新
正如@Jasper建议的那样,为了避免依赖整个EclipseLink库,你也可以依赖于EclipseLink MOXy:
Maven的
1 2 3 4 5 | <dependency> <groupId>org.eclipse.persistence</groupId> org.eclipse.persistence.moxy</artifactId> <version>2.7.3</version> </dependency> |
摇篮
1 | compile group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.moxy', version: '2.7.3' |
作为我的Java 8应用程序的依赖项,它生成一个* .jar,它可以由JRE 8或JRE 9运行,没有其他参数。
此外,这需要在使用JAXB API之前在某处执行:
1 | System.setProperty("javax.xml.bind.JAXBContextFactory","org.eclipse.persistence.jaxb.JAXBContextFactory"); |
到目前为止工作得很好,作为一种解决方法。虽然看起来不是一个完美的解决方案......
这是因为java版本,如果你使用jdk 9或更高版本,只需将它添加到你的pom
1 2 3 4 5 | <dependency> <groupId>javax.xml.bind</groupId> jaxb-api</artifactId> <version>2.3.0</version> </dependency> |
在编译和运行时,添加开关
1 2 3 | javac --add-modules java.xml.bind <java file name> java --add-modules java.xml.bind <class file> |
还可以在以下位置找到
所有JDK的清洁解决方案> = 9
您需要为构建添加两个依赖项
- jaxb-api
- 一个jaxb实现
作为一个实现,我选择使用glassfish的参考实现来摆脱旧的com.sun类/库。
因此,我添加了我的maven构建
1 2 3 4 5 6 7 8 9 10 11 | <dependency> <groupId>javax.xml.bind</groupId> jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> jaxb-runtime</artifactId> <version>2.3.1</version> </dependency> |
请注意,从版本2.3.1开始,您不再需要添加javax.activation。 (见https://github.com/eclipse-ee4j/jaxb-ri/issues/1222)
为了解决这个问题,我在项目中导入了一些JAR文件:
- 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的核心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
您可以使用
例如:
这对我有用。仅添加jaxb-api是不够的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <dependency> <groupId>javax.xml.bind</groupId> jaxb-api</artifactId> <version>${jaxb-api.version}</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> jaxb-impl</artifactId> <version>${jaxb-api.version}</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> jaxb-core</artifactId> <version>${jaxb-api.version}</version> </dependency> |
转到Build.gradle并为Java 9或Java 10添加以下依赖项。
1 2 3 4 5 6 7 8 | 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' |
对于Java Web Start Execution,我们可以使用Andy Guibert的建议:
1 2 | <j2se version="1.6+" java-vm-args="-XX:+IgnoreUnrecognizedVMOptions --add-modules=java.se.ee"/> |
注意--add-modules中的额外"="。请参阅此OpenJDK Ticket或Java平台标准版Oracle JDK 9迁移指南的"了解运行时访问警告"中的最后一个注释。
2019年4月更新
适用于JAXB版本的Changelong位于https://javaee.github.io/jaxb-v2/doc/user-guide/ch02.html
摘录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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 |
权威链接位于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拉入:
1 2 3 4 5 6 7 | [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 |
原始答案
以下哪些工件应该用于我的Maven项目中的JAXB RI?在Maven中,您可以使用如下配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <profile> <id>java-9</id> <jdk>9</jdk> </activation> <dependencies> <dependency> <groupId>org.glassfish.jaxb</groupId> jaxb-runtime</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>javax.activation</groupId> activation</artifactId> <version>1.1.1</version> </dependency> </dependencies> </profile> |
依赖树显示:
1 2 3 4 5 6 7 8 | [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 |
要在Eclipse中使用它,请说Oxygen.3a Release(4.7.3a)或更高版本,Ctrl-Alt-P,或右键单击项目Maven,然后选择配置文件。
在pom.xml中添加javax.xml.bind依赖项
1 2 3 4 5 | <dependency> <groupId>javax.xml.bind</groupId> jaxb-api</artifactId> <version>2.3.0</version> </dependency> |
我按照这个URL,以下设置真的帮助了我。我在Macbook Pro中使用Java 10和STS IDE。它就像一个魅力。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <dependency> <groupId>javax.xml.bind</groupId> jaxb-api</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> jaxb-runtime</artifactId> <version>2.3.0</version> <scope>runtime</scope> </dependency> <dependency> <groupId>javax.activation</groupId> javax.activation-api</artifactId> <version>1.2.0</version> </dependency> |
我在Java 11上使用Spring Boot
单独添加
不是答案,而是一个附录:我得到了因为运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 |
解决方案是:
-
转到github.io上的JAXB项目("JAXB是根据双许可证授予的 - CDDL 1.1和带有类路径异常的GPL 2.0")
-
下载
jaxb-ri-2.3.0.zip -
解压缩放置java基础结构文件的位置(在我的情况下,
/usr/local/java/jaxb-ri/ )。可能存在其他解决方案(可能通过SDKMAN,我不知道) -
确保lib子目录中的jar位于
CLASSPATH 上。我通过在bash启动时启动的脚本(称为/etc/profile.d/java.sh )来执行此操作,其中我添加了(在许多其他行中)以下循环:
打包成一个功能......
1 2 3 4 5 6 7 8 9 10 11 | 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 |
它的工作原理!
由于JavaEE现在由https://jakarta.ee/管理,因此从2.3.2开始的新Maven坐标是:
https://github.com/eclipse-ee4j/jaxb-ri#maven-artifacts
第一个发布的jaxb.version是2.3.2。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <properties> <jaxb.version>2.3.2</jaxb.version> </properties> <dependency> <groupId>jakarta.xml.bind</groupId> jakarta.xml.bind-api</artifactId> <version>${jaxb.version}</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> jaxb-runtime</artifactId> <version>${jaxb.version}</version> </dependency> |
好吧,我一直有同样的问题,但我使用的是Java 8,并且不断收到此错误,我尝试了大多数解决方案。但事实证明我的maven仍然指向java 9甚至 - 虽然我将全局Java版本设置为8,一旦我修复它一切正常。
对于任何可能遇到此类问题的人,请查看如何修复Maven以使用默认Java
旧答案"切换到amazoncorretto解决了问题"
新闻回答:我使用了corretto最新版,但是类似于jdk 1.8。所以无论如何我们需要手动添加依赖项
这解决了我在Java 12上运行Apache Camel 2.24.1的依赖项的问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <dependency> <groupId>javax.activation</groupId> activation</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> jaxb-core</artifactId> <version>2.3.0.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> jaxb-impl</artifactId> <version>2.3.0.1</version> </dependency> |
我知道我迟到了,但我的错误最终需要一个不同的解决方案......超级简单
我原先去了Tomcat 9并意识到我需要7 ...我忘了将我的类路径映射回build.xml中的7版本
希望这将在未来解决别人的错误,他设法忽略了这个简单的问题,就像我一样!
这对我有用,我有一个用Java 8编译的Spring启动项目,但我不知道为什么有一天我的maven开始使用Java 11进行编译,在Ubuntu中我常常修复它:
1 | sudo update-java-alternatives -l |
这向我展示了我的电脑上可用的JDK:
1 | java-1.11.0-openjdk-amd64 1111 /usr/lib/jvm/java-1.11.0-openjdk-amd64 |
所以我最终运行此命令来选择所需的命令:
1 | sudo update-java-alternatives -s java-1.8.0-openjdk-amd64 |
就是这样,有关更多信息,请参阅如何使用命令更新替代方案
编译Java 8目标时需要使用的依赖版本。在Java 8,11和12 JRE中测试的应用程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <!-- replace dependencies that have been removed from JRE's starting with Java v11 --> <dependency> <groupId>javax.xml.bind</groupId> jaxb-api</artifactId> <version>2.2.8</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> jaxb-core</artifactId> <version>2.2.8-b01</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> jaxb-impl</artifactId> <version>2.2.8-b01</version> </dependency> <!-- end replace dependencies that have been removed from JRE's starting with Java v11 --> |
对于Java 11和gradle中的我来说,这是有用的:
1 2 3 4 5 6 7 | plugins { id 'java' } dependencies { runtimeOnly 'javax.xml.bind:jaxb-api:2.3.1' } |
您需要将jaxb依赖项添加到maven。 glassfish实现版本2.3.2与新的jakarta EE jaxb api版本2.3.2完全兼容。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!-- API --> <dependency> <groupId>jakarta.xml.bind</groupId> jakarta.xml.bind-api</artifactId> <version>2.3.2</version> </dependency> <!-- Runtime --> <dependency> <groupId>org.glassfish.jaxb</groupId> jaxb-runtime</artifactId> <version>2.3.2</version> </dependency> |