简体   繁体   中英

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

I have a little project which does throw an exception when i let it run.

The problem is here (TestObject.java):

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

I really do not understand why this throws the exception. I also created a test which works like a charm (TestTest.java). Please forgive me the names, but this is just a small test application to get this working with java 11.

I followed this: javax.xml.bind.JAXBException Implementation of JAXB-API 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')

to my build.gradle but then it complains that

Error:java: module not found: java.activation

is missing. As this is also removed from Java 11 i added:

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

but then it throws a lot of errors:

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

What is so confusing to me: the test works. So it seems like there is some kind of jaxb-implementation in the junit5 environment. I also found some other information in how to migrate a java 8 app to java 9 modules, where i found this:

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'

But this is also not working. I would be very happy if someone can help me to get that running. I use java-openjdk-11.0.1.13-11.rolling.fc29.x86_64 on Fedora 29, 64 bit.

ps.: i wanted to write all that into the comment of the post with topic "javax.xml.bind.JAXBException..." but i was not allowed to do so. So i created this new post.

edit: the exception which is thrown in that sample application is this:

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

The solution is very easy. First, use jaxb 2.3.1. The beta-stuff is for testing only. The real problem was the module-info.java. It is required to have 2 entries for jaxb:

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

The first requires defines the implementation, the second the API.

The only two dependencies required are:

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

In order to complete the other answers:

JAXB uses the classloader bound to current thread to find the JAXB ContextFactory class ( Thread.currentThread().getContextClassLoader() ), and in some cases (for instance with jetty threads), the bound classloader is a PlatformClassLoader , which has the particularity to not being aware of class-path , contrary to the AppClassLoader .

To solve this issue JAXB API and runtime must be in the module-path (which is accessible by PlatformClassLoader ).

For instance app is packaged with following dependencies:

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

So the application should be started with jaxb-runtime and its module dependencies, as below:

### 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 [...]

Note: ALL-MODULE-PATH could be replaced by specific module names

I believe java.lang.ClassNotFoundException is coming because of multiple versions not able to define defination.

Solution: delete com.sun.xml folder from your local m2 repository, and download only one dependency.

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

I found there to be a ClassLoader bug, especially if you're doing work within a thread via a ForkJoinPool or similar. The bug is listed here: https://github.com/eclipse-ee4j/jaxb-api/issues/78

Creating the JaxbContext statically will force the correct ClassLoader to be used, but it's hacky. :/

从我的外部库中删除了 maven-dependency com.sun.xml.bind ,它不是模块化的,很多错误,比如the unnamed module reads package com.sun.xml.bind.util已经消失了。

I was using the Moxy and I was getting this error even after adding the jaxb.properties file. So I had to make sure followings:

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

Along with dependency its important to make sure that Moxy uses the jaxb.properties file during the compilatation which is present within the same package. So add the following above the dependencies within the 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>

Evertything together would be something like this:

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

When upgrading to SpringBoot 2.5, I received the same exception. Adding the following dependency (Maven) solved my issues:

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

For the implementation of OAuth2 with Spring 2.5.3, along with the dependency of OAuth2

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

use of following dependency will remove the error 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>

I was facing the same issue for Java 11 - Gradle and below dependencies resolved it

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM