簡體   English   中英

Java 11:在模塊路徑或類路徑上未找到 JAXB-API 的實現

[英]Java 11: Implementation of JAXB-API has not been found on module path or classpath

我有一個小項目,當我讓它運行時確實會拋出異常。

問題就在這里(TestObject.java):

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

我真的不明白為什么會拋出異常。 我還創建了一個非常有效的測試 (TestTest.java)。 請原諒我的名字,但這只是一個小的測試應用程序,可以使它與 java 11 一起工作。

我遵循了這個: javax.xml.bind.JAXBException JAXB-API Implementation has not been found on module path or classpath and added

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 ...”的帖子的評論中,但我不允許這樣做。 所以我創建了這個新帖子。

編輯:在該示例應用程序中拋出的異常是這樣的:

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

解決方案非常簡單。 首先,使用 jaxb 2.3.1。 測試版僅用於測試。 真正的問題是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'

為了完成其他答案:

JAXB 使用綁定到當前線程的類加載器來查找 JAXB ContextFactory類( Thread.currentThread().getContextClassLoader() ),並且在某些情況下(例如使用 jetty 線程),綁定的類加載器是一個PlatformClassLoader ,它具有特殊性不知道 class-path ,與AppClassLoader相反。

要解決此問題,JAXB API 和運行時必須位於模塊路徑中(可通過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 可以替換為特定的模塊名稱

我相信java.lang.ClassNotFoundException即將到來,因為多個版本無法定義定義。

解決方案:從本地m2存儲庫中刪除com.sun.xml文件夾,只下載一個依賴項。

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

我發現有一個 ClassLoader 錯誤,尤其是當您通過 ForkJoinPool 或類似方法在線程內工作時。 該錯誤在此處列出: https : //github.com/eclipse-ee4j/jaxb-api/issues/78

靜態創建 JaxbContext 將強制使用正確的 ClassLoader,但它很笨拙。 :/

從我的外部庫中刪除了 maven-dependency com.sun.xml.bind ,它不是模塊化的,很多錯誤,比如the unnamed module reads package com.sun.xml.bind.util已經消失了。

我正在使用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>

除了依賴之外,確保Moxycompilatation期間使用同一個包中存在的jaxb.properties文件很重要。 因此,在pom.xmldependencies上方添加以下內容:

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

升級到 SpringBoot 2.5 時,我收到了同樣的異常。 添加以下依賴項(Maven)解決了我的問題:

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

用於使用 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]以下原因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]的錯誤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>

對於 Java 11 - Gradle 我遇到了同樣的問題,下面的依賴項解決了它

compileOnly 'javax.xml.bind:jaxb-api:2.3.1'
compileOnly 'org.glassfish.jaxb:jaxb-runtime:2.3.1' code here

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM