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

Reply via email to