如何解决 java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

Posted

技术标签:

【中文标题】如何解决 java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException【英文标题】:How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException 【发布时间】:2017-09-20 07:53:00 【问题描述】:

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

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

【问题讨论】:

附加部分in this answer与这些API的迁移有关。 使用 Java 8 构建将使您的代码可以编译,但是当您尝试在 Java 9+ 上运行该编译代码时,它将失败,因为 JAX-B 不存在。 对于Java 11,本文的解决方案是最新的:crunchify.com/java-11-and-javax-xml-bind-jaxbcontext 见wiki.bitplan.com/index.php/Java8 看看我是怎么修她的 :- Answer 【参考方案1】:

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 一起使用!!!

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

    您可以使用JDK_JAVA_OPTIONS 环境变量设置任何仅限Java 9+ 的选项。此环境变量是 automatically read,由 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 中是 scheduled for removal。因此--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 Reference Implementation page。

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

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

将以下依赖项添加到您的 build.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 EE API 模块被标记为已弃用,这是否意味着 Java 10 中的 JAXB 可能在 Java 10 的运行时不再可用?这似乎是倒退了一步。我们将不得不回到包含 JAXB 作为依赖项的 6 之前的做法。 不推荐使用 --add-modules java.se.ee 或 --add-modules ALL-SYSTEM 作为解决方法,根据迁移指南docs.oracle.com/javase/9/migrate 下的模块与 Java EE 共享不默认解决 --> 第 1 点 随着 Java 10 的正式发布,我们可以确认 add-modules 方法仍然有效。根据JEP-320,javax.xml.bind 和其他 JavaEE 类计划在 Java 11 中删除。 现在 Java 11 发布了,java.se.ee 模块已被移除,所以--add-modules 解决方案不再起作用。请改用推荐的解决方案:将 JAXB 添加为单独的依赖项。 我已经添加了这些依赖项,但它仍然给我同样的错误。任何想法为什么?【参考方案2】:

在我的情况下(spring boot fat jar),我只需将以下内容添加到 pom.xml。

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

【讨论】:

仅供参考github.com/spring-projects/spring-boot/wiki/… testCompile('javax.xml.bind:jaxb-api') 这样添加 gradle 依赖项对我有用。 就像@pamcevoy 提到的,在使用Spring Boot 时不需要指定jaxb-api 的版本。 Boot 会自动管理版本。 我建议在这种情况下使用&lt;scope&gt;runtime&lt;/scope&gt; @Tuno 的链接对我不起作用,固定链接是:github.com/spring-projects/spring-boot/wiki/…【参考方案3】:

在最近的 JDK 9.0.1 中,这些解决方案都不适合我。

我发现此依赖项列表足以正常运行,因此您不需要显式指定--add-module(尽管它已在这些依赖项的 pom 中指定)。您唯一需要的是指定此依赖项列表:

<dependencies>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>javax.activation</groupId>
        <artifactId>activation</artifactId>
        <version>1.1.1</version>
    </dependency>
</dependencies>

【讨论】:

对于 JDK 8,从上面删除 jaxb-core 和 jaxb-impl。 @Anil 这是一个 Maven 配置的pom.xml 文件。如果你不知道那是什么,那么最好从头开始 发生了非法反射访问操作警告:com.sun.xml.bind.v2.runtime.reflect.opt.Injector (file:/C:/Users/eis/. m2/repository/com/sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0.jar) 到方法 java.lang.ClassLoader.defineClass(java.lang.String,byte[], int,int) 警告:请考虑将此报告给 com.sun.xml.bind.v2.runtime.reflect.opt.Injector 的维护者 警告:使用 --illegal-access=warn 启用对进一步非法反射访问操作的警告警告:所有非法访问操作将在未来版本中被拒绝 这在 JDK 9.0.4 上对我有用(我通过 Maven 3.5.3 的 Maven 插件调用 JAXB 相关代码)。虽然我会使用 &lt;dependency&gt; &lt;groupId&gt;javax.activation&lt;/groupId&gt; &lt;artifactId&gt;javax.activation-api&lt;/artifactId&gt; &lt;version&gt;1.2.0&lt;/version&gt; &lt;/dependency&gt; 作为最后一个依赖项。 太棒了。我有一种情况,由于某种原因,spring boot 应用程序将在 intellij CE 中运行,但在 mac 上不运行 eclipse,在 eclipse 中运行,但在 win10 上不运行 intellij CE。能够在两个平台上的一个 IDE 中工作是一项优势。【参考方案4】:

适用于所有 JDK 的干净解决方案 >= 9

您需要在构建中添加两个依赖项

jaxb-api jaxb 实现

作为一个实现,我选择使用 glassfish 的参考实现来摆脱旧的 com.sun 类/库。 因此,我在我的 Maven 构建中添加了

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

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

请注意,从 2.3.1 版开始,您不再需要添加 javax.activation。 (见https://github.com/eclipse-ee4j/jaxb-ri/issues/1222)

【讨论】:

真的需要 javax.xml.bind 模块吗?我在 JDK 11 中的代码没有它也可以工作。 @k.liakos 我不确定。 jaxb-runtime jar 和 api-jar 不共享相同的类/包。我想这取决于你的代码。如果您的代码不使用包“javax.xml.bind”中的类,那么您可能不需要它。该线程的主题是找不到'javax/xml/bind/JAXBException';此类仅在 jaxb-api 中。 与 java 12 中的多模块项目完美配合。【参考方案5】:

这对我有用:

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>eclipselink</artifactId>
    <version>2.7.0</version>
</dependency>

更新

正如@Jasper 建议的那样,为了避免依赖整个 EclipseLink 库,您也可以只依赖 EclipseLink MOXy:

Maven

<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>org.eclipse.persistence.moxy</artifactId>
    <version>2.7.3</version>
</dependency>

Gradle

compile group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.moxy', version: '2.7.3'

作为我的 Java 8 应用程序的依赖项,它生成一个 *.jar,它可以由 JRE 8 或 JRE 9 运行而无需额外的参数。

此外,这需要在使用 JAXB API 之前在某处执行:

System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");

到目前为止效果很好,作为一种解决方法。虽然看起来不是一个完美的解决方案......

【讨论】:

添加 org.eclipse.persistence:eclipselink 只是为了获取 JAXB API 是一个非常重的依赖项,除非您已经在使用 eclipselink? 是的,它很重(~9mb),是的,我已经在使用它了。我已经提到,对于那些可能需要临时使用 8 和 9 JRE 来处理同一个 jar/war 而不提供命令行参数的人来说,这只是一种替代解决方法。 为了 JDK 8 和 9 之间的互操作,我建议使用 -XX:+IgnoreUnrecognizedVMOptions 命令行选项(更新了我的答案详细信息) System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");不适合我 为了避免依赖整个EclipseLink库,你也可以只依赖EclipseLink MOXy:groupId org.eclipse.persistence, artifactId org.eclipse.persistence.moxy【参考方案6】:

这是因为 java 版本,如果您使用 jdk 9 或更高版本,只需将其添加到您的 pom 中

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

【讨论】:

我一直在使用 Spring Boot 指南遇到这个问题......非常感谢。 @Cesar Rodriguez T,我用一个大摇大摆的例子试过这个,编译成功,但运行出错。我使用了包含更多依赖项并且有效的选定答案。 在项目的 pom.xml 文件中【参考方案7】:

为了解决这个问题,我在我的项目中导入了一些 JAR 文件:

javax.activation-1.2.0.jar

http://search.maven.org/remotecontent?filepath=com/sun/activation/javax.activation/1.2.0/javax.activation-1.2.0.jar

jaxb-api-2.3.0.jar

http://search.maven.org/remotecontent?filepath=javax/xml/bind/jaxb-api/2.3.0/jaxb-api-2.3.0.jar

jaxb-core-2.3.0.jar

http://search.maven.org/remotecontent?filepath=com/sun/xml/bind/jaxb-core/2.3.0/jaxb-core-2.3.0.jar

jaxb-impl-2.3.0.jar

http://search.maven.org/remotecontent?filepath=com/sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0.jar

    下载以上文件并复制到项目中的libs文件夹中 在 Java Build Path 中添加导入的 JAR 文件

【讨论】:

请注意,com.sun.xml.bind 工件是旧的,仅用于向后兼容。如其他一些答案中所述,您应该改用等效的 org.glassfish.jaxb 工件。 这对我不起作用。它抛出一个错误,并说它找不到特定的类。 在部署 Grails 3.4.10 应用程序时,将它们放在 Mint 19.2(Ubuntu 18.04 基础)下的 tomcat9/lib 文件夹中为我工作。 没有用,而是引发了更多错误,需要包含其他几个 jar。我的是 jdk8【参考方案8】:

在编译时以及运行时,添加开关--add-modules java.xml.bind

javac --add-modules java.xml.bind <java file name>

java --add-modules java.xml.bind <class file>

JDK 9 模块的良好介绍也可以在以下位置找到: https://www.youtube.com/watch?v=KZfbRuvv5qc

【讨论】:

【参考方案9】:

2019 年 4 月更新

JAXB 版本的 Changelong 位于 https://javaee.github.io/jaxb-v2/doc/user-guide/ch02.html

摘录:

    4.1. Changes between 2.3.0.1 and 2.4.0

         JAXB RI is now JPMS modularized:

            All modules have native module descriptor.

            Removed jaxb-core module, which caused split package issue on JPMS.

            RI binary bundle now has single jar per dependency instead of shaded fat jars.

            Removed runtime class weaving optimization.

    4.2. Changes between 2.3.0 and 2.3.0.1

          Removed legacy technology dependencies:

            com.sun.xml.bind:jaxb1-impl

            net.java.dev.msv:msv-core

            net.java.dev.msv:xsdlib

            com.sun.xml.bind.jaxb:isorelax

    4.3. Changes between 2.2.11 and 2.3.0

          Adopt Java SE 9:

            JAXB api can now be loaded as a module.

            JAXB RI is able to run on Java SE 9 from the classpath.

            Addes support for java.util.ServiceLoader mechanism.

            Security fixes

权威链接在https://github.com/eclipse-ee4j/jaxb-ri#maven-artifacts

JAXB 工件的 Maven 坐标

jakarta.xml.bind:jakarta.xml.bind-api:JAXB 的 API 类。必需的 针对 JAXB 进行编译。

org.glassfish.jaxb:jaxb-runtime:JAXB 的实现,使用的运行时 用于将 java 对象序列化和反序列化到/从 xml。

JAXB fat-jar 包:

com.sun.xml.bind:jaxb-impl:JAXB 运行时胖 罐子。

相比之下 对于 org.glassfish.jaxb 工件,这些 jar 具有所有依赖项 类包括在内。这些工件不包含 JPMS 模块 描述符。 在 Maven 项目中,org.glassfish.jaxb 工件是 应该被使用。

org.glassfish.jaxb:jaxb-runtime:jar:2.3.2 引入:

[INFO] +- org.glassfish.jaxb:jaxb-runtime:jar:2.3.2:compile
[INFO] |  +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.2:compile
[INFO] |  +- org.glassfish.jaxb:txw2:jar:2.3.2:compile
[INFO] |  +- com.sun.istack:istack-commons-runtime:jar:3.0.8:compile
[INFO] |  +- org.jvnet.staxex:stax-ex:jar:1.8.1:compile
[INFO] |  +- com.sun.xml.fastinfoset:FastInfoset:jar:1.2.16:compile
[INFO] |  \- jakarta.activation:jakarta.activation-api:jar:1.2.1:compile

原答案

按照 Maven 中的Which artifacts should I use for JAXB RI in my Maven project?,您可以使用如下配置文件:

<profile>
    <id>java-9</id>
    <activation>
        <jdk>9</jdk>
    </activation>
    <dependencies>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
    </dependencies>
</profile> 

依赖树显示:

[INFO] +- org.glassfish.jaxb:jaxb-runtime:jar:2.3.0:compile
[INFO] |  +- org.glassfish.jaxb:jaxb-core:jar:2.3.0:compile
[INFO] |  |  +- javax.xml.bind:jaxb-api:jar:2.3.0:compile
[INFO] |  |  +- org.glassfish.jaxb:txw2:jar:2.3.0:compile
[INFO] |  |  \- com.sun.istack:istack-commons-runtime:jar:3.0.5:compile
[INFO] |  +- org.jvnet.staxex:stax-ex:jar:1.7.8:compile
[INFO] |  \- com.sun.xml.fastinfoset:FastInfoset:jar:1.2.13:compile
[INFO] \- javax.activation:activation:jar:1.1.1:compile

要在 Eclipse 中使用它,请说 Oxygen.3a Release (4.7.3a) 或更高版本,Ctrl-Alt-P,或右键单击项目 Maven,然后选择配置文件。

【讨论】:

感谢您展示了我在其他地方看到的对 javax.xml.bind > jaxb-api 的依赖实际上是多余的。 glassfish 的依赖拉动了它。我刚试过,确实有效。【参考方案10】:

这对我有用。仅添加 jaxb-api 是不够的。

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>$jaxb-api.version</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>$jaxb-api.version</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>$jaxb-api.version</version>
        </dependency>

【讨论】:

jaxb-api.version 设置为什么? @MiguelMunoz 我用的是 2.2.7 请注意,com.sun.xml.bind 工件是旧的,仅用于向后兼容。如其他一些答案中所述,您应该改用等效的 org.glassfish.jaxb 工件。【参考方案11】:

转到您的 Build.gradle 并为 Java 9 或 Java 10 添加以下依赖项。

sourceCompatibility = 10 // You can also decrease your souce compatibility to 1.8 

//java 9+ does not have Jax B Dependents

    compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.0'
    compile group: 'com.sun.xml.bind', name: 'jaxb-core', version: '2.3.0'
    compile group: 'com.sun.xml.bind', name: 'jaxb-impl', version: '2.3.0'
    compile group: 'javax.activation', name: 'activation', version: '1.1.1'

【讨论】:

【参考方案12】:

您可以使用--add-modules=java.xml.bind JVM 选项将xml绑定模块添加到JVM运行时环境。

例如:java --add-modules=java.xml.bind XmlTestClass

【讨论】:

【参考方案13】:

我还使用 Java 11

偶然发现了 ClassNotFoundException:javax.xml.bind.DatatypeConverter
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

我尝试了围绕添加 javax.xml.bind:jaxb-api 或 spring boot jakarta.xml.bind-api 的所有这些东西。我在 jjwt 版本 0.10.0 中找到了修复提示 .. 但最重要的是, jjwt 包现已拆分!

因此,请检查此参考:https://github.com/jwtk/jjwt/issues/510

简单地说,如果你使用

Java11 和 jjwt 0.9.x 和 您面临 ClassNotFoundException:javax.xml.bind.DatatypeConverter 问题,

jjwt 版本 0.11.x,但使用拆分包:https://github.com/jwtk/jjwt#install

你不会找到更高版本的 jjwt 依赖,因为它们会拆分包。

干杯。

【讨论】:

使用 io.jsonwebtoken 版本 0.9.1 中的 jjwt 和 java 16 也会导致同样的错误。根本原因与 java 11 相同。使用版本 0.10.7 的 jjwt-api 和 jjwt-impl(来自 io.jsonwebtoken)解决了这里的问题。【参考方案14】:

使用 JDK 9+ 时需要添加 JAX-B 依赖项。对于 android Studio 用户,您需要将其添加到您的 build.gradledependencies 块中:

// Add missing dependencies for JDK 9+
if (JavaVersion.current().ordinal() >= JavaVersion.VERSION_1_9.ordinal()) 
    // If you're using @AutoValue or any libs that requires javax.annotation (like Dagger)
    compileOnly 'com.github.pengrad:jdk9-deps:1.0'
    compileOnly 'javax.annotation:javax.annotation-api:1.3.2'

    // If you're using Kotlin
    kapt "com.sun.xml.bind:jaxb-core:2.3.0.1"
    kapt "javax.xml.bind:jaxb-api:2.3.1"
    kapt "com.sun.xml.bind:jaxb-impl:2.3.2"

    // If you're using Java
    annotationProcessor "com.sun.xml.bind:jaxb-core:2.3.0.1"
    annotationProcessor "javax.xml.bind:jaxb-api:2.3.1"

    testAnnotationProcessor "com.sun.xml.bind:jaxb-core:2.3.0.1"
    testAnnotationProcessor "javax.xml.bind:jaxb-api:2.3.1"

【讨论】:

我已经修改了你的答案以使用单元测试。 这是唯一对我有用的解决方案! 这是最好的解决方案!!!【参考方案15】:

对于 Java Web Start Execution,我们可以像这样使用 Andy Guibert 的建议:

<j2se version="1.6+" 
      java-vm-args="-XX:+IgnoreUnrecognizedVMOptions --add-modules=java.se.ee"/>

注意 --add-modules 中额外的“=”。请参阅this OpenJDK Ticket 或Java Platform, Standard Edition Oracle JDK 9 Migration Guide 的“了解运行时访问警告”中的最后一条注释。

【讨论】:

【参考方案16】:

在 pom.xml 中添加 javax.xml.bind 依赖

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

【讨论】:

【参考方案17】:

这个问题的根本原因是 Gradle Daemon 使用 JDK11,或者您将 JAVA_HOME 设置为 JDK11,或者您在使用 JDK11 运行的共享守护程序中运行 Gradle Task。

对于安卓:

    检查您的项目结构设置,您可以从那里将 JDK 更改为 JDK8。

    您还可以设置一个 JAVA_HOME 并指向 java8 主页。

【讨论】:

【参考方案18】:

我在 Debian 10 中处理 Java 项目 时遇到了这个问题。

每次我启动应用程序时,它都会在日志文件中抛出错误:

java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

我是这样解决的

当类路径中缺少 JAXB 库(用于 XML 绑定的 Java 架构)时,通常会导致该问题。 JAXB 包含在 Java SE 10 或更早版本中,但在 Java 11 或更高版本中已从 Java SE 中删除——在 Jakarta EE 项目下移至 Java EE。

所以,我使用以下方法检查了我的 Java 版本:

java --version

它给了我这个输出

openjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+10-post-Debian-1deb10u1)
OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Debian-1deb10u1, mixed mode, sharing)

所以我遇到了 JAXBException 错误,因为我使用的是 Java 11,它没有 JAXB 库(Java Architecture for XML Binding)在类路径中丢失. JAXB 包含在其中。

为了解决这个问题,我必须将 JAXB API 库添加到我的 tomcat 安装的 lib (/opt/tomcat/lib) 目录中:

sudo wget https://repo1.maven.org/maven2/javax/xml/bind/jaxb-api/2.4.0-b180830.0359/jaxb-api-2.4.0-b180830.0359.jar

然后我把它从jaxb-api-2.4.0-b180830.0359.jar重命名为jaxb-api.jar

sudo mv jaxb-api-2.4.0-b180830.0359.jar jaxb-api.jar

注意:确保您更改了允许tomcat访问文件的权限,并将所有权更改为tomcat

sudo chown -R tomcat:tomcat /opt/tomcat
sudo chmod -R 777 /opt/tomcat/

然后我重启了tomcat服务器:

sudo systemctl restart tomcat

资源:[Solved] java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

就是这样。

【讨论】:

【参考方案19】:

这解决了我在 Java 12 上运行 Apache Camel 2.24.1 的依赖项问题:

    <dependency>
        <groupId>javax.activation</groupId>
        <artifactId>activation</artifactId>
        <version>1.1.1</version>
    </dependency>

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

    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-core</artifactId>
        <version>2.3.0.1</version>
    </dependency>

    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.3.0.1</version>
    </dependency>

【讨论】:

在我的情况下,我需要在 pom 文件中添加 tomcat 依赖项【参考方案20】:

由于 JavaEE 现在由 https://jakarta.ee/ 管理,因此 2.3.2 的新 Maven 坐标为:

https://eclipse-ee4j.github.io/jaxb-ri/#maven-artifacts

第一个发布的 jaxb.version 是 2.3.2。

<properties>
  <jaxb.version>2.3.2</jaxb.version>
</properties>

<dependency>
  <groupId>jakarta.xml.bind</groupId>
  <artifactId>jakarta.xml.bind-api</artifactId>
  <version>$jaxb.version</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>$jaxb.version</version>
</dependency>

【讨论】:

【参考方案21】:

我关注了这个 URL,下面的设置对我很有帮助。我在 Macbook Pro 中使用 Java 10 和 STS IDE。它就像一个魅力。

   <dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.0</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>javax.activation-api</artifactId>
    <version>1.2.0</version>
</dependency>

【讨论】:

【参考方案22】:

我在 Java 11 上使用 Spring Boot 2.0.5.RELEASE 遇到了同样的问题。

单独添加javax.xml.bind:jaxb-api:2.3.0 并不能解决问题。我还必须将 Spring Boot 更新到最新的 Milestone 2.1.0.M2,所以我认为这将在下一个正式版本中修复。

【讨论】:

这听起来与我无关。无论使用 spring boot 2,这个线程中有几个解决方案都可以工作。(我也使用 spring boot 2.0.5.RELEASE btw)。也许在 Spring 2.1.0.M2 中已经包含了一个 jaxb 运行时。 似乎使用 Spring Boot 2.1.0.RELEASE,不再需要 JAXB - github.com/spring-projects/spring-boot/releases【参考方案23】:

正如official documentation 所说:

升级时您可能会遇到以下情况:

java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

Hibernate 通常需要默认不再提供的 JAXB。你可以 添加 java.xml.bind 模块以使用 Java9 恢复此功能 或 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

【讨论】:

【参考方案24】:

添加以下依赖项对我有用。

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

【讨论】:

请注意 javax 库自 jdk 11 以来已被弃用。只需将 javax 依赖项替换为 Jakarta 库依赖项即可,请参阅下面的链接。 wiki.eclipse.org/Jakarta_EE_Maven_Coordinates【参考方案25】:

不是答案,而是附录:如果 JAVA_HOME 指向 Java 9 安装(准确地说是java version "9.0.1"),运行 groovysh (Groovy 2.4.13) 会非常失败:

java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:107)
        at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:129)
Caused by: java.lang.NoClassDefFoundError: Unable to load class groovy.xml.jaxb.JaxbGroovyMethods due to missing dependency javax/xml/bind/JAXBContext
        at org.codehaus.groovy.vmplugin.v5.Java5.configureClassNode(Java5.java:400)
        at org.codehaus.groovy.ast.ClassNode.lazyClassInit(ClassNode.java:277)
        at org.codehaus.groovy.ast.ClassNode.getMethods(ClassNode.java:397)
        ...
        ..
        .
        ..
        ...
        at org.codehaus.groovy.tools.shell.Groovysh.<init>(Groovysh.groovy:135)
        at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:232)
        at org.codehaus.groovy.tools.shell.Main.<init>(Main.groovy:66)
        at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:232)
        at org.codehaus.groovy.tools.shell.Main.main(Main.groovy:163)
... 6 more

解决办法是:

转到 github.io 上的 JAXB Project(“JAXB 在双重许可下获得许可 - CDDL 1.1 和 GPL 2.0 与类路径异常”

下载jaxb-ri-2.3.0.zip

解压缩您放置 java 基础结构文件的任何位置(在我的例子中,/usr/local/java/jaxb-ri/)。可能存在其他解决方案(可能通过 SDKMAN,我不知道)

确保 lib 子目录中的 jar 位于 CLASSPATH 上。我通过一个在 bash 启动时启动的脚本来执行此操作,称为 /etc/profile.d/java.sh,我在其中添加了(在许多其他行中)以下循环:

打包成一个函数...

function extend_qzminynshg 
   local BASE="/usr/local/java"
   for LIB in jaxb-api.jar  jaxb-core.jar  jaxb-impl.jar  jaxb-jxc.jar  jaxb-xjc.jar; do
      local FQLIB="$BASE/jaxb-ri/lib/$LIB"
      if [[ -f $FQLIB ]]; then
         export CLASSPATH=$FQLIB:$CLASSPATH
      fi
    done


extend_qzminynshg; unset extend_qzminynshg

而且它有效!

【讨论】:

我不明白反对意见。显然人们想玩弄命令行选项而不是实际获取罐子?适合自己。 Java 开发人员通常使用 Gradle 或 Maven 等构建工具来管理依赖项,而不是手动下载 jar。这可能是投反对票的原因。【参考方案26】:

您只需要 1 个依赖项:

dependencies 
    implementation ("jakarta.xml.bind:jakarta.xml.bind-api:2.3.2")

【讨论】:

【参考方案27】:

好的,我一直遇到同样的问题,但我使用的是 Java 8,并且一直收到此错误,我尝试了大多数解决方案。但事实证明,即使我将全局 Java 版本设置为 8,我的 maven 仍然指向 java 9,只要我修复它一切正常。

对于可能遇到此类问题的任何人,请查看How to fix Maven to use default Java

【讨论】:

链接失效【参考方案28】:

旧答案“通过切换到 amazoncorretto 解决了问题” 新闻回答:我使用了 corretto latest ,但类似 ​​jdk 1.8。所以无论如何我们需要手动添加依赖项

【讨论】:

JDK 11 的 Amazon Corretto 发行版不提供 javax.xml.bind 类。如果切换到 Correto 后问题解决了,那是因为你降级到了 JDK 8。 奇怪,我会检查一下,在我使用 correto 最新的 docker 中 是的,amazoncorretto:latest 目前给出的是 JDK 8,而不是 11。很多 Docker 镜像仍然基于 JDK 8,正是因为 JDK 8 之间的 API 移除导致的兼容性问题 --> 11 【参考方案29】:

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

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

【讨论】:

【参考方案30】:

对于我在 Java 11 和 gradle 中的结果,这是可行的:

plugins 
      id 'java'


dependencies 
      runtimeOnly 'javax.xml.bind:jaxb-api:2.3.1'

【讨论】:

我们把它放在哪里? 如果您使用的是 gradle,请在 build.gradle 文件中。

以上是关于如何解决 java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException的主要内容,如果未能解决你的问题,请参考以下文章

如何解决 Ajax 跨域请求不到的问题

如何解决包冲突问题

如何解决包冲突问题

如何解决ajax跨域问题

MySQL 的 10048问题,如何解决?

如何解决smartgit的冲突问题