【问题标题】:Java 11: Implementation of JAXB-API has not been found on module path or classpathJava 11:在模块路径或类路径上找不到 JAXB-API 的实现
【发布时间】:2021-09-23 03:23:32
【问题描述】:

我有一个小项目,当我让它运行时确实会引发异常。

问题出在这里(TestObject.java):

final JAXBContext jaxbContext = JAXBContext.newInstance(...);

我真的不明白为什么这会引发异常。我还创建了一个像魅力一样工作的测试(TestTest.java)。请原谅我的名字,但这只是一个小型测试应用程序,可以让它与 java 11 一起使用。

我关注了这个:javax.xml.bind.JAXBException Implementation of JAXB-API has not been found on module path or classpath 并添加了

compile('javax.xml.bind:jaxb-api:2.3.0')
compile('javax.activation:activation:1.1')
compile('org.glassfish.jaxb:jaxb-runtime:2.3.0')

到我的 build.gradle 但它抱怨说

Error:java: module not found: java.activation

不见了。由于这也已从 Java 11 中删除,因此我添加了:

compile 'com.sun.activation:javax.activation:1.2.0'

但它会引发很多错误:

Error:java: the unnamed module reads package com.sun.xml.bind from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.util from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.marshaller from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.api from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.v2 from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.v2.util from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.v2.model.impl from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.v2.model.annotation from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.v2.runtime from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.v2.runtime.unmarshaller from both jaxb.runtime and jaxb.core
Error:java: the unnamed module reads package com.sun.xml.bind.unmarshaller from both jaxb.runtime and jaxb.core
Error:java: module jaxb.runtime reads package com.sun.xml.bind from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.util from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.marshaller from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.api from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.v2 from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.v2.util from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.v2.model.impl from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.v2.model.annotation from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.v2.runtime from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.v2.runtime.unmarshaller from both jaxb.core and jaxb.runtime
Error:java: module jaxb.runtime reads package com.sun.xml.bind.unmarshaller from both jaxb.core and jaxb.runtime
Error:java: module jaxb.core reads package com.sun.xml.bind from both jaxb.core and jaxb.runtime

让我感到困惑的是:测试有效。所以似乎在 junit5 环境中有某种 jaxb 实现。 我还发现了有关如何将 java 8 应用程序迁移到 java 9 模块的一些其他信息,我在其中找到了这个:

compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.4.0-b180830.0359'
compile group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.4.0-b180830.0438'
compile group: 'org.glassfish.jaxb', name: 'jaxb-xjc', version: '2.4.0-b180830.0438'

但这也行不通。如果有人可以帮助我运行它,我会非常高兴。 我在 Fedora 29 64 位上使用 java-openjdk-11.0.1.13-11.rolling.fc29.x86_64。

ps.:我想将所有这些都写到主题为“javax.xml.bind.JAXBException...”的帖子的评论中,但我不被允许这样做。所以我创建了这个新帖子。

编辑:该示例应用程序中引发的异常是:

Exception in thread "main" java.lang.RuntimeException: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
 - with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory]
    at test/com.example.TestObject.doSomething(TestObject.java:21)
    at test/com.example.TestObject.main(TestObject.java:12)
Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
 - with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory]
    at java.xml.bind/javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:269)
    at java.xml.bind/javax.xml.bind.ContextFinder.find(ContextFinder.java:412)
    at java.xml.bind/javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
    at java.xml.bind/javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
    at test/com.example.TestObject.doSomething(TestObject.java:17)
    ... 1 more
Caused by: java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at java.xml.bind/javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122)
    at java.xml.bind/javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155)
    at java.xml.bind/javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:267)
    ... 5 more

【问题讨论】:

  • 在 java 11 中,这些库已从 JDK 中删除。您需要将库添加为依赖项。检查这个:blog.codefx.org/java/java-11-migration-guide/…
  • @NeplatnyUdaj 我已经添加了这些依赖项。否则,应用程序将无法编译。出于这个原因,我添加了 org.glassfish.jaxb 人工制品。如果这些是错误的,请告诉我使用哪一个。
  • 我按照上面第一条评论中的说明进行操作。将 jaxb-core 和 jaxb-impl 添加到我的 lib 目录解决了我的问题。

标签: java java-11 java-platform-module-system


【解决方案1】:

解决方案非常简单。首先,使用 jaxb 2.3.1。 beta-stuff 仅用于测试。 真正的问题是module-info.java。 jaxb 需要有 2 个条目:

requires java.xml.bind;
requires com.sun.xml.bind;

第一个要求定义实现,第二个要求定义 API。

唯一需要的两个依赖项是:

compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
compile group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.1'

【讨论】:

  • 将 org.glassfish.jaxb 定义为运行时依赖就足够了
【解决方案2】:

我发现有一个 ClassLoader 错误,尤其是当您通过 ForkJoinPool 或类似方法在线程内工作时。该错误在此处列出:https://github.com/eclipse-ee4j/jaxb-api/issues/78

静态创建 JaxbContext 将强制使用正确的 ClassLoader,但这很麻烦。 :/

【讨论】:

  • 对我来说这也是问题,它只在多线程中运行 JaxbContext 时出现。我建议的解决方案是将 JaxbContext 定义为单独的依赖项或 Spring bean,并且作为奖励,Oracle 建议无论如何只创建一次 JaxbContext:javaee.github.io/jaxb-v2/doc/user-guide/…
【解决方案3】:

为了完成其他答案:

JAXB 使用绑定到当前线程的类加载器来查找 JAXB ContextFactory 类(Thread.currentThread().getContextClassLoader()),并且在某些情况下(例如使用码头线程),绑定的类加载器是 PlatformClassLoader,它具有特殊性不知道类路径,与AppClassLoader相反。

要解决这个问题,JAXB API 和运行时必须在 module-path 中(PlatformClassLoader 可以访问)。

例如应用程序被打包有以下依赖项:

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

所以应用程序应该以jaxb-runtime 及其模块依赖项启动,如下所示:

### Set the module-path
MODULEPATH="./lib/jaxb-runtime-2.3.3.jar"
MODULEPATH="${MODULEPATH}:./lib/jakarta.activation-1.2.2.jar"
MODULEPATH="${MODULEPATH}:./lib/jakarta.xml.bind-api-2.3.3.jar"
MODULEPATH="${MODULEPATH}:./lib/txw2-2.3.3.jar"
MODULEPATH="${MODULEPATH}:./lib/istack-commons-runtime-3.0.11.jar"

java --module-path ${MODULEPATH} --add-modules ALL-MODULE-PATH [...]

注意:ALL-MODULE-PATH 可以替换为特定的模块名称

【讨论】:

  • 你能检查一下stackoverflow.com/questions/70466801/…的问题吗?正如您在提供的堆栈跟踪中看到的那样,我有 AppClassLoader,但我仍然收到 javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath
  • @PhilippeGioseffi 使用 AppClassLoader 时,您只需要将 JAXB API 和 Inplementation 放在类路径中。在您的情况下,我建议您添加来自 glassfish 的 jaxb-runtime,而不是来自 Sun 的那个(如果我记得清楚的话,它或多或少已被弃用)
  • 我使用的是 Glassfish 的那个,但我仍然遇到同样的错误。
【解决方案4】:

我相信java.lang.ClassNotFoundException 即将到来是因为多个版本无法定义定义。

解决方案:从本地 m2 存储库中删除 com.sun.xml 文件夹,并仅下载一个依赖项。

javax.xml.bind:jaxb-api:"latest-version" in pom/gradle.

【讨论】:

    【解决方案5】:

    升级到 SpringBoot 2.5 时,我收到了同样的异常。添加以下依赖项(Maven)解决了我的问题:

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

    【讨论】:

      【解决方案6】:

      从我的非模块化外部库中删除了 maven-dependency com.sun.xml.bind,并且像 the unnamed module reads package com.sun.xml.bind.util 这样的许多错误已经消失。

      【讨论】:

        【解决方案7】:

        我使用的是Moxy,即使在添加jaxb.properties 文件后也出现此错误。所以我必须确保以下几点:

        以下是dependency:

            <dependency>
              <groupId>jakarta.xml.bind</groupId>
              <artifactId>jakarta.xml.bind-api</artifactId>
              <version>3.0.1</version>
            </dependency>
        
            <dependency>
              <groupId>org.eclipse.persistence</groupId>
              <artifactId>eclipselink</artifactId>
              <version>3.0.0</version>
            </dependency>
        
        

        除了依赖关系之外,确保Moxy 在同一包中存在的compilatation 期间使用jaxb.properties 文件也很重要。因此,在pom.xml 内的dependencies 上方添加以下内容:

          <build>
            <plugins>
              <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                  <source>8</source>
                  <target>8</target>
                </configuration>
              </plugin>
            </plugins>
            <resources>
              <resource>
                <directory>src/main/java</directory>
                <excludes>
                  <exclude>**/*.java</exclude>
                </excludes>
              </resource>
            </resources>
          </build>
        

        所有东西加在一起会是这样的:

          <build>
            <plugins>
              <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                  <source>8</source>
                  <target>8</target>
                </configuration>
              </plugin>
            </plugins>
            <resources>
              <resource>
                <directory>src/main/java</directory>
                <excludes>
                  <exclude>**/*.java</exclude>
                </excludes>
              </resource>
            </resources>
          </build>
        
        <dependencies>
            <dependency>
              <groupId>jakarta.xml.bind</groupId>
              <artifactId>jakarta.xml.bind-api</artifactId>
              <version>3.0.1</version>
            </dependency>
        
            <dependency>
              <groupId>org.eclipse.persistence</groupId>
              <artifactId>eclipselink</artifactId>
              <version>3.0.0</version>
            </dependency>
        
        </dependencies>
        

        【讨论】:

          【解决方案8】:

          对于OAuth2与Spring 2.5.3的实现,以及OAuth2的依赖

          <dependency>
              <groupId>org.springframework.security.oauth</groupId>
              <artifactId>spring-security-oauth2</artifactId>
              <version>2.5.1.RELEASE</version>
          </dependency>
          

          使用以下依赖将消除错误 Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:822) ~[na:na] at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:182) ~[na:na]

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-08-29
            • 2018-08-24
            • 1970-01-01
            • 2019-10-30
            • 2013-12-17
            • 2018-11-06
            相关资源
            最近更新 更多