17

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
J. Doe
  • 430
  • 2
  • 4
  • 11
  • 1
    In java 11, these libraries were removed from JDK. You need to add the libs as dependencies. Check this: https://blog.codefx.org/java/java-11-migration-guide/#Removal-Of-Java-EE-Modules – NeplatnyUdaj Feb 11 '19 at 13:59
  • @NeplatnyUdaj 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. – J. Doe Feb 11 '19 at 14:27
  • I followed the instructions in the first comment above. Adding jaxb-core and jaxb-impl to my lib directory solved my problems. – Jeremy Goodell Apr 21 '21 at 22:48
  • Does this answer your question? [Replacements for deprecated JPMS modules with Java EE APIs](https://stackoverflow.com/questions/48204141/replacements-for-deprecated-jpms-modules-with-java-ee-apis) – 9ilsdx 9rvj 0lo Jun 07 '21 at 11:52

9 Answers9

22

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'
J. Doe
  • 430
  • 2
  • 4
  • 11
9

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>
Ostecke
  • 1,469
  • 12
  • 13
8

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

Donatello
  • 3,486
  • 3
  • 32
  • 38
  • Could you please check the question https://stackoverflow.com/questions/70466801/how-to-convert-xml-to-string-with-jaxb-and-spring-boot? 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`. – Philippe Gioseffi Dec 26 '21 at 08:00
  • @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) – Donatello Dec 27 '21 at 11:19
  • I was using that one from Glassfish, but I was still getting the same error. – Philippe Gioseffi Dec 27 '21 at 13:30
  • I suggest upgrading both dependencies to 3.0.1 – Galigator Jul 11 '23 at 14:24
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. :/

Jeremy
  • 111
  • 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: https://javaee.github.io/jaxb-v2/doc/user-guide/ch03.html#other-miscellaneous-topics-performance-and-thread-safety – Bojan Trajkovski Nov 12 '21 at 09:15
  • 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. – Jeremy Jan 25 '22 at 13:54
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.

kometen
  • 6,536
  • 6
  • 41
  • 51
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.

Filomat
  • 753
  • 1
  • 11
  • 16
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>
BATMAN_2008
  • 2,788
  • 3
  • 31
  • 98
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>
Donatello
  • 3,486
  • 3
  • 32
  • 38
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
Wafa Saba
  • 101
  • 1
  • 9