You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Creating a Thread using its 5 parameter constructor with the inheritInheritableThreadLocals parameter set to false will result in using the system class loader since Java 19 (see this line in the JDK source) This means that the ThreadHelper.JDK9ThreadFactory will create threads that before Java 19 would inherit the parent thread's context class loader, however after Java 19, the created threads will use the system class loader.
Specifically on a project I'm currently working on, I noticed strange errors while trying to upgrade to Java 21. See this stack trace:
java.util.concurrent.ExecutionException: jakarta.xml.ws.WebServiceException: java.lang.Error: jakarta.xml.bind.JAXBException: Implementation of Jakarta XML Binding-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: org.glassfish.jaxb.runtime.v2.ContextFactory]
at com.sun.xml.ws.util.CompletedFuture.get(CompletedFuture.java:50)
at [*********]
at com.sun.xml.ws.client.AsyncResponseImpl.set(AsyncResponseImpl.java:104)
at com.sun.xml.ws.client.sei.AsyncMethodHandler$SEIAsyncInvoker$1.onCompletion(AsyncMethodHandler.java:179)
at com.sun.xml.ws.client.Stub$1.onCompletion(Stub.java:528)
at com.sun.xml.ws.api.pipe.Fiber.completionCheck(Fiber.java:897)
at com.sun.xml.ws.api.pipe.Fiber.run(Fiber.java:792)
at com.sun.xml.ws.api.server.ThreadLocalContainerResolver$2$1.run(ThreadLocalContainerResolver.java:89)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1570)
Caused by: jakarta.xml.ws.WebServiceException: java.lang.Error: jakarta.xml.bind.JAXBException: Implementation of Jakarta XML Binding-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: org.glassfish.jaxb.runtime.v2.ContextFactory]
... 8 common frames omitted
Caused by: java.lang.Error: jakarta.xml.bind.JAXBException: Implementation of Jakarta XML Binding-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: org.glassfish.jaxb.runtime.v2.ContextFactory]
at com.sun.xml.ws.fault.ExceptionBean.<clinit>(ExceptionBean.java:173)
at com.sun.xml.ws.fault.SOAPFaultBuilder.attachServerException(SOAPFaultBuilder.java:275)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:124)
at com.sun.xml.ws.client.sei.StubHandler.readResponse(StubHandler.java:225)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:176)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:263)
at com.sun.xml.ws.client.sei.AsyncMethodHandler$SEIAsyncInvoker$1.onCompletion(AsyncMethodHandler.java:148)
... 7 common frames omitted
Caused by: jakarta.xml.bind.JAXBException: Implementation of Jakarta XML Binding-API has not been found on module path or classpath.
at jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:250)
at jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:238)
at jakarta.xml.bind.ContextFinder.find(ContextFinder.java:386)
at jakarta.xml.bind.JAXBContext.newInstance(JAXBContext.java:605)
at jakarta.xml.bind.JAXBContext.newInstance(JAXBContext.java:546)
at com.sun.xml.ws.fault.ExceptionBean.<clinit>(ExceptionBean.java:170)
... 13 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.glassfish.jaxb.runtime.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:525)
at jakarta.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:113)
at jakarta.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:146)
at jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:248)
... 18 common frames omitted
This seems to happen because the completion handler runs on the "jaxws-engine-" threads but outside of a Fiber's _doRun method. This causes the code to use the original context class loader of that thread, which in Java 19(+) is the system class loader. However as our project is run from a Spring Boot generated executable jar, this is incorrect, because it should use Spring Boot's class loader instead.
Creating a
Thread
using its 5 parameter constructor with theinheritInheritableThreadLocals
parameter set tofalse
will result in using the system class loader since Java 19 (see this line in the JDK source) This means that theThreadHelper.JDK9ThreadFactory
will create threads that before Java 19 would inherit the parent thread's context class loader, however after Java 19, the created threads will use the system class loader.This does not play nice with Spring Boot generated executable jars (see https://docs.spring.io/spring-boot/specification/executable-jar/index.html). This can cause some code running on "jaxws-engine-" threads to behave differently with Java 19(+).
Specifically on a project I'm currently working on, I noticed strange errors while trying to upgrade to Java 21. See this stack trace:
This seems to happen because the completion handler runs on the "jaxws-engine-" threads but outside of a Fiber's
_doRun
method. This causes the code to use the original context class loader of that thread, which in Java 19(+) is the system class loader. However as our project is run from a Spring Boot generated executable jar, this is incorrect, because it should use Spring Boot's class loader instead.My proposal to fix this is by explicitely setting the context class loader of the threads created by
ThreadHelper.JDK9ThreadFactory
to the parent thread's class loader.This seems to be the proper solution according to this JDK ticket: https://bugs.openjdk.org/browse/JDK-8290003?jql=labels%20%3D%20JEP-425.
Spring Boot documentation mentions this as well: https://docs.spring.io/spring-boot/specification/executable-jar/restrictions.html.
I created the following PR for this: #698.
@lukasj Kindly review and share your feedback. Thanks.
The text was updated successfully, but these errors were encountered: