Search code examples
javaspring-bootjaxbspring-wsspring-oxm

JDK17 + Spring Boot Starter Web Services: Implementation of JAXB-API has not been found on module path or classpath


I have a simple spring boot app and I want to send request to a SOAP endpoint. Unfortunately every time I try to do this I receive: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath. I'm really confident that I have all the required libraries and I have no idea why it's happening

Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:177)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:364)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:508)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:465)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:366)
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.createJaxbContextFromContextPath(Jaxb2Marshaller.java:540)
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.getJaxbContext(Jaxb2Marshaller.java:500)
    ... 18 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    at javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122)
    at javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:174)
    ... 24 common frames omitted

I'm using JDK17

openjdk 17.0.2 2022-01-18
OpenJDK Runtime Environment Temurin-17.0.2+8 (build 17.0.2+8)
OpenJDK 64-Bit Server VM Temurin-17.0.2+8 (build 17.0.2+8, mixed mode, sharing)

My build.gradle looks like this:

implementation("org.springframework.boot:spring-boot-starter-web-services:2.6.6")
implementation('jakarta.xml.bind:jakarta.xml.bind-api:3.0.1')
implementation('org.glassfish.jaxb:jaxb-runtime:3.0.2')
implementation('com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.2')

My code looks like this:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import jakarta.xml.bind.JAXBElement;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.ws.soap.client.core.SoapActionCallback;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;



@Component
public class MyClient extends WebServiceGatewaySupport {

    XmlMapper xmlMapper = new XmlMapper();

    public MyClient() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath(CONTEXT_PATH);

        this.setMarshaller(marshaller);
        this.setUnmarshaller(marshaller);
        this.setDefaultUri(API_URL);
    }

 void myMethod(){
...
// AT THIS MOMENT I RECEIVE THE EXCEPTION
        var response = (MyResponseClass) getWebServiceTemplate()
            .marshalSendAndReceive(
                request,
                new SoapActionCallback(CALLBACK_URI)
            );
...
{

How to solve it ?


Solution

  • Jakarta EE9 is not supported by spring yet - you need to wait for spring6 - https://spring.io/blog/2021/09/02/a-java-17-and-jakarta-ee-9-baseline-for-spring-framework-6

    You should use

    implementation('jakarta.xml.bind:jakarta.xml.bind-api:2.3.3')
    implementation('org.glassfish.jaxb:jaxb-runtime:2.3.6')