Handling NoClassDefFoundError for JAXBException in Java 9 – 在Java 9中处理JAXBException的NoClassDefFoundError

最后修改: 2018年 4月 30日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

For anyone who has tried upgrading to Java 9, they have likely experienced some sort of NoClassDefFoundError when compiling code that previously worked in earlier versions of Java.

对于任何试图升级到Java 9的人来说,他们很可能在编译以前在早期版本的Java中工作的代码时遇到了某种NoClassDefFoundError

In this article, we’ll look at a common missing class, JAXBException, and different ways we can solve it. The solutions provided here are generally applicable to any class that may be missing when upgrading to Java 9.

在这篇文章中,我们将看看一个常见的缺失类,JAXBException,以及我们可以解决它的不同方法。这里提供的解决方案一般适用于升级到Java 9时可能缺失的任何类。

2. Why Java 9 Cannot Find JAXBException?

2.为什么Java 9找不到JAXBException

One of the most discussed features of Java 9 is the module system. The goal of the Java 9 module system is to break apart the core JVM classes and related projects into stand-alone modules. This helps us create applications with smaller footprints by only including the minimum required classes to run.

Java 9中讨论最多的功能之一是模块系统。Java 9模块系统的目标是将核心JVM类和相关项目分解成独立的模块。这有助于我们创建占地面积较小的应用程序,只包括运行所需的最小的类。

The downside is that many classes are no longer available on the classpath by default. In this case, the class JAXBExceptioncan be found in one of the new Jakarta EE modules named java.xml.bind. As this module isn’t required by the core Java runtime, it’s not available on the classpath by default.

缺点是许多类在默认情况下不再在classpath中可用。在这种情况下,JAXBException类可以在一个名为java.xml.bind的新Jakarta EE模块中找到。由于核心 Java 运行时不需要这个模块,因此默认情况下它在 classpath 中是不可用的。

Trying to run an application that uses JAXBExceptionwill result in:

试图运行一个使用JAXBException的应用程序将导致。

NoClassDefFoundError: javax/xml/bind/JAXBException

To get around this we must include the java.xml.bindmodule. As we’ll see below, there are multiple ways to accomplish this.

为了解决这个问题我们必须包括java.xml.bind模块。正如我们将在下面看到的,有多种方法来实现这一目标。

3. Short-Term Solution

3.短期的解决方案

The quickest way to make sure the JAXB API classes are available to an application is to add use the –add-modules command line argument:

确保JAXB API类对应用程序可用的最快速方法是添加使用-add-modules 命令行参数

--add-modules java.xml.bind

However, this might not be a good solution for a couple of reasons.

然而,由于几个原因,这可能不是一个好的解决方案。

First, the –add-modules argument is also new in Java 9. For applications that need to run on multiple versions of Java, this presents some challenges. We’d have to maintain multiple sets of build files, one for each Java version the application runs on.

首先,-add-modules参数在Java 9中也是新的。 对于需要在多个版本的Java上运行的应用程序,这带来了一些挑战。我们必须维护多套构建文件,为应用程序运行的每个Java版本建立一套。

To work around this we could also use the -XX:+IgnoreUnrecognizedVMOptionscommand line argument for older Java compilers.

为了解决这个问题,我们也可以使用-XX:+IgnoreUnrecognizedVMOptions命令行参数,用于旧的Java编译器。

However, this means any typo or misspelled argument won’t be brought to our attention. For example, if we try to set a minimum or maximum heap size and mistype the argument name, we won’t get a warning. Our application will still start, but it will be running with a different configuration than we expect.

然而,这意味着任何错字或拼写错误的参数都不会被提请我们注意。例如,如果我们试图设置一个最小或最大的堆大小,但打错了参数名称,我们不会得到一个警告。我们的应用程序仍然会启动,但它将以与我们预期不同的配置运行。

Second, the –add-modules option will be deprecated in a future Java release. This means at some point after we upgrade to a new version of Java, we’ll face the same problem of using an unknown command line argument and have to address the issue again.

第二,-add-modules选项将在未来的Java版本中被弃用。这意味着在我们升级到新的Java版本后的某个时刻,我们将面临使用未知命令行参数的同样问题,不得不再次解决这个问题。

4. Long-Term Solution

4.长期的解决方案

There is a better approach that will work across different versions of Java and will not break with future releases.

有一种更好的方法,可以在不同版本的Java中使用,并且不会在未来的版本中出现故障。

The solution is to utilize a dependency management tool such as Maven. With this approach we would add the JAXB API library as a dependency just like any other library:

解决办法是使用依赖管理工具,如Maven。通过这种方法,我们可以像其他库一样,将JAXB API库作为一个依赖项加入。

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>

The above library only contains the JAXB API classes, which includes JAXBException. Depending on the application we may need to include other modules.

上述库只包含JAXB API类,其中包括JAXBException。根据不同的应用,我们可能需要包括其他模块。

Also keep in mind that the Maven artifact names may be different than the Java 9 module name, as is the case for JAXB API. It can be found on Maven Central.

另外请记住,Maven工件名称可能与Java 9模块名称不同,JAXB API就是如此。它可以在Maven Central上找到。

5. Conclusion

5.结论

The Java 9 module system provides a number of benefits such as decreasing application size and better performance.

Java 9模块系统提供了许多好处,如减少应用程序的大小和更好的性能。

However, it also introduces some unintended consequences. When upgrading to Java 9 it is important to understand which modules an application truly requires and take steps to ensure they are available on the classpath.

然而,它也带来了一些意想不到的后果。当升级到Java 9时,重要的是了解应用程序真正需要哪些模块,并采取措施确保它们在classpath上可用。