Java 9中Jaxbexception简介
1. 简介
对于尝试升级到 Java 9 的任何人,他们在编译以前在 Java 早期版本中工作的代码时可能会遇到某种NoClassDefFoundError。 在本文中,我们将研究一个常见的缺失类JAXBException以及我们可以解决它的不同方法。此处提供的解决方案通常适用于升级到 Java 9 时可能缺少的任何类。
2. 为什么 Java 9 找不到JAXBException?
Java 9 中讨论最多的特性之一是模块系统。Java 9 模块系统的目标是将核心 JVM 类和相关项目分解为独立模块。这有助于我们通过仅包含运行所需的最少类来创建占用空间更小的应用程序。
缺点是默认情况下许多类在类路径中不再可用。在这种情况下,可以在名为java.xml.bind的新 Jakarta EE 模块之一中找到JAXBException类。由于核心 Java 运行时不需要此模块,因此默认情况下它在类路径中不可用。 尝试运行使用JAXBException的应用程序将导致:
NoClassDefFoundError: javax/xml/bind/JAXBException
为了解决这个问题**,我们必须包含java.xml.bind模块**。正如我们将在下面看到的,有多种方法可以实现这一点。
3. 短期解决方案
确保 JAXB API 类对应用程序可用的最快方法是添加使用*–add-modules*命令行参数:
--add-modules java.xml.bind
但是,由于几个原因,这可能不是一个好的解决方案。
首先,–add-modules参数在 Java 9 中也是新的。对于需要在多个 Java 版本上运行的应用程序,这带来了一些挑战。我们必须维护多组构建文件,一个用于运行应用程序的每个 Java 版本。
为了解决这个问题,我们还可以为旧版 Java 编译器使用*-XX:+IgnoreUnrecognizedVMOptions*命令行参数。
但是,这意味着任何拼写错误或拼写错误的论点都不会引起我们的注意。例如,如果我们尝试设置最小或最大堆大小并错误输入参数名称,我们将不会收到警告。我们的应用程序仍将启动,但它将以与我们预期不同的配置运行。
其次,在未来的 Java 版本中将不推荐使用*–add-modules 选项。*这意味着在我们升级到新版本的 Java 后,我们将面临使用未知命令行参数的相同问题,并且必须再次解决该问题。
4. 长期解决方案
有一种更好的方法适用于不同版本的 Java,并且不会因未来的版本而中断。 解决方案是 使用依赖管理工具,例如 Maven。使用这种方法,我们将像任何其他库一样添加 JAXB API 库作为依赖项:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
上述库仅包含 JAXB API 类,其中包括JAXBException。根据应用程序,我们可能需要包含其他模块。
还要记住,Maven 工件名称可能与 Java 9 模块名称不同,就像 JAXB API 的情况一样。它可以在Maven Central 上找到。