Problem on updating from Java 8 to Java 17
beat2 opened this issue · 5 comments
My SOAP service worked for the last few years with Java 8. Then I tried to update to Java 17.
When sending (a valid) request with Soap-UI I am getting this stacktrace:
15:57:49 WARN [fd416dff-2bc7-4d49-86ca-4b3d68cfc627] [] [] [c.a.b.l.s.e.CustomFaultHandler]: Processing Exception java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 16 at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.mergeContext(XMLSchemaValidator.java:494) at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElementPSVI(XMLSchemaValidator.java:2561) at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(XMLSchemaValidator.java:2477) at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(XMLSchemaValidator.java:944) at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.DOMValidatorHelper.finishNode(DOMValidatorHelper.java:342) at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.DOMValidatorHelper.validate(DOMValidatorHelper.java:247) at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.DOMValidatorHelper.validate(DOMValidatorHelper.java:190) at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(ValidatorImpl.java:108) at java.xml/javax.xml.validation.Validator.validate(Validator.java:124) at org.springframework.xml.validation.Jaxp15ValidatorFactory$Jaxp15Validator.validate(Jaxp15ValidatorFactory.java:97) at org.springframework.ws.server.endpoint.interceptor.AbstractValidatingInterceptor.handleRequest(AbstractValidatingInterceptor.java:187) at org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:221) at org.springframework.ws.server.MessageDispatcher.receive(MessageDispatcher.java:174) at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:88) at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:60) at org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:288) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) at javax.servlet.http.HttpServlet.service(HttpServlet.java:515) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at javax.servlet.http.HttpServlet.service(HttpServlet.java:583) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:212) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:156) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:181) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:156) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:181) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:156) at ch.admin.bit.jeap.log.correlation.web.CorrelationIdFilter.doFilterInternal(CorrelationIdFilter.java:71) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:181) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:156) at org.springframework.web.servlet.resource.ResourceUrlEncodingFilter.doFilter(ResourceUrlEncodingFilter.java:67) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:181) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:156) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:181) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:156) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:181) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:156) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:181) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:156) at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:181) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:156) at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:126) at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:64) at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:101) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:119) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:181) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:156) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:181) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:156) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:682) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:617) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:932) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1695) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) 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)
With Java 8 it just works. Spring-WS 3.1.6 is used.
Interestingly, I found a workaround. If I use a custom PayloadValidatingInterceptor
(like mentioned here: Stackoverflow), it works again.
Java 8 -> Java 17 seems to hit SOAP land hardest due to the sheer number of packages pulled out of the JDK that migrated either to Jakarta EE or to external projects.
Some of the clues are captured here: https://spring.io/blog/2022/12/02/spring-ws-samples-upgraded-for-spring-boot-3-0
And there are more code examples here: https://github.com/spring-projects/spring-ws-samples
Of course, the examples just provided illustrate how to use Spring WS with Spring Boot 3 combined with Java 17, so that means Java 17 as well as Jakarta EE 9+. To use Spring WS 3.1 with Java 17 requires a bit of a mixture because that version does NOT use Jakarta EE 9+, meaning you are still on the javax.*
packages, but you won't find anything you are looking for inside the JDK.
Now we actually test the 3.1.x
branch against Java 17 on our CI system (https://github.com/spring-projects/spring-ws/blob/3.1.x/Jenkinsfile#L127-L140). The clue is in the java11
profile in our build file (https://github.com/spring-projects/spring-ws/blob/3.1.x/pom.xml#L723-L840).
You may want to check that out, and also compare that with the versions of the SOAP provider we have on our 3.1.x
branch compared to the version of your SOAP provider. SOAP can be rather brittle, so it's vital that all these parts are properly aligned.
I frankly can't see what's breaking, but it could be any of these things (or something else!)
Thanks for your reply.
Yes, that is true. We use Spring Boot 2.7.12, are not (yet) on Spring Boot 3.
I am unsure if the problem is in Spring WS or in the JDK. The exception happens in internal JDKs Xerces code.
- But then again, if I log and validate the XML in question that works.
- It also works when providing the "real" / original Xerces, but then Spring complains a bit about the OWASP-Security-Settings.
- It also works when using the mentioned workaround, but converting to a String might double the used Heap-Size I fear.
I will try to compare the dependencies next, to see if something differs.
Tried to change dependencies, but it did not make a difference.
I tried to switch off the webservice security, then it validates. So it might be related to something like wss4j, I don't know. We are using Wss4jSecurityInterceptor wrapped in a DelegatingSmartSoapEndpointInterceptor.
Here is a reproducible project that has the issue: https://github.com/beat2/demo
@beat2 Java 17 doesn't include all the dependencies you need. If you are on Spring Boot 2.7.x I suggest remain on Java 8. If you want to move to Java 17 consider upgrading to Spring Boot 3.2.x
Tried to change dependencies, but it did not make a difference.
I tried to switch off the webservice security, then it validates. So it might be related to something like wss4j, I don't know. We are using Wss4jSecurityInterceptor wrapped in a DelegatingSmartSoapEndpointInterceptor.
Here is a reproducible project that has the issue: https://github.com/beat2/demo
The jakarta xml dependencies are not going to work with Spring WS 3.x