P D
P D

Reputation: 33

JAXB Exception in Java Spring Boot SOAP client

I am trying to create a Java Spring Boot SOAP client. I followed this instruction: https://www.baeldung.com/spring-soap-web-service

I am using Java 17 with Spring 3.1.0.

The basic steps are:

  1. generate classes from wsdl

This is the part of my pom file

<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.14.0</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <schemaLanguage>WSDL</schemaLanguage>
        <generateDirectory>${project.basedir}/target/generate-sources</generateDirectory>
        <generatePackage>de.mat.test.country</generatePackage>
        <schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory>
        <schemaIncludes>
            <include>countries.wsdl</include>
        </schemaIncludes>
    </configuration>
</plugin>

The class generation works fine as I can import and use the classes in the following classes.

  1. I created Client & ClientConfig with the following code
public class CountryClient extends WebServiceGatewaySupport {

  public GetCountryResponse getCountry(String country) {
    GetCountryRequest request = new GetCountryRequest();
    request.setName(country);

    var webServiceTemplate = getWebServiceTemplate();
    var response = webServiceTemplate.marshalSendAndReceive(request);
    GetCountryResponse getCountryResponse = (GetCountryResponse) response;
    return getCountryResponse;
  }
}
@Configuration
public class CountryClientConfig {

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("de.mat.test.country"); // this is the only thing changed here
        return marshaller;
    }

    @Bean
    public CountryClient countryClient(Jaxb2Marshaller marshaller) {
        CountryClient client = new CountryClient();
        client.setDefaultUri("http://localhost:8080/ws");
        client.setMarshaller(marshaller);
        client.setUnmarshaller(marshaller);
        return client;
    }
}
  1. Finally I created the test class, with a change to the annotation due to newer spring version
@SpringBootTest // this was @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CountryClientConfig.class, loader = AnnotationConfigContextLoader.class)
public class ClientLiveTest {

    @Autowired
    CountryClient client;

    @Test
    public void givenCountryService_whenCountryGermany_thenCapitalIsBerlin() {
        GetCountryResponse response = client.getCountry("GER");
        assertEquals("BLN", response.getCountry().getCapital());
    }

    @Test
    public void givenCountryService_whenCountrySpain_thenCurrencyEUR() {
        GetCountryResponse response = client.getCountry("ESP");
        assertEquals(Currency.EUR, response.getCountry().getCurrency());
    }
}

After doing all this and running the test I get an JAXB exception:

org.springframework.oxm.UncategorizedMappingException: Unknown JAXB exception
 at org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:958)
 at org.springframework.oxm.jaxb.Jaxb2Marshaller.marshal(Jaxb2Marshaller.java:716)
 at org.springframework.ws.support.MarshallingUtils.marshal(MarshallingUtils.java:80)
 at org.springframework.ws.client.core.WebServiceTemplate$2.doWithMessage(WebServiceTemplate.java:399)
 at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:569)
 at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:539)
 at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:391)
 at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:385)
 at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:375)
 at de.mat.test.client.CountryClient2.getCountry(CountryClient2.java:15)
 at de.mat.test.ClientLiveTest.givenCountryService_whenCountrySpain_thenCurrencyEUR(ClientLiveTest.java:31)
 at java.base/java.util.ArrayList.forEach(Unknown Source)
 at java.base/java.util.ArrayList.forEach(Unknown Source)
Caused by: jakarta.xml.bind.JAXBException: class de.mat.test.country.GetCountryRequest nor any of its super class is known to this context.
 at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:543)
 at org.glassfish.jaxb.runtime.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:444)
 at org.glassfish.jaxb.runtime.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:265)
 at org.glassfish.jaxb.runtime.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:197)
 at org.springframework.oxm.jaxb.Jaxb2Marshaller.marshal(Jaxb2Marshaller.java:712)

Does anyone know what the problem here might be? Am I missing an annotation or something? Is it due to me using a newer Spring Boot version?

If needed I am happy to provide more information.

Thanks in advance, Paul

Upvotes: 0

Views: 1815

Answers (1)

Dev Duart
Dev Duart

Reputation: 1

I was able to successfully run with Spring Boot 3.1.0 and Java 17 using these configurations in my pom.xml and by removing all javax dependencies:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-rt</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
</dependency>
....
<build>
    <plugins>
        <plugin>
            <groupId>com.sun.xml.ws</groupId>
            <artifactId>jaxws-maven-plugin</artifactId>
            <version>4.0.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>wsimport</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <packageName>{com.example.wsdl}</packageName>
                <wsdlUrls>
                    <wsdlUrl>{url}</wsdlUrl>
                </wsdlUrls>
                <sourceDestDir>${basedir}/src/main/java</sourceDestDir>
                <extension>true</extension>
                <keep>true</keep>
                <verbose>true</verbose>
                <vmArgs>
                    <vmArg>-Djavax.xml.accessExternalSchema=all</vmArg>
                </vmArgs>
            </configuration>
        </plugin>
    </plugins>
</build>

Upvotes: 0

Related Questions