Java 11:在模块路径或类路径上找不到JAXB-API的实现

时间:2019-02-11 13:53:27

标签: java java-11 jigsaw

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

问题在这里(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'

但这也不起作用。如果有人可以帮助我实现目标,我将非常高兴。 我在64位Fedora 29上使用java-openjdk-11.0.1.13-11.rolling.fc29.x86_64。

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

edit:该示例应用程序中抛出的异常是:

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

8 个答案:

答案 0 :(得分:2)

解决方案非常简单。首先,使用jaxb 2.3.1。 Beta版资料仅供测试。 真正的问题是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'

答案 1 :(得分:1)

我相信java.lang.ClassNotFoundException的出现是因为有多个版本无法定义定义。

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

javax.xml.bind:jaxb-api:pom / gradle中的“最新版本”。

答案 2 :(得分:1)

为了完成其他答案:

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

要解决此问题,JAXB API 和运行时必须位于 module-path(可通过 AppClassLoader 访问)中。

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

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
<块引用>

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

答案 3 :(得分:1)

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

静态创建 JaxbContext 将强制使用正确的 ClassLoader,但它很笨拙。 :/

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

从我的非模块化外部库中删除了maven依赖项com.sun.xml.bind,而the unnamed module reads package com.sun.xml.bind.util之类的许多错误都消失了。

答案 6 :(得分:0)

我使用的是 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>

除了依赖项外,重要的是要确保 Moxyjaxb.properties 期间使用 compilatation 文件,该文件存在于同一个包中。因此,在 dependencies 中的 pom.xml 上方添加以下内容:

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

答案 7 :(得分:0)

用于使用 Spring 2.5.3 实现 OAuth2,以及 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>