This is an automated email from the ASF dual-hosted git repository. rzo1 pushed a commit to branch TOMEE-4703 in repository https://gitbox.apache.org/repos/asf/tomee.git
commit 780819f8f0d3243bfe94a3ecba0a124d8b5aa7d6 Author: Richard Zowalla <[email protected]> AuthorDate: Tue Sep 8 21:14:57 2026 +0200 TOMEE-4703 restore the caller's class loader after exiting the ThreadContext ApplicationThreadContextRestorer.endContext() restored the class loader it had saved and then called ThreadContext.exit(), which sets the loader again from the value the context recorded on entry - the application class loader begin() had just installed. The thread was left on the application class loader instead of the one it arrived with. Exit first and restore afterwards. Today this only shows on pool threads, where the next task's begin() masks it, because the identity guard in begin() keeps exitThreadContext false whenever the captured context is already the current one. --- .../threads/impl/ApplicationThreadContextProvider.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/container/openejb-core/src/main/java/org/apache/openejb/threads/impl/ApplicationThreadContextProvider.java b/container/openejb-core/src/main/java/org/apache/openejb/threads/impl/ApplicationThreadContextProvider.java index 5977812e3b..600b42c4d1 100755 --- a/container/openejb-core/src/main/java/org/apache/openejb/threads/impl/ApplicationThreadContextProvider.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/threads/impl/ApplicationThreadContextProvider.java @@ -100,13 +100,17 @@ public class ApplicationThreadContextProvider implements ThreadContextProvider, @Override public void endContext() throws IllegalStateException { - if (oldClassLoader != null) { - Thread.currentThread().setContextClassLoader(oldClassLoader); - } - + // exit first: ThreadContext.exit sets the class loader back to the one the context + // recorded when it was entered, which is the application class loader begin() had + // already installed. Restoring our own loader afterwards is what actually puts the + // thread back where it started. if (exitThreadContext) { ThreadContext.exit(oldThreadContext); } + + if (oldClassLoader != null) { + Thread.currentThread().setContextClassLoader(oldClassLoader); + } } @Override
