0

What do I do wrong with JAX-WS and SPRING-BOOT? I use jaxws-spring v1.9, spring-boot-starter-parent v2.7.0. I don`t have web.xml. I have @WebService() @SOAPBinding()

My problem is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat

 Runtime descriptor "/WEB-INF/sun-jaxws.xml" is missing but file is in /src/main/resource/WEB-INF/sun-jaxws.xml

2022-08-04 16:47:58.026 ERROR 20076 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:165) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577) ~[spring-context-5.3.20.jar:5.3.20]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.0.jar:2.7.0]
    at com.thecloud.telecom.TelecomApplication.main(TelecomApplication.java:14) ~[classes/:na]
Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:142) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:479) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:211) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:184) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:162) ~[spring-boot-2.7.0.jar:2.7.0]
    ... 8 common frames omitted
Caused by: java.lang.IllegalStateException: StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[] failed to start
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.rethrowDeferredStartupExceptions(TomcatWebServer.java:187) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:126) ~[spring-boot-2.7.0.jar:2.7.0]
    ... 13 common frames omitted

Disconnected from the target VM, address: '127.0.0.1:52298', transport: 'socket'

Process finished with exit code 1

It happens when I try to use JaxWsListener

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import com.sun.xml.ws.transport.http.servlet.WSServletContextListener;

@WebListener
public class JaxWsListener implements ServletContextAttributeListener, ServletContextListener {
    private final WSServletContextListener listener;

    public JaxWsListener() {
        this.listener = new WSServletContextListener();
    }

    @Override
    public void attributeAdded(ServletContextAttributeEvent event) {
        listener.attributeAdded(event);
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent event) {
        listener.attributeRemoved(event);
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent event) {
        listener.attributeReplaced(event);
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        listener.contextInitialized(sce);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        listener.contextDestroyed(sce);
    }
}

without this Listener spring-boot (tomcat) started well.

for JAX-WS as well I use this class : JaxWsServlet

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.xml.ws.transport.http.servlet.WSServlet;
import lombok.extern.log4j.Log4j2;

@Log4j2
@WebServlet(name = "JaxWsServlet", urlPatterns = JaxWsServlet.URL_PATTERN, loadOnStartup = 1)
public class JaxWsServlet extends WSServlet {

    public static final String URL_PATTERN = "/jaxws";

    public JaxWsServlet() {
        LOG.debug("CREATE {}", this.getClass().getSimpleName());
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        super.init(servletConfig);
        LOG.debug("JAX-WS Init");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {
        super.doPost(request, response);
        LOG.debug("JAX-WS DoPost");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
        super.doGet(request, response);
        LOG.debug("JAX-WS DoGet");
    }
}

as well I have /WEB-INF/soap-jaxws.xml

<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
           version="2.0">
    <endpoint name="SoapService"
              implementation="com.ws.endpoint.SoapService"
              url-pattern="/ws/call1" />

    <endpoint name="SoapService2"
              implementation="com.ws.endpoint.SoapService2"
              url-pattern="/ws/call2" />
</endpoints>

this file parsed in the WSServletContextListener - it is hard coded there.

Andrew Niken
  • 606
  • 2
  • 8
  • 18
  • Please post the full stacktrace instead of a snippet. – M. Deinum Aug 04 '22 at 14:01
  • Also `jaxws-spring` is pretty old (2013) and might not work with newer versions of Spring. I would suggest to ditch JaxWS and use something like Apache CXF instead. – M. Deinum Aug 04 '22 at 14:06
  • @M.Deinum changed log to full trace. About OLD JAX-WS - agree, but we have some code that used this and I have to extract this (at the beginning) and start in the spring boot. It has dome logic of the certificate validation. I was not able to reproduce it with spring-ws. Maybe I can do this later. but now I need legacy code that works with spring boot. It looks the problem only with Listener (at the moment) – Andrew Niken Aug 04 '22 at 15:39

1 Answers1

0

I solved this issue by putting /WEB-INF/sun-jaxws.xml into **/srv/main/resources/META-INF/resources/**WEB-INF/sun-jaxrs.xml

this helped me

sap-jaxws.xml

It is enough to have in your spring-boot application:

  1. /WEB-INF/sun-jaxws.xml - BCS it is HARDCODED in the jax-ws

  2. @WebService

  3. @WebListener

  4. spring-boot-starter-parent:2.7.0

  5. org.jvnet.jax-ws-commons.spring:jaxws-spring:1.9 - with exclusions

    @Service @WebService( name = "SoapService", endpointInterface = "com.ws.service.SoapService") @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE) public class SoapService implements ISoapService { ....

and @WebListener (look at it above)

@WebListener
public class JaxWsListener implements ServletContextAttributeListener, ServletContextListener {
    private final WSServletContextListener listener;
........

You do not need @WebServlet

pom.xml:

    <dependency>
        <groupId>org.jvnet.jax-ws-commons.spring</groupId>
        <artifactId>jaxws-spring</artifactId>
        <version>1.9</version>
        <exclusions>
            <exclusion>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.sun.xml.ws</groupId>
                <artifactId>jaxws-rt</artifactId>
            </exclusion>
            <!-- ? -->
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.sun.xml.stream.buffer</groupId>
                <artifactId>streambuffer</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.jvnet.staxex</groupId>
                <artifactId>stax-ex</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
Andrew Niken
  • 606
  • 2
  • 8
  • 18