Home > Back-end >  Spring boot 2.7.2 with JDK 17 and SOAP Web service
Spring boot 2.7.2 with JDK 17 and SOAP Web service

Time:08-12

I'm trying to set up Spring boot (2.7.2) on JDK 18 with exposing Web service endpoints alongside of normal REST endpoints.

The application boots up without any errors and can server my REST endpoints without any problems but the moment it receives a SOAP request it fails with the following error message:

: Servlet.init() for servlet [messageDispatcherServlet] threw exception

org.springframework.beans.factory.BeanInitializationException: Could not initialize WebServiceMessageReceiverHandlerAdapter; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.ws.soap.saaj.SaajSoapMessageFactory]: Unresolvable class definition; nested exception is java.lang.NoClassDefFoundError: javax/xml/soap/SOAPException
at org.springframework.ws.transport.http.MessageDispatcherServlet.initMessageReceiverHandlerAdapter(MessageDispatcherServlet.java:380)
at org.springframework.ws.transport.http.MessageDispatcherServlet.initStrategies(MessageDispatcherServlet.java:361)
at org.springframework.ws.transport.http.MessageDispatcherServlet.onRefresh(MessageDispatcherServlet.java:296)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:599)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:170)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1164)
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:804)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:128)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.ws.soap.saaj.SaajSoapMessageFactory]: Unresolvable class definition; nested exception is java.lang.NoClassDefFoundError: javax/xml/soap/SOAPException
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:156)
at org.springframework.ws.support.DefaultStrategiesHelper.instantiateBean(DefaultStrategiesHelper.java:149)
at org.springframework.ws.support.DefaultStrategiesHelper.getDefaultStrategies(DefaultStrategiesHelper.java:134)
at org.springframework.ws.support.DefaultStrategiesHelper.getDefaultStrategy(DefaultStrategiesHelper.java:214)
at org.springframework.ws.transport.http.MessageDispatcherServlet.initWebServiceMessageFactory(MessageDispatcherServlet.java:389)
at org.springframework.ws.transport.http.MessageDispatcherServlet.initMessageReceiverHandlerAdapter(MessageDispatcherServlet.java:377)
... 24 common frames omitted
 Caused by: java.lang.NoClassDefFoundError: javax/xml/soap/SOAPException
at java.base/java.lang.Class.getDeclaredConstructors0(Native Method)
at java.base/java.lang.Class.privateGetDeclaredConstructors(Class.java:3405)
at java.base/java.lang.Class.getConstructor0(Class.java:3610)
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2786)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:146)
... 29 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.xml.soap.SOAPException
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:521)
... 34 common frames omitted

Here is my pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.2</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
<groupId>com.company</groupId>
<artifactId>simulator-service</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>simulator-service</name>
<description>Microservice to simulate X</description>

<properties>
    <java.version>17</java.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <mapstruct.version>1.4.2.Final</mapstruct.version>
    <swagger.v3.annotations.version>2.1.12</swagger.v3.annotations.version>
    <commons.validator.version>1.7</commons.validator.version>
    <logback.ecs.version>1.3.0</logback.ecs.version>
    <lombok.mapstruct.version>0.2.0</lombok.mapstruct.version>
    <commons.io.version>2.11.0</commons.io.version>
    <springdoc.version>1.6.4</springdoc.version>
    <hamcrest-all.version>1.3</hamcrest-all.version>
    <swagger.annotations.version>1.6.4</swagger.annotations.version>
    <jose4j.version>0.7.12</jose4j.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web-services</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
    </dependency>
    <dependency>
        <groupId>org.flywaydb</groupId>
        <artifactId>flyway-core</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>${mapstruct.version}</version>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>${mapstruct.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <dependency>
        <groupId>wsdl4j</groupId>
        <artifactId>wsdl4j</artifactId>
    </dependency>
    <dependency>
        <groupId>io.swagger.core.v3</groupId>
        <artifactId>swagger-annotations</artifactId>
        <version>${swagger.v3.annotations.version}</version>
    </dependency>
    <dependency>
        <groupId>commons-validator</groupId>
        <artifactId>commons-validator</artifactId>
        <version>${commons.validator.version}</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok-mapstruct-binding</artifactId>
        <version>${lombok.mapstruct.version}</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>${commons.io.version}</version>
    </dependency>
    <dependency>
      <groupId>org.bitbucket.b_c</groupId>
      <artifactId>jose4j</artifactId>
      <version>${jose4j.version}</version>
    </dependency>
  <!--    expose swagger-->
    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-ui</artifactId>
        <version>${springdoc.version}</version>
    </dependency>
  <dependency>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-annotations</artifactId>
    <version>${swagger.annotations.version}</version>
  </dependency>
</dependencies>

<build>
    <finalName>${project.artifactId}-${project.version}</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>build-info</id>
                    <goals>
                        <goal>build-info</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>${maven-dependency-plugin.version}</version>
            <executions>
                <execution>
                    <id>unpack</id>
                    <phase>package</phase>
                    <goals>
                        <goal>unpack</goal>
                    </goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>${project.groupId}</groupId>
                                <artifactId>${project.artifactId}</artifactId>
                                <version>${project.version}</version>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <runOrder>alphabetical</runOrder>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
        </plugin>
    </plugins>
</build>
<profiles>
    <profile>
        <id>dependency-check</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.owasp</groupId>
                    <artifactId>dependency-check-maven</artifactId>
                    <version>6.0.3</version>
                    <executions>
                        <execution>
                            <id>verify</id>
                            <phase>verify</phase>
                            <goals>
                                <goal>check</goal>
                            </goals>
                            <configuration>
                                <format>XML</format>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
    <profile>
        <id>swaggergen</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <profiles>swaggergen</profiles>
                        <jvmArguments>-Dspring.application.admin.enabled=false</jvmArguments>
                    </configuration>
                    <executions>
                        <execution>
                            <id>pre-integration-test</id>
                            <goals>
                                <goal>start</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>post-integration-test</id>
                            <goals>
                                <goal>stop</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>

</profiles>

I have created the following configuration class:

@EnableWs
@Configuration
public class WebServiceConfig
    extends WsConfigurerAdapter
{
  @Bean
  public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
    MessageDispatcherServlet servlet = new MessageDispatcherServlet();
    servlet.setApplicationContext(applicationContext);
    servlet.setTransformWsdlLocations(true);
    return new ServletRegistrationBean(servlet, "/webservices/Service/SoapStubService", "/webservices/Service/*");
  }

  @Bean(name = "bnl")
  public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema bnlSchema) {
    DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
    wsdl11Definition.setPortTypeName("bnlPort");
    wsdl11Definition.setLocationUri("/webservices/Service/SoapStubService");
    wsdl11Definition.setTargetNamespace("http://www.bnl.ll/company/schemas");
    wsdl11Definition.setSchema(bnlSchema);
    return wsdl11Definition;
  }

  @Bean
  public XsdSchema bnlSchema() {
    return new SimpleXsdSchema(new ClassPathResource("/xsd/bnl.xsd"));
  }
}

and the following endpoint class to receive the incoming request:

@Endpoint
public class BnlSoapEndpoint
{
  private static final String NAMESPACE_URI = "http://www.bnl.ll/company/schemas";

  @Autowired
  public BilSoapEndpoint() {
    super();
  }

  @PayloadRoot(namespace = NAMESPACE_URI, localPart = "PingBnl")
  @ResponsePayload
  public PingResponse pingBnl(@RequestPayload PingRequest pingRequest) {
    PingResponse response = new PingResponse();
    response.setStatus(PingStatus.SUCCESS);
    return response;
  }

}

The matching POJOs are using the javax.xml.bind packages which are working and running fine as it seems. Trying to replace them with the jakarta equivalent for newer JDKs caused problems with Hibernate on runtime.

I have tried a bunch of google results and StackOverflow results from 2015-2018 but none have resolved my problem. Here were some dependencies I tried without success or any change in the exception:

    <!-- <dependency>
      <groupId>jakarta.xml.soap</groupId>
      <artifactId>jakarta.xml.soap-api</artifactId>
      <version>3.0.0</version>
    </dependency> -->
    <!-- <dependency>
      <groupId>javax.xml.soap</groupId>
      <artifactId>javax.xml.soap-api</artifactId>
      <version>1.4.0</version>
    </dependency>
    <dependency>
      <groupId>javax.xml.ws</groupId>
      <artifactId>jaxws-api</artifactId>
      <version>2.3.1</version>
    </dependency>
    <dependency>
      <groupId>com.sun.xml.messaging.saaj</groupId>
      <artifactId>saaj-impl</artifactId>
      <version>3.0.0</version>
    </dependency> -->
  <!-- <dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>4.0.0</version>
  </dependency>
    <dependency>
      <groupId>org.glassfish.jaxb</groupId>
      <artifactId>jaxb-runtime</artifactId>
      <version>4.0.0</version>
    </dependency> -->

Any help in resolving this would be highly appreciated.

PS: Resources I read and tried out below

SoapUI

CodePudding user response:

As Andy Wilkinson pointed out in the comments my local repository got broken or my IDE was holding incorrect caches somewhere and after cleaning my whole .m2 local repository and cleaning the IDE caches, it built completely fine and is able to respond to the SOAP message!

  • Related