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

9

21

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
Unbending answered 11/2, 2019 at 13:53 Comment(4)
In java 11, these libraries were removed from JDK. You need to add the libs as dependencies. Check this: blog.codefx.org/java/java-11-migration-guide/…Amplify
@Amplify i already added those dependencies. Otherwise, the application would not compile. For that reason i added org.glassfish.jaxb artefacts. If these are wrong, please tell me which one to use.Unbending
I followed the instructions in the first comment above. Adding jaxb-core and jaxb-impl to my lib directory solved my problems.Tectonics
Does this answer your question? Replacements for deprecated JPMS modules with Java EE APIsFlamsteed
U
26

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'
Unbending answered 13/2, 2019 at 12:6 Comment(2)
it's enough to define org.glassfish.jaxb as a runtime dependencyMucilage
+1 for the point about using the 2.3.x version. I've been trying to get it to work with 3.x and it fails miserably!Argillite
B
11

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>
Beard answered 6/7, 2021 at 8:20 Comment(0)
I
9

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

Ignace answered 5/2, 2021 at 17:41 Comment(4)
Could you please check the question #70467301? I have AppClassLoader as you can see in the stacktrace provided but I'sm still getting javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.Hydromel
@PhilippeGioseffi when using AppClassLoader you just need the JAXB API and Inplementation to be in the classpath. In your case, I suggest you to add the jaxb-runtime from glassfish, instead of the one from Sun (which is more or less deprecated if I remember well)Ignace
I was using that one from Glassfish, but I was still getting the same error.Hydromel
I suggest upgrading both dependencies to 3.0.1Easy
G
4

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. :/

Gally answered 6/5, 2021 at 16:59 Comment(2)
For me this was also the issue, it only appeared when running JaxbContext in multiple threads. Solution that I would suggest is to define JaxbContext as a separate dependency or Spring bean and also as a bonus, it is recommended by Oracle to only create JaxbContext once anyway: javaee.github.io/jaxb-v2/doc/user-guide/…Pellegrino
If using Spring, I ended up creating a JaxbContextFactory component that I autowired around to the places I need access to the contexts. The constructor of the factory stored off the Thread.currentThread().getContextClassLoader() into a class variable, and uses a ConcurrentHashMap for caching new instances. New requests will lazy load a new context against that stored off class loader and cache the result in a map for subsequent calls. That was as close as I could get to a clean-ish solution for now.Gally
R
1

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

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.

Rafaelle answered 18/2, 2020 at 6:41 Comment(0)
B
0

Removed maven-dependency com.sun.xml.bind from my external library which is not modular and a lot of errors like the unnamed module reads package com.sun.xml.bind.util has gone.

Botulinus answered 14/9, 2019 at 22:59 Comment(0)
T
0

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>
Talc answered 7/6, 2021 at 11:16 Comment(0)
U
0

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>
Unni answered 2/8, 2021 at 13:40 Comment(0)
M
0

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
Marcenemarcescent answered 12/12, 2022 at 20:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.