我有一些使用JAXB API类的代码,这些类已作为Java 6/7/8中的JDK的一部分提供。当我用Java 9运行相同的代码时,在运行时得到错误,指示找不到JAXB类。
从Java 6开始,JAXB类就作为JDK的一部分提供了,那么为什么Java 9再也找不到这些类了呢?
我有一些使用JAXB API类的代码,这些类已作为Java 6/7/8中的JDK的一部分提供。当我用Java 9运行相同的代码时,在运行时得到错误,指示找不到JAXB类。
从Java 6开始,JAXB类就作为JDK的一部分提供了,那么为什么Java 9再也找不到这些类了呢?
当前回答
我在Debian 10中开发Java项目时遇到了这个问题。
每次我启动应用程序时,它都会在日志文件中抛出错误:
java.lang.NoClassDefFoundError: javax / xml /绑定/ JAXBException
以下是我的解决方法:
这个问题通常是在类路径中缺少JAXB库(用于XML绑定的Java体系结构)时引起的。JAXB包含在Java SE 10或更早版本中,但从Java 11或更新版本的Java SE中删除了它—在Jakarta EE项目下转移到Java EE。
所以,我检查我的Java版本使用:
java --version
它的输出是这样的
openjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+10-post-Debian-1deb10u1)
OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Debian-1deb10u1, mixed mode, sharing)
因此,我遇到了JAXBException错误,因为我使用的是Java 11,该类路径中没有JAXB库(用于XML绑定的Java体系结构)。其中包括JAXB。
为了解决这个问题,我必须将JAXB API库添加到我的tomcat安装的lib (/opt/tomcat/lib)目录:
sudo wget https://repo1.maven.org/maven2/javax/xml/bind/jaxb-api/2.4.0-b180830.0359/jaxb-api-2.4.0-b180830.0359.jar
然后我将它从jaxb-api-2.4.0-b180830.0359.jar重命名为jaxb-api.jar:
sudo mv jaxb-api-2.4.0-b180830.0359.jar jaxb-api.jar
注意:确保您更改了允许tomcat访问该文件的权限,并将所有权更改为tomcat:
sudo chown -R tomcat:tomcat /opt/tomcat
sudo chmod -R 777 /opt/tomcat/
然后重启tomcat服务器:
sudo systemctl restart tomcat
资源:[解决]java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
这是所有。
其他回答
您可以使用这个依赖项
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
JAXB api被认为是Java EE api,因此不再包含在Java SE 9的默认类路径中。在Java 11中,它们完全从JDK中删除了。
Java 9引入了模块的概念,默认情况下,Java。Se聚合模块在类路径(或者更确切地说,模块路径)上可用。顾名思义,java。se聚合模块不包括传统上与Java 6/7/8绑定的Java EE api。
幸运的是,JDK 6/7/8中提供的这些Java EE api仍然在JDK中,但默认情况下它们不在类路径中。额外的Java EE api在以下模块中提供:
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.xml.bind
但我仍然需要这与Java 8一起工作!!
如果尝试使用较旧的JDK指定——add-modules,将会失败,因为它是一个无法识别的选项。我建议有两个选择:
您可以使用JDK_JAVA_OPTIONS环境变量设置任何Java 9+选项。这个环境变量由java 9+的java启动器自动读取。 您可以添加-XX:+IgnoreUnrecognizedVMOptions,以使JVM静默地忽略无法识别的选项,而不是爆发。但是要小心!JVM将不再验证您使用的任何其他命令行参数。此选项适用于Oracle/OpenJDK以及IBM JDK(从JDK 8sr4开始)。
替代快速解决方案:(仅限JDK 9/10)
注意,通过指定——add-modules Java .se. EE选项,可以在运行时使用上述所有Java EE模块。Java .se. EE模块是一个聚合模块,它包括Java .se. EE以及上面的Java EE API模块。注意,这在Java 11上不起作用,因为Java .se.ee在Java 11中被删除了。
适当的长期解决方案:(JDK 9及以上版本)
上面列出的Java EE API模块都被标记为@Deprecated(forRemoval=true),因为它们在Java 11中被计划删除。因此——add-module方法将不再在Java 11开箱即用中工作。
在Java 11中需要做的是在类路径或模块路径中包含您自己的Java EE api副本。例如,你可以像这样添加JAX-B api作为Maven依赖:
<!-- 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>
有关JAXB的更多详细信息,请参阅JAXB参考实现页。
有关Java模块化的详细信息,请参见JEP 261:模块系统
截至2022年7月,bind-api和jaxb-runtime的最新版本是4.0.0。所以你也可以用
<version>4.0.0</version>
…在这些依赖子句中。但是如果你这样做,包的名称已经从javax.xml.bind…jakarta.xml.bind……您将需要修改源代码以使用这些jar的后续版本。
对于Gradle或Android Studio开发者:(JDK 9及以上版本)
将以下依赖项添加到构建中。gradle文件:
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"
}
我还碰到了ClassNotFoundException:javax.xml.bind。DatatypeConverter使用Java 11和
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
我尝试了添加javax.xml的所有方法。绑定:jaxb-api或spring boot jakarta.xml。bind-api . .我发现了一个关于jjwt 0.10.0版本修复的提示。但最重要的是,JJWT包现在是分开的!
因此,查看这个参考:https://github.com/jwtk/jjwt/issues/510
很简单,如果你使用
Java11和 jjwt 0.9。x和 你将面临ClassNotFoundException:javax.xml.bind。DatatypeConverter问题,
去
JJWT 0.11版。X,但是使用分离的包:https://github.com/jwtk/jjwt#install
你的maven找不到更高版本的jjwt依赖,因为他们把包分开了。
欢呼。
不是答案,而是一个附录:我得到的原因是,如果JAVA_HOME指向Java 9安装(准确地说是Java版本“9.0.1”),则运行groovysh (Groovy 2.4.13)会失败:
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
解决方案是:
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:
打包到函数中…
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
它确实有效!
干净的解决方案为所有jdk >= 9
您需要向构建中添加两个依赖项
的jaxb-api jaxb实现
作为实现,我选择使用glassfish的参考实现来摆脱旧的com。Sun类/库。 因此,我添加了我的专业构建
<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>
注意,从版本2.3.1开始,您不需要添加javax。不再激活。(参见https://github.com/eclipse-ee4j/jaxb-ri/issues/1222)