JAXB类自Java 6以来已经作为JDK的一部分提供,那么为什么Java 9找不到这些类了呢?
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可用,请指定以下命令行选项:
--add-modules 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中已被删除。
上述Java EE API模块都标有@Deprecated(forRemoval=true)
,因为它们在Java 11中计划删除。因此,在Java 11中,--add-module
方法将不再默认工作。
在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及以上)
将以下依赖项添加到您的build.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"
}
javax.xml.bind
和其他JavaEE类将在Java 11中被移除。 - Joep Weijersjava.se.ee
模块已被移除,所以--add-modules
的解决方案不再适用。取而代之的是使用推荐的解决方案:将JAXB作为单独的依赖项添加。 - Jesper<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
testCompile('javax.xml.bind:jaxb-api')
对我有效。 - pamcevoy<scope>runtime</scope>
。 - VladS您需要将两个依赖项添加到构建中:
作为实现,我选择使用 glassfish 的参考实现来摆脱旧的 com.sun 类/库。因此,在我的 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>
请注意,从2.3.1版本开始,您无需再添加javax.activation。(请参见https://github.com/eclipse-ee4j/jaxb-ri/issues/1222)。
对我来说,这些解决方案在最近的JDK 9.0.1中都不起作用。
我发现这个依赖项列表足以实现适当的功能,因此您不需要显式指定--add-module
(尽管它在这些依赖项的pom中已经被指定)。唯一需要做的就是指定这个依赖项列表:
<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>
pom.xml
文件。如果你不知道它是什么,最好从头开始学起。 - Andremoniy<dependency>
中的javax.activation-api
作为最后一个依赖项。 - scrutari这对我起作用:
<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>
如@Jasper所建议的那样,为了避免依赖整个EclipseLink库,您也可以只依赖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'
作为我的Java 8应用程序的依赖项,它可以生成一个*.jar文件,该文件可以在JRE 8或JRE 9上运行而无需任何其他参数。System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
目前为止,作为一种解决方法表现良好。但看起来并不完美...
org.eclipse.persistence:eclipselink
是一种非常重的依赖,除非您已经在使用eclipselink? - Andy Guibert-XX:+IgnoreUnrecognizedVMOptions
命令行选项(已更新我的答案,包含详细信息)。 - Andy Guibertorg.eclipse.persistence
,artifactId org.eclipse.persistence.moxy
。 - Jesper这是因为您使用的是JDK 9或更高版本,只需将以下内容添加到您的pom文件中即可解决该问题。
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
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
com.sun.xml.bind
依赖项已经过时,仅提供向后兼容性。建议使用等效的 org.glassfish.jaxb
依赖项,正如其他答案中所提到的那样。 - Jesper--add-modules java.xml.bind
。javac --add-modules java.xml.bind <java file name>
java --add-modules java.xml.bind <class file>
您还可以在以下链接中了解有关JDK 9
模块的良好介绍:
https://www.youtube.com/watch?v=KZfbRuvv5qc
在我的Debian 10上开发Java项目时,我遇到了这个问题。
每次启动应用程序时,日志文件中都会抛出以下错误:
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
以下是解决方法:
这个问题通常是由于类路径中缺少JAXB库(Java Architecture for XML Binding)引起的。JAXB包含在Java SE 10或更早版本中,但从Java 11或新版本中删除 - 移至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 库(Java Architecture for XML Binding)。为了解决这个问题,我需要将 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
就这些。
我也在使用Java 11时遇到了ClassNotFoundException:javax.xml.bind.DatatypeConverter。
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
我尝试了所有添加javax.xml.bind: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依赖的更高版本。
干杯。