如何在 Java 9 中解决 java.lang.NoClassDefFoundError:javax/xml/bind/JAXBException
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 一起工作!
如果您尝试 –add-modules 使用较旧的 JDK 进行指定,那么它将会爆炸,因为它是一个无法识别的选项。我建议两种选择之一:
您可以使用 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 模块。
适当的长期解决方案:(JDK 9 及更高版本)
上面列出的 Java EE API 模块都已标记 @Deprecated(forRemoval=true),因为它们计划在 Java 11 中删除。因此,该 –add-module 方法将不再适用于 Java 11 开箱即用。
您需要在 Java 11 和转发中执行的操作是在类路径或模块路径上包含您自己的 Java EE API 副本。例如,您可以将 JAX-B API 添加为 maven 依赖项,如下所示:
<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>
有关 Java 模块化的完整详细信息,请参阅 JEP 261:模块系统
对于 Gradle 或 Android Studio 开发人员:(JDK 9 及更高版本)
将以下依赖项添加到 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"
}