如何解决 java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException [英] How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

查看:34
本文介绍了如何解决 java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些使用 JAXB API 类的代码,这些类在 Java 6/7/8 中作为 JDK 的一部分提供.当我使用 Java 9 运行相同的代码时,在运行时我收到错误消息,指出找不到 JAXB 类.

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.

JAXB 类从 Java 6 开始就作为 JDK 的一部分提供了,那么为什么 Java 9 再也找不到这些类了?

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?

推荐答案

JAXB API 被认为是 Java EE API,因此不再包含在 Java SE 9 的默认类路径中.在 Java 11 中,它们被完全删除来自 JDK.

The JAXB APIs are considered to be Java EE APIs and therefore are no longer contained on the default classpath in Java SE 9. In Java 11, they are completely removed from the JDK.

Java 9 引入了模块的概念,默认情况下,java.se 聚合模块在类路径(或者更确切地说,模块路径)上可用.顾名思义,java.se 聚合模块包括传统上与 Java 6/7/8 捆绑在一起的 Java EE API.

Java 9 introduces the concepts of modules, and by default, the java.se aggregate module is available on the classpath (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.

幸运的是,JDK 6/7/8 中提供的这些 Java EE API 仍在 JDK 中,但默认情况下它们不在类路径中.以下模块中提供了额外的 Java EE API:

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 classpath 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

快速而肮脏的解决方案:(仅限 JDK 9/10)

要使 JAXB API 在运行时可用,请指定以下命令行选项:

To make the JAXB APIs available at runtime, specify the following command-line option:

--add-modules java.xml.bind

但我仍然需要它来使用 Java 8!!!

如果您尝试使用较旧的 JDK 指定 --add-modules,它会崩溃,因为它是一个无法识别的选项.我建议两种选择之一:

If you try specifying --add-modules with an older JDK, it will blow up because it's an unrecognized option. I suggest one of two options:

  1. 您可以使用 JDK_JAVA_OPTIONS 环境变量设置任何仅限 Java 9+ 的选项.这个环境变量是自动读取 通过 Java 9+ 的 java 启动器.
  2. 您可以添加 -XX:+IgnoreUnrecognizedVMOptions 以使 JVM 静默忽略无法识别的选项,而不是炸毁.但要小心!JVM 将不再为您验证您使用的任何其他命令行参数.此选项适用于 Oracle/OpenJDK 以及 IBM JDK(从 JDK 8sr4 开始).
  1. You can set any Java 9+ only options using the JDK_JAVA_OPTIONS environment variable. This environment variable is automatically read by the java launcher for Java 9+.
  2. You can add the -XX:+IgnoreUnrecognizedVMOptions to make the JVM silently ignore unrecognized options, instead of blowing up. But beware! Any other command-line arguments 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).


替代快速解决方案:(仅限 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 中已被删除.

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.

上面列出的 Java EE API 模块都标记为 @Deprecated(forRemoval=true) 因为它们是 计划在 Java 11 中删除.因此 --add-module 方法将不再适用于开箱即用的 Java 11.

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.

在 Java 11 及以后版本中,您需要做的是在类路径或模块路径中包含您自己的 Java EE API 副本.例如,您可以将 JAX-B API 添加为 Maven 依赖项,如下所示:

What you will need to do in Java 11 and forward is include your own copy of the Java EE APIs on the classpath 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>

有关 JAXB 的更多详细信息,请参阅 JAXB 参考实现页面.

See the JAXB Reference Implementation page for more details on JAXB.

有关 Java 模块化的完整详细信息,请参阅 JEP 261:模块系统

For full details on Java modularity, see JEP 261: Module System

对于 Gradle 或 Android Studio 开发者:(JDK 9 及更高版本)

将以下依赖项添加到您的 build.gradle 文件中:

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"
}

这篇关于如何解决 java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆