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

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


当前回答

好吧,我一直有同样的问题,但我使用的是Java 8,并不断得到这个错误,我尝试了大多数的解决方案。但事实证明,我的maven仍然指向java 9,即使我将全局java版本设置为8,只要我修复了它就能正常工作。

对于任何可能遇到这类问题的人,请参阅如何修复Maven以使用默认Java(已存档)

其他回答

如果你使用的是JDK 11,你可以将以下内容添加到你的Gradle(应用程序):

dependencies {
    ...
    annotationProcessor "javax.xml.bind:jaxb-api:2.3.1"
    ...
}

这对我很管用。

如果您正在调用SOAP web服务(例如,使用jaxws-maven-plugin),只需添加此依赖项,所有JAXB错误就会消失:

<dependency>
            <groupId>org.glassfish.metro</groupId>
            <artifactId>webservices-rt</artifactId>
            <version>2.4.3</version>
</dependency>

使用Java 13进行测试

为Java 8目标编译时需要使用的依赖项版本。在Java 8、11和12 JREs中测试的应用程序。

        <!-- replace dependencies that have been removed from JRE's starting with Java v11 -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.2.8</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.2.8-b01</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.2.8-b01</version>
        </dependency>
        <!-- end replace dependencies that have been removed from JRE's starting with Java v11 -->

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在运行时可用,请指定以下命令行选项:

——添加模块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中被删除了。


适当的长期解决方案:(JDK 9及以上版本)

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

在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及以上版本)

将以下依赖项添加到构建中。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"
}

正如官方文件所述:

升级时,您可能会面临以下问题: java.lang.NoClassDefFoundError: javax / xml /绑定/ JAXBException Hibernate通常需要缺省情况下不再提供的JAXB。你可以 在Java9中添加java.xml.bind模块来恢复此功能 或Java10(即使该模块已弃用)。 从Java11开始,该模块不可用,所以您唯一的选择是 添加JAXB RI(您可以在Java9中这样做,以代替添加 java.xml.bind模块:


Maven

<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
</dependency>

Gradle (build.gradle.kts):

implementation("org.glassfish.jaxb:jaxb-runtime")

Gradle build.gradle)

implementation 'org.glassfish.jaxb:jaxb-runtime'

如果你想指定一个特定的版本,看看这里: https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime