This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push: new 90a3050e93 Refactor to reduce native calls 90a3050e93 is described below commit 90a3050e93c3b3e58d772051313525d0446b95f9 Author: Mark Thomas <ma...@apache.org> AuthorDate: Fri Feb 24 14:59:43 2023 +0000 Refactor to reduce native calls Thread.currentThread() is a native call so ensure it is only used once per method, caching the result in a local variable if it is used more than once. Note: some instances of caching aren't strictly necessary but are a side-effect of the refactoring. --- java/org/apache/catalina/ant/ValidatorTask.java | 7 +- .../core/JreMemoryLeakPreventionListener.java | 7 +- java/org/apache/catalina/core/StandardContext.java | 14 ++-- java/org/apache/catalina/core/StandardServer.java | 5 +- .../catalina/ha/context/ReplicatedContext.java | 7 +- .../apache/catalina/ha/session/DeltaManager.java | 7 +- .../apache/catalina/ha/session/DeltaSession.java | 7 +- java/org/apache/catalina/loader/WebappLoader.java | 7 +- java/org/apache/catalina/realm/JAASRealm.java | 10 +-- java/org/apache/catalina/realm/JNDIRealm.java | 80 +++++++++++++--------- .../apache/catalina/servlets/DefaultServlet.java | 14 ++-- .../tribes/membership/McastServiceImpl.java | 37 +++++----- .../membership/StaticMembershipProvider.java | 14 ++-- .../membership/cloud/CloudMembershipProvider.java | 7 +- .../catalina/valves/StuckThreadDetectionValve.java | 5 +- java/org/apache/coyote/AsyncStateMachine.java | 13 ++-- java/org/apache/jasper/JspC.java | 9 +-- .../apache/jasper/compiler/ELFunctionMapper.java | 5 +- .../apache/jasper/compiler/JspDocumentParser.java | 15 ++-- .../apache/jasper/compiler/TagPluginManager.java | 15 ++-- java/org/apache/naming/ContextBindings.java | 10 +-- .../tomcat/util/descriptor/tld/TldParser.java | 13 ++-- .../tomcat/util/security/PrivilegedGetTccl.java | 15 +++- .../tomcat/util/security/PrivilegedSetTccl.java | 1 + .../tomcat/util/threads/ThreadPoolExecutor.java | 6 +- .../tomcat/websocket/AsyncChannelGroupUtil.java | 8 +-- .../tomcat/websocket/server/WsFrameServer.java | 14 ++-- .../TestWebappClassLoaderExecutorMemoryLeak.java | 11 ++- .../catalina/startup/TestTomcatClassLoader.java | 7 +- .../org/apache/juli/TestClassLoaderLogManager.java | 7 +- 30 files changed, 212 insertions(+), 165 deletions(-) diff --git a/java/org/apache/catalina/ant/ValidatorTask.java b/java/org/apache/catalina/ant/ValidatorTask.java index fbe360dd0a..81d3997bc4 100644 --- a/java/org/apache/catalina/ant/ValidatorTask.java +++ b/java/org/apache/catalina/ant/ValidatorTask.java @@ -81,8 +81,9 @@ public class ValidatorTask extends BaseRedirectorHelperTask { } // Commons-logging likes having the context classloader set - ClassLoader oldCL = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(ValidatorTask.class.getClassLoader()); + Thread currentThread = Thread.currentThread(); + ClassLoader oldCL = currentThread.getContextClassLoader(); + currentThread.setContextClassLoader(ValidatorTask.class.getClassLoader()); // Called through trusted manager interface. If running under a // SecurityManager assume that untrusted applications may be deployed. @@ -100,7 +101,7 @@ public class ValidatorTask extends BaseRedirectorHelperTask { handleErrorOutput("Validation failure: " + e); } } finally { - Thread.currentThread().setContextClassLoader(oldCL); + currentThread.setContextClassLoader(oldCL); closeRedirector(); } diff --git a/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java b/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java index 86430e8c06..897701f72a 100644 --- a/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java +++ b/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java @@ -237,12 +237,13 @@ public class JreMemoryLeakPreventionListener implements LifecycleListener { DriverManager.getDrivers(); } - ClassLoader loader = Thread.currentThread().getContextClassLoader(); + Thread currentThread = Thread.currentThread(); + ClassLoader loader = currentThread.getContextClassLoader(); try { // Use the system classloader as the victim for all this // ClassLoader pinning we're about to do. - Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader()); + currentThread.setContextClassLoader(ClassLoader.getSystemClassLoader()); /* * Several components end up calling: sun.awt.AppContext.getAppContext() @@ -403,7 +404,7 @@ public class JreMemoryLeakPreventionListener implements LifecycleListener { } } finally { - Thread.currentThread().setContextClassLoader(loader); + currentThread.setContextClassLoader(loader); } } } diff --git a/java/org/apache/catalina/core/StandardContext.java b/java/org/apache/catalina/core/StandardContext.java index 478e5b1bc5..cbdef7902f 100644 --- a/java/org/apache/catalina/core/StandardContext.java +++ b/java/org/apache/catalina/core/StandardContext.java @@ -5522,12 +5522,13 @@ public class StandardContext extends ContainerBase implements Context, Notificat webApplicationClassLoader = loader.getClassLoader(); } + Thread currentThread = Thread.currentThread(); if (originalClassLoader == null) { if (usePrivilegedAction) { - PrivilegedAction<ClassLoader> pa = new PrivilegedGetTccl(); + PrivilegedAction<ClassLoader> pa = new PrivilegedGetTccl(currentThread); originalClassLoader = AccessController.doPrivileged(pa); } else { - originalClassLoader = Thread.currentThread().getContextClassLoader(); + originalClassLoader = currentThread.getContextClassLoader(); } } @@ -5540,10 +5541,10 @@ public class StandardContext extends ContainerBase implements Context, Notificat ThreadBindingListener threadBindingListener = getThreadBindingListener(); if (usePrivilegedAction) { - PrivilegedAction<Void> pa = new PrivilegedSetTccl(webApplicationClassLoader); + PrivilegedAction<Void> pa = new PrivilegedSetTccl(currentThread, webApplicationClassLoader); AccessController.doPrivileged(pa); } else { - Thread.currentThread().setContextClassLoader(webApplicationClassLoader); + currentThread.setContextClassLoader(webApplicationClassLoader); } if (threadBindingListener != null) { try { @@ -5573,11 +5574,12 @@ public class StandardContext extends ContainerBase implements Context, Notificat } } + Thread currentThread = Thread.currentThread(); if (usePrivilegedAction) { - PrivilegedAction<Void> pa = new PrivilegedSetTccl(originalClassLoader); + PrivilegedAction<Void> pa = new PrivilegedSetTccl(currentThread, originalClassLoader); AccessController.doPrivileged(pa); } else { - Thread.currentThread().setContextClassLoader(originalClassLoader); + currentThread.setContextClassLoader(originalClassLoader); } } diff --git a/java/org/apache/catalina/core/StandardServer.java b/java/org/apache/catalina/core/StandardServer.java index b099cde602..0bf371020c 100644 --- a/java/org/apache/catalina/core/StandardServer.java +++ b/java/org/apache/catalina/core/StandardServer.java @@ -558,9 +558,10 @@ public final class StandardServer extends LifecycleMBeanBase implements Server { // undocumented yet - for embedding apps that are around, alive. return; } + Thread currentThread = Thread.currentThread(); if (getPortWithOffset() == -1) { try { - awaitThread = Thread.currentThread(); + awaitThread = currentThread; while (!stopAwait) { try { Thread.sleep(10000); @@ -584,7 +585,7 @@ public final class StandardServer extends LifecycleMBeanBase implements Server { } try { - awaitThread = Thread.currentThread(); + awaitThread = currentThread; // Loop waiting for a connection and a valid command while (!stopAwait) { diff --git a/java/org/apache/catalina/ha/context/ReplicatedContext.java b/java/org/apache/catalina/ha/context/ReplicatedContext.java index 1eb12975c6..c9f3dfa733 100644 --- a/java/org/apache/catalina/ha/context/ReplicatedContext.java +++ b/java/org/apache/catalina/ha/context/ReplicatedContext.java @@ -106,13 +106,14 @@ public class ReplicatedContext extends StandardContext implements MapOwner { if (loader != null) { classLoader = loader.getClassLoader(); } + Thread currentThread = Thread.currentThread(); if ( classLoader == null ) { - classLoader = Thread.currentThread().getContextClassLoader(); + classLoader = currentThread.getContextClassLoader(); } - if ( classLoader == Thread.currentThread().getContextClassLoader() ) { + if ( classLoader == currentThread.getContextClassLoader() ) { return new ClassLoader[] {classLoader}; } else { - return new ClassLoader[] {classLoader,Thread.currentThread().getContextClassLoader()}; + return new ClassLoader[] {classLoader,currentThread.getContextClassLoader()}; } } diff --git a/java/org/apache/catalina/ha/session/DeltaManager.java b/java/org/apache/catalina/ha/session/DeltaManager.java index 2217d7ca70..e32415fd94 100644 --- a/java/org/apache/catalina/ha/session/DeltaManager.java +++ b/java/org/apache/catalina/ha/session/DeltaManager.java @@ -1217,11 +1217,12 @@ public class DeltaManager extends ClusterManagerBase{ * requesting node */ protected void messageReceived(SessionMessage msg, Member sender) { - ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); + Thread currentThread = Thread.currentThread(); + ClassLoader contextLoader = currentThread.getContextClassLoader(); try { ClassLoader[] loaders = getClassLoaders(); - Thread.currentThread().setContextClassLoader(loaders[0]); + currentThread.setContextClassLoader(loaders[0]); if (log.isDebugEnabled()) { log.debug(sm.getString("deltaManager.receiveMessage.eventType", getName(), msg.getEventTypeString(), sender)); @@ -1262,7 +1263,7 @@ public class DeltaManager extends ClusterManagerBase{ } catch (Exception x) { log.error(sm.getString("deltaManager.receiveMessage.error",getName()), x); } finally { - Thread.currentThread().setContextClassLoader(contextLoader); + currentThread.setContextClassLoader(contextLoader); } } diff --git a/java/org/apache/catalina/ha/session/DeltaSession.java b/java/org/apache/catalina/ha/session/DeltaSession.java index 85ef168028..a896b02a39 100644 --- a/java/org/apache/catalina/ha/session/DeltaSession.java +++ b/java/org/apache/catalina/ha/session/DeltaSession.java @@ -197,16 +197,17 @@ public class DeltaSession extends StandardSession implements Externalizable,Clus public void applyDiff(byte[] diff, int offset, int length) throws IOException, ClassNotFoundException { lockInternal(); try (ObjectInputStream stream = ((ClusterManager) getManager()).getReplicationStream(diff, offset, length)) { - ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); + Thread currentThread = Thread.currentThread(); + ClassLoader contextLoader = currentThread.getContextClassLoader(); try { ClassLoader[] loaders = getClassLoaders(); if (loaders != null && loaders.length > 0) { - Thread.currentThread().setContextClassLoader(loaders[0]); + currentThread.setContextClassLoader(loaders[0]); } getDeltaRequest().readExternal(stream); getDeltaRequest().execute(this, ((ClusterManager)getManager()).isNotifyListenersOnReplication()); } finally { - Thread.currentThread().setContextClassLoader(contextLoader); + currentThread.setContextClassLoader(contextLoader); } } finally { unlockInternal(); diff --git a/java/org/apache/catalina/loader/WebappLoader.java b/java/org/apache/catalina/loader/WebappLoader.java index 98b81657ae..674a52fdce 100644 --- a/java/org/apache/catalina/loader/WebappLoader.java +++ b/java/org/apache/catalina/loader/WebappLoader.java @@ -302,16 +302,15 @@ public class WebappLoader extends LifecycleMBeanBase @Override public void backgroundProcess() { if (reloadable && modified()) { + Thread currentThread = Thread.currentThread(); try { - Thread.currentThread().setContextClassLoader - (WebappLoader.class.getClassLoader()); + currentThread.setContextClassLoader(WebappLoader.class.getClassLoader()); if (context != null) { context.reload(); } } finally { if (context != null && context.getLoader() != null) { - Thread.currentThread().setContextClassLoader - (context.getLoader().getClassLoader()); + currentThread.setContextClassLoader(context.getLoader().getClassLoader()); } } } diff --git a/java/org/apache/catalina/realm/JAASRealm.java b/java/org/apache/catalina/realm/JAASRealm.java index a24b3d5346..e1bc08cdb3 100644 --- a/java/org/apache/catalina/realm/JAASRealm.java +++ b/java/org/apache/catalina/realm/JAASRealm.java @@ -374,10 +374,12 @@ public class JAASRealm extends RealmBase { // What if the LoginModule is in the container class loader ? ClassLoader ocl = null; + Thread currentThread = null; if (!isUseContextClassLoader()) { - ocl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + currentThread = Thread.currentThread(); + ocl = currentThread.getContextClassLoader(); + currentThread.setContextClassLoader(this.getClass().getClassLoader()); } try { @@ -391,8 +393,8 @@ public class JAASRealm extends RealmBase { invocationSuccess = false; return null; } finally { - if (!isUseContextClassLoader()) { - Thread.currentThread().setContextClassLoader(ocl); + if (currentThread != null) { + currentThread.setContextClassLoader(ocl); } } diff --git a/java/org/apache/catalina/realm/JNDIRealm.java b/java/org/apache/catalina/realm/JNDIRealm.java index 0ac18ce0da..6ccf5a69d4 100644 --- a/java/org/apache/catalina/realm/JNDIRealm.java +++ b/java/org/apache/catalina/realm/JNDIRealm.java @@ -1134,6 +1134,7 @@ public class JNDIRealm extends RealmBase { public Principal authenticate(String username, String credentials) { ClassLoader ocl = null; + Thread currentThread = null; JNDIConnection connection = null; Principal principal = null; @@ -1143,8 +1144,9 @@ public class JNDIRealm extends RealmBase { // running on a JVM that includes a fix for // https://bugs.openjdk.java.net/browse/JDK-8273874 if (!isUseContextClassLoader()) { - ocl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + currentThread = Thread.currentThread(); + ocl = currentThread.getContextClassLoader(); + currentThread.setContextClassLoader(this.getClass().getClassLoader()); } // Ensure that we have a directory context available @@ -1206,8 +1208,8 @@ public class JNDIRealm extends RealmBase { } return null; } finally { - if (!isUseContextClassLoader()) { - Thread.currentThread().setContextClassLoader(ocl); + if (currentThread != null) { + currentThread.setContextClassLoader(ocl); } } } @@ -1236,14 +1238,16 @@ public class JNDIRealm extends RealmBase { } ClassLoader ocl = null; + Thread currentThread= null; try { // https://bz.apache.org/bugzilla/show_bug.cgi?id=65553 // This can move back to open() once it is known that Tomcat must be // running on a JVM that includes a fix for // https://bugs.openjdk.java.net/browse/JDK-8273874 if (!isUseContextClassLoader()) { - ocl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + currentThread = Thread.currentThread(); + ocl = currentThread.getContextClassLoader(); + currentThread.setContextClassLoader(this.getClass().getClassLoader()); } if (userPatternArray != null) { @@ -1294,8 +1298,8 @@ public class JNDIRealm extends RealmBase { return new GenericPrincipal(username, credentials, roles); } } finally { - if (!isUseContextClassLoader()) { - Thread.currentThread().setContextClassLoader(ocl); + if (currentThread != null) { + currentThread.setContextClassLoader(ocl); } } } @@ -1309,15 +1313,17 @@ public class JNDIRealm extends RealmBase { @Override public Principal authenticate(String username) { ClassLoader ocl = null; + Thread currentThread = null; try { if (!isUseContextClassLoader()) { - ocl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + currentThread = Thread.currentThread(); + ocl = currentThread.getContextClassLoader(); + currentThread.setContextClassLoader(this.getClass().getClassLoader()); } return super.authenticate(username); } finally { - if (!isUseContextClassLoader()) { - Thread.currentThread().setContextClassLoader(ocl); + if (currentThread != null) { + currentThread.setContextClassLoader(ocl); } } } @@ -1332,15 +1338,17 @@ public class JNDIRealm extends RealmBase { public Principal authenticate(String username, String clientDigest, String nonce, String nc, String cnonce, String qop, String realm, String md5a2) { ClassLoader ocl = null; + Thread currentThread = null; try { if (!isUseContextClassLoader()) { - ocl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + currentThread = Thread.currentThread(); + ocl = currentThread.getContextClassLoader(); + currentThread.setContextClassLoader(this.getClass().getClassLoader()); } return super.authenticate(username, clientDigest, nonce, nc, cnonce, qop, realm, md5a2); } finally { - if (!isUseContextClassLoader()) { - Thread.currentThread().setContextClassLoader(ocl); + if (currentThread != null) { + currentThread.setContextClassLoader(ocl); } } } @@ -1354,15 +1362,17 @@ public class JNDIRealm extends RealmBase { @Override public Principal authenticate(X509Certificate[] certs) { ClassLoader ocl = null; + Thread currentThread = null; try { if (!isUseContextClassLoader()) { - ocl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + currentThread = Thread.currentThread(); + ocl = currentThread.getContextClassLoader(); + currentThread.setContextClassLoader(this.getClass().getClassLoader()); } return super.authenticate(certs); } finally { - if (!isUseContextClassLoader()) { - Thread.currentThread().setContextClassLoader(ocl); + if (currentThread != null) { + currentThread.setContextClassLoader(ocl); } } } @@ -1376,15 +1386,17 @@ public class JNDIRealm extends RealmBase { @Override public Principal authenticate(GSSContext gssContext, boolean storeCred) { ClassLoader ocl = null; + Thread currentThread = null; try { if (!isUseContextClassLoader()) { - ocl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + currentThread = Thread.currentThread(); + ocl = currentThread.getContextClassLoader(); + currentThread.setContextClassLoader(this.getClass().getClassLoader()); } return super.authenticate(gssContext, storeCred); } finally { - if (!isUseContextClassLoader()) { - Thread.currentThread().setContextClassLoader(ocl); + if (currentThread != null) { + currentThread.setContextClassLoader(ocl); } } } @@ -1398,15 +1410,17 @@ public class JNDIRealm extends RealmBase { @Override public Principal authenticate(GSSName gssName, GSSCredential gssCredential) { ClassLoader ocl = null; + Thread currentThread = null; try { if (!isUseContextClassLoader()) { - ocl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + currentThread = Thread.currentThread(); + ocl = currentThread.getContextClassLoader(); + currentThread.setContextClassLoader(this.getClass().getClassLoader()); } return super.authenticate(gssName, gssCredential); } finally { - if (!isUseContextClassLoader()) { - Thread.currentThread().setContextClassLoader(ocl); + if (currentThread != null) { + currentThread.setContextClassLoader(ocl); } } } @@ -2721,6 +2735,7 @@ public class JNDIRealm extends RealmBase { // Check to see if the connection to the directory can be opened ClassLoader ocl = null; + Thread currentThread = null; JNDIConnection connection = null; try { // https://bz.apache.org/bugzilla/show_bug.cgi?id=65553 @@ -2728,8 +2743,9 @@ public class JNDIRealm extends RealmBase { // running on a JVM that includes a fix for // https://bugs.openjdk.java.net/browse/JDK-8273874 if (!isUseContextClassLoader()) { - ocl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + currentThread = Thread.currentThread(); + ocl = currentThread.getContextClassLoader(); + currentThread.setContextClassLoader(this.getClass().getClassLoader()); } connection = get(); } catch (NamingException e) { @@ -2740,8 +2756,8 @@ public class JNDIRealm extends RealmBase { containerLog.error(sm.getString("jndiRealm.open"), e); } finally { release(connection); - if (!isUseContextClassLoader()) { - Thread.currentThread().setContextClassLoader(ocl); + if (currentThread != null) { + currentThread.setContextClassLoader(ocl); } } diff --git a/java/org/apache/catalina/servlets/DefaultServlet.java b/java/org/apache/catalina/servlets/DefaultServlet.java index 49f55c88fe..18c3dd5fd3 100644 --- a/java/org/apache/catalina/servlets/DefaultServlet.java +++ b/java/org/apache/catalina/servlets/DefaultServlet.java @@ -1760,19 +1760,19 @@ public class DefaultServlet extends HttpServlet { // Prevent possible memory leak. Ensure Transformer and // TransformerFactory are not loaded from the web application. ClassLoader original; + Thread currentThread = Thread.currentThread(); if (Globals.IS_SECURITY_ENABLED) { - PrivilegedGetTccl pa = new PrivilegedGetTccl(); + PrivilegedGetTccl pa = new PrivilegedGetTccl(currentThread); original = AccessController.doPrivileged(pa); } else { - original = Thread.currentThread().getContextClassLoader(); + original = currentThread.getContextClassLoader(); } try { if (Globals.IS_SECURITY_ENABLED) { - PrivilegedSetTccl pa = - new PrivilegedSetTccl(DefaultServlet.class.getClassLoader()); + PrivilegedSetTccl pa = new PrivilegedSetTccl(currentThread, DefaultServlet.class.getClassLoader()); AccessController.doPrivileged(pa); } else { - Thread.currentThread().setContextClassLoader( + currentThread.setContextClassLoader( DefaultServlet.class.getClassLoader()); } @@ -1790,10 +1790,10 @@ public class DefaultServlet extends HttpServlet { throw new ServletException(sm.getString("defaultServlet.xslError"), e); } finally { if (Globals.IS_SECURITY_ENABLED) { - PrivilegedSetTccl pa = new PrivilegedSetTccl(original); + PrivilegedSetTccl pa = new PrivilegedSetTccl(currentThread, original); AccessController.doPrivileged(pa); } else { - Thread.currentThread().setContextClassLoader(original); + currentThread.setContextClassLoader(original); } } } diff --git a/java/org/apache/catalina/tribes/membership/McastServiceImpl.java b/java/org/apache/catalina/tribes/membership/McastServiceImpl.java index da42ac7ceb..acf1f60fc3 100644 --- a/java/org/apache/catalina/tribes/membership/McastServiceImpl.java +++ b/java/org/apache/catalina/tribes/membership/McastServiceImpl.java @@ -399,18 +399,19 @@ public class McastServiceImpl extends MembershipProviderBase { log.trace("Mcast receive ping from member " + m); } Runnable t = null; + Thread currentThread = Thread.currentThread(); if (Arrays.equals(m.getCommand(), Member.SHUTDOWN_PAYLOAD)) { if (log.isDebugEnabled()) { log.debug("Member has shutdown:" + m); } membership.removeMember(m); t = () -> { - String name = Thread.currentThread().getName(); + String name = currentThread.getName(); try { - Thread.currentThread().setName("Membership-MemberDisappeared"); + currentThread.setName("Membership-MemberDisappeared"); service.memberDisappeared(m); - }finally { - Thread.currentThread().setName(name); + } finally { + currentThread.setName(name); } }; } else if (membership.memberAlive(m)) { @@ -418,16 +419,16 @@ public class McastServiceImpl extends MembershipProviderBase { log.debug("Mcast add member " + m); } t = () -> { - String name = Thread.currentThread().getName(); + String name = currentThread.getName(); try { - Thread.currentThread().setName("Membership-MemberAdded"); + currentThread.setName("Membership-MemberAdded"); service.memberAdded(m); - }finally { - Thread.currentThread().setName(name); + } finally { + currentThread.setName(name); } }; - } //end if - if ( t != null ) { + } + if (t != null) { executor.execute(t); } } @@ -448,9 +449,10 @@ public class McastServiceImpl extends MembershipProviderBase { } } Runnable t = () -> { - String name = Thread.currentThread().getName(); + Thread currentThread = Thread.currentThread(); + String name = currentThread.getName(); try { - Thread.currentThread().setName("Membership-MemberAdded"); + currentThread.setName("Membership-MemberAdded"); for (ChannelData datum : data) { try { if (datum != null && !member.equals(datum.getAddress())) { @@ -466,8 +468,8 @@ public class McastServiceImpl extends MembershipProviderBase { log.error(sm.getString("mcastServiceImpl.unableReceive.broadcastMessage"), t1); } } - }finally { - Thread.currentThread().setName(name); + } finally { + currentThread.setName(name); } }; executor.execute(t); @@ -484,12 +486,13 @@ public class McastServiceImpl extends MembershipProviderBase { } try { Runnable t = () -> { - String name = Thread.currentThread().getName(); + Thread currentThread = Thread.currentThread(); + String name = currentThread.getName(); try { - Thread.currentThread().setName("Membership-MemberExpired"); + currentThread.setName("Membership-MemberExpired"); service.memberDisappeared(member); } finally { - Thread.currentThread().setName(name); + currentThread.setName(name); } }; executor.execute(t); diff --git a/java/org/apache/catalina/tribes/membership/StaticMembershipProvider.java b/java/org/apache/catalina/tribes/membership/StaticMembershipProvider.java index 250a37d136..a4406b94c6 100644 --- a/java/org/apache/catalina/tribes/membership/StaticMembershipProvider.java +++ b/java/org/apache/catalina/tribes/membership/StaticMembershipProvider.java @@ -159,12 +159,13 @@ public class StaticMembershipProvider extends MembershipProviderBase implements Member mbr = setupMember(member); if(membership.memberAlive(mbr)) { Runnable r = () -> { - String name = Thread.currentThread().getName(); + Thread currentThread = Thread.currentThread(); + String name = currentThread.getName(); try { - Thread.currentThread().setName("StaticMembership-memberAdded"); + currentThread.setName("StaticMembership-memberAdded"); membershipListener.memberAdded(mbr); } finally { - Thread.currentThread().setName(name); + currentThread.setName(name); } }; executor.execute(r); @@ -174,12 +175,13 @@ public class StaticMembershipProvider extends MembershipProviderBase implements protected void memberDisappeared(Member member) { membership.removeMember(member); Runnable r = () -> { - String name = Thread.currentThread().getName(); + Thread currentThread = Thread.currentThread(); + String name = currentThread.getName(); try { - Thread.currentThread().setName("StaticMembership-memberDisappeared"); + currentThread.setName("StaticMembership-memberDisappeared"); membershipListener.memberDisappeared(member); } finally { - Thread.currentThread().setName(name); + currentThread.setName(name); } }; executor.execute(r); diff --git a/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipProvider.java b/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipProvider.java index 8bab726f87..67300cc454 100644 --- a/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipProvider.java +++ b/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipProvider.java @@ -156,17 +156,18 @@ public abstract class CloudMembershipProvider extends MembershipProviderBase imp log.debug(message); } Runnable r = () -> { - String name = Thread.currentThread().getName(); + Thread currentThread = Thread.currentThread(); + String name = currentThread.getName(); try { String threadName = add ? "CloudMembership-memberAdded" : "CloudMembership-memberDisappeared"; - Thread.currentThread().setName(threadName); + currentThread.setName(threadName); if (add) { membershipListener.memberAdded(member); } else { membershipListener.memberDisappeared(member); } } finally { - Thread.currentThread().setName(name); + currentThread.setName(name); } }; executor.execute(r); diff --git a/java/org/apache/catalina/valves/StuckThreadDetectionValve.java b/java/org/apache/catalina/valves/StuckThreadDetectionValve.java index a75bc0fe26..33ae4fe639 100644 --- a/java/org/apache/catalina/valves/StuckThreadDetectionValve.java +++ b/java/org/apache/catalina/valves/StuckThreadDetectionValve.java @@ -173,13 +173,14 @@ public class StuckThreadDetectionValve extends ValveBase { // Keeping a reference to the thread object here does not prevent // GC'ing, as the reference is removed from the Map in the finally clause - Long key = Long.valueOf(Thread.currentThread().getId()); + Thread currentThread = Thread.currentThread(); + Long key = Long.valueOf(currentThread.getId()); StringBuffer requestUrl = request.getRequestURL(); if (request.getQueryString() != null) { requestUrl.append('?'); requestUrl.append(request.getQueryString()); } - MonitoredThread monitoredThread = new MonitoredThread(Thread.currentThread(), requestUrl.toString(), + MonitoredThread monitoredThread = new MonitoredThread(currentThread, requestUrl.toString(), interruptThreadThreshold > 0); activeThreads.put(key, monitoredThread); diff --git a/java/org/apache/coyote/AsyncStateMachine.java b/java/org/apache/coyote/AsyncStateMachine.java index 16d270b6f6..d2bcae1b0d 100644 --- a/java/org/apache/coyote/AsyncStateMachine.java +++ b/java/org/apache/coyote/AsyncStateMachine.java @@ -432,27 +432,28 @@ class AsyncStateMachine { // Execute the runnable using a container thread from the // Connector's thread pool. Use a wrapper to prevent a memory leak ClassLoader oldCL; + Thread currentThread = Thread.currentThread(); if (Constants.IS_SECURITY_ENABLED) { - PrivilegedAction<ClassLoader> pa = new PrivilegedGetTccl(); + PrivilegedAction<ClassLoader> pa = new PrivilegedGetTccl(currentThread); oldCL = AccessController.doPrivileged(pa); } else { - oldCL = Thread.currentThread().getContextClassLoader(); + oldCL = currentThread.getContextClassLoader(); } try { if (Constants.IS_SECURITY_ENABLED) { - PrivilegedAction<Void> pa = new PrivilegedSetTccl(this.getClass().getClassLoader()); + PrivilegedAction<Void> pa = new PrivilegedSetTccl(currentThread, this.getClass().getClassLoader()); AccessController.doPrivileged(pa); } else { - Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + currentThread.setContextClassLoader(this.getClass().getClassLoader()); } processor.execute(runnable); } finally { if (Constants.IS_SECURITY_ENABLED) { - PrivilegedAction<Void> pa = new PrivilegedSetTccl(oldCL); + PrivilegedAction<Void> pa = new PrivilegedSetTccl(currentThread, oldCL); AccessController.doPrivileged(pa); } else { - Thread.currentThread().setContextClassLoader(oldCL); + currentThread.setContextClassLoader(oldCL); } } } else { diff --git a/java/org/apache/jasper/JspC.java b/java/org/apache/jasper/JspC.java index 4de189caaf..33b7825e32 100644 --- a/java/org/apache/jasper/JspC.java +++ b/java/org/apache/jasper/JspC.java @@ -1331,6 +1331,7 @@ public class JspC extends Task implements Options { } ClassLoader originalClassLoader = null; + Thread currentThread = Thread.currentThread(); try { // set up a scratch/output dir if none is provided @@ -1355,8 +1356,8 @@ public class JspC extends Task implements Options { clctxt.setBasePackageName(targetPackage); } - originalClassLoader = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(loader); + originalClassLoader = currentThread.getContextClassLoader(); + currentThread.setContextClassLoader(loader); clctxt.setClassLoader(loader); clctxt.setClassPath(classPath); @@ -1400,8 +1401,8 @@ public class JspC extends Task implements Options { } throw new JasperException(e); } finally { - if(originalClassLoader != null) { - Thread.currentThread().setContextClassLoader(originalClassLoader); + if (originalClassLoader != null) { + currentThread.setContextClassLoader(originalClassLoader); } } } diff --git a/java/org/apache/jasper/compiler/ELFunctionMapper.java b/java/org/apache/jasper/compiler/ELFunctionMapper.java index 5ec20ef0d7..99a79d0b7e 100644 --- a/java/org/apache/jasper/compiler/ELFunctionMapper.java +++ b/java/org/apache/jasper/compiler/ELFunctionMapper.java @@ -311,11 +311,12 @@ public class ELFunctionMapper { Class<?> clazz; ClassLoader tccl; + Thread currentThread = Thread.currentThread(); if (Constants.IS_SECURITY_ENABLED) { - PrivilegedAction<ClassLoader> pa = new PrivilegedGetTccl(); + PrivilegedAction<ClassLoader> pa = new PrivilegedGetTccl(currentThread); tccl = AccessController.doPrivileged(pa); } else { - tccl = Thread.currentThread().getContextClassLoader(); + tccl = currentThread.getContextClassLoader(); } try { diff --git a/java/org/apache/jasper/compiler/JspDocumentParser.java b/java/org/apache/jasper/compiler/JspDocumentParser.java index 0ad4774b14..54160b3187 100644 --- a/java/org/apache/jasper/compiler/JspDocumentParser.java +++ b/java/org/apache/jasper/compiler/JspDocumentParser.java @@ -1455,20 +1455,19 @@ class JspDocumentParser throws Exception { ClassLoader original; + Thread currentThread = Thread.currentThread(); if (Constants.IS_SECURITY_ENABLED) { - PrivilegedGetTccl pa = new PrivilegedGetTccl(); + PrivilegedGetTccl pa = new PrivilegedGetTccl(currentThread); original = AccessController.doPrivileged(pa); } else { - original = Thread.currentThread().getContextClassLoader(); + original = currentThread.getContextClassLoader(); } try { if (Constants.IS_SECURITY_ENABLED) { - PrivilegedSetTccl pa = - new PrivilegedSetTccl(JspDocumentParser.class.getClassLoader()); + PrivilegedSetTccl pa = new PrivilegedSetTccl(currentThread, JspDocumentParser.class.getClassLoader()); AccessController.doPrivileged(pa); } else { - Thread.currentThread().setContextClassLoader( - JspDocumentParser.class.getClassLoader()); + currentThread.setContextClassLoader(JspDocumentParser.class.getClassLoader()); } SAXParserFactory factory = SAXParserFactory.newInstance(); @@ -1500,10 +1499,10 @@ class JspDocumentParser return saxParser; } finally { if (Constants.IS_SECURITY_ENABLED) { - PrivilegedSetTccl pa = new PrivilegedSetTccl(original); + PrivilegedSetTccl pa = new PrivilegedSetTccl(currentThread, original); AccessController.doPrivileged(pa); } else { - Thread.currentThread().setContextClassLoader(original); + currentThread.setContextClassLoader(original); } } } diff --git a/java/org/apache/jasper/compiler/TagPluginManager.java b/java/org/apache/jasper/compiler/TagPluginManager.java index 9b830c8427..3e95ed80f9 100644 --- a/java/org/apache/jasper/compiler/TagPluginManager.java +++ b/java/org/apache/jasper/compiler/TagPluginManager.java @@ -77,20 +77,19 @@ public class TagPluginManager { TagPluginParser parser; ClassLoader original; + Thread currentThread = Thread.currentThread(); if (Constants.IS_SECURITY_ENABLED) { - PrivilegedGetTccl pa = new PrivilegedGetTccl(); + PrivilegedGetTccl pa = new PrivilegedGetTccl(currentThread); original = AccessController.doPrivileged(pa); } else { - original = Thread.currentThread().getContextClassLoader(); + original = currentThread.getContextClassLoader(); } try { if (Constants.IS_SECURITY_ENABLED) { - PrivilegedSetTccl pa = - new PrivilegedSetTccl(TagPluginManager.class.getClassLoader()); + PrivilegedSetTccl pa = new PrivilegedSetTccl(currentThread, TagPluginManager.class.getClassLoader()); AccessController.doPrivileged(pa); } else { - Thread.currentThread().setContextClassLoader( - TagPluginManager.class.getClassLoader()); + currentThread.setContextClassLoader(TagPluginManager.class.getClassLoader()); } parser = new TagPluginParser(ctxt, blockExternal); @@ -110,10 +109,10 @@ public class TagPluginManager { throw new JasperException(e); } finally { if (Constants.IS_SECURITY_ENABLED) { - PrivilegedSetTccl pa = new PrivilegedSetTccl(original); + PrivilegedSetTccl pa = new PrivilegedSetTccl(currentThread, original); AccessController.doPrivileged(pa); } else { - Thread.currentThread().setContextClassLoader(original); + currentThread.setContextClassLoader(original); } } diff --git a/java/org/apache/naming/ContextBindings.java b/java/org/apache/naming/ContextBindings.java index baf3ce2bdb..9c4895acc2 100644 --- a/java/org/apache/naming/ContextBindings.java +++ b/java/org/apache/naming/ContextBindings.java @@ -142,8 +142,9 @@ public class ContextBindings { throw new NamingException( sm.getString("contextBindings.unknownContext", obj)); } - threadBindings.put(Thread.currentThread(), context); - threadObjectBindings.put(Thread.currentThread(), obj); + Thread currentThread = Thread.currentThread(); + threadBindings.put(currentThread, context); + threadObjectBindings.put(currentThread, obj); } } @@ -156,8 +157,9 @@ public class ContextBindings { */ public static void unbindThread(Object obj, Object token) { if (ContextAccessController.checkSecurityToken(obj, token)) { - threadBindings.remove(Thread.currentThread()); - threadObjectBindings.remove(Thread.currentThread()); + Thread currentThread = Thread.currentThread(); + threadBindings.remove(currentThread); + threadObjectBindings.remove(currentThread); } } diff --git a/java/org/apache/tomcat/util/descriptor/tld/TldParser.java b/java/org/apache/tomcat/util/descriptor/tld/TldParser.java index e31c2fea58..933a13c1ca 100644 --- a/java/org/apache/tomcat/util/descriptor/tld/TldParser.java +++ b/java/org/apache/tomcat/util/descriptor/tld/TldParser.java @@ -52,18 +52,19 @@ public class TldParser { public TaglibXml parse(TldResourcePath path) throws IOException, SAXException { ClassLoader original; + Thread currentThread = Thread.currentThread(); if (Constants.IS_SECURITY_ENABLED) { - PrivilegedGetTccl pa = new PrivilegedGetTccl(); + PrivilegedGetTccl pa = new PrivilegedGetTccl(currentThread); original = AccessController.doPrivileged(pa); } else { - original = Thread.currentThread().getContextClassLoader(); + original = currentThread.getContextClassLoader(); } try (InputStream is = path.openStream()) { if (Constants.IS_SECURITY_ENABLED) { - PrivilegedSetTccl pa = new PrivilegedSetTccl(TldParser.class.getClassLoader()); + PrivilegedSetTccl pa = new PrivilegedSetTccl(currentThread, TldParser.class.getClassLoader()); AccessController.doPrivileged(pa); } else { - Thread.currentThread().setContextClassLoader(TldParser.class.getClassLoader()); + currentThread.setContextClassLoader(TldParser.class.getClassLoader()); } XmlErrorHandler handler = new XmlErrorHandler(); digester.setErrorHandler(handler); @@ -85,10 +86,10 @@ public class TldParser { } finally { digester.reset(); if (Constants.IS_SECURITY_ENABLED) { - PrivilegedSetTccl pa = new PrivilegedSetTccl(original); + PrivilegedSetTccl pa = new PrivilegedSetTccl(currentThread, original); AccessController.doPrivileged(pa); } else { - Thread.currentThread().setContextClassLoader(original); + currentThread.setContextClassLoader(original); } } } diff --git a/java/org/apache/tomcat/util/security/PrivilegedGetTccl.java b/java/org/apache/tomcat/util/security/PrivilegedGetTccl.java index 11d11a8602..c580cfab50 100644 --- a/java/org/apache/tomcat/util/security/PrivilegedGetTccl.java +++ b/java/org/apache/tomcat/util/security/PrivilegedGetTccl.java @@ -19,10 +19,19 @@ package org.apache.tomcat.util.security; import java.security.PrivilegedAction; public class PrivilegedGetTccl implements PrivilegedAction<ClassLoader> { + private final Thread currentThread; + + @Deprecated + public PrivilegedGetTccl() { + this(Thread.currentThread()); + } + + public PrivilegedGetTccl(Thread currentThread) { + this.currentThread = currentThread; + } + @Override public ClassLoader run() { - return Thread.currentThread().getContextClassLoader(); + return currentThread.getContextClassLoader(); } } - - diff --git a/java/org/apache/tomcat/util/security/PrivilegedSetTccl.java b/java/org/apache/tomcat/util/security/PrivilegedSetTccl.java index 739d915794..188a8ae08e 100644 --- a/java/org/apache/tomcat/util/security/PrivilegedSetTccl.java +++ b/java/org/apache/tomcat/util/security/PrivilegedSetTccl.java @@ -23,6 +23,7 @@ public class PrivilegedSetTccl implements PrivilegedAction<Void> { private final ClassLoader cl; private final Thread t; + @Deprecated public PrivilegedSetTccl(ClassLoader cl) { this(Thread.currentThread(), cl); } diff --git a/java/org/apache/tomcat/util/threads/ThreadPoolExecutor.java b/java/org/apache/tomcat/util/threads/ThreadPoolExecutor.java index 3de34cb387..7ea4c91ad7 100644 --- a/java/org/apache/tomcat/util/threads/ThreadPoolExecutor.java +++ b/java/org/apache/tomcat/util/threads/ThreadPoolExecutor.java @@ -2222,9 +2222,9 @@ public class ThreadPoolExecutor extends AbstractExecutorService { protected boolean currentThreadShouldBeStopped() { - if (threadRenewalDelay >= 0 - && Thread.currentThread() instanceof TaskThread) { - TaskThread currentTaskThread = (TaskThread) Thread.currentThread(); + Thread currentThread = Thread.currentThread(); + if (threadRenewalDelay >= 0 && currentThread instanceof TaskThread) { + TaskThread currentTaskThread = (TaskThread) currentThread; if (currentTaskThread.getCreationTime() < this.lastContextStoppedTime.longValue()) { return true; diff --git a/java/org/apache/tomcat/websocket/AsyncChannelGroupUtil.java b/java/org/apache/tomcat/websocket/AsyncChannelGroupUtil.java index dd688db273..6bf48ed076 100644 --- a/java/org/apache/tomcat/websocket/AsyncChannelGroupUtil.java +++ b/java/org/apache/tomcat/websocket/AsyncChannelGroupUtil.java @@ -74,11 +74,11 @@ public class AsyncChannelGroupUtil { private static AsynchronousChannelGroup createAsynchronousChannelGroup() { // Need to do this with the right thread context class loader else the // first web app to call this will trigger a leak - ClassLoader original = Thread.currentThread().getContextClassLoader(); + Thread currentThread = Thread.currentThread(); + ClassLoader original = currentThread.getContextClassLoader(); try { - Thread.currentThread().setContextClassLoader( - AsyncIOThreadFactory.class.getClassLoader()); + currentThread.setContextClassLoader(AsyncIOThreadFactory.class.getClassLoader()); // These are the same settings as the default // AsynchronousChannelGroup @@ -98,7 +98,7 @@ public class AsyncChannelGroupUtil { throw new IllegalStateException(sm.getString("asyncChannelGroup.createFail")); } } finally { - Thread.currentThread().setContextClassLoader(original); + currentThread.setContextClassLoader(original); } } diff --git a/java/org/apache/tomcat/websocket/server/WsFrameServer.java b/java/org/apache/tomcat/websocket/server/WsFrameServer.java index d29ea047aa..c40ae31095 100644 --- a/java/org/apache/tomcat/websocket/server/WsFrameServer.java +++ b/java/org/apache/tomcat/websocket/server/WsFrameServer.java @@ -123,24 +123,26 @@ public class WsFrameServer extends WsFrameBase { @Override protected void sendMessageText(boolean last) throws WsIOException { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Thread currentThread = Thread.currentThread(); + ClassLoader cl = currentThread.getContextClassLoader(); try { - Thread.currentThread().setContextClassLoader(applicationClassLoader); + currentThread.setContextClassLoader(applicationClassLoader); super.sendMessageText(last); } finally { - Thread.currentThread().setContextClassLoader(cl); + currentThread.setContextClassLoader(cl); } } @Override protected void sendMessageBinary(ByteBuffer msg, boolean last) throws WsIOException { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Thread currentThread = Thread.currentThread(); + ClassLoader cl = currentThread.getContextClassLoader(); try { - Thread.currentThread().setContextClassLoader(applicationClassLoader); + currentThread.setContextClassLoader(applicationClassLoader); super.sendMessageBinary(msg, last); } finally { - Thread.currentThread().setContextClassLoader(cl); + currentThread.setContextClassLoader(cl); } } diff --git a/test/org/apache/catalina/loader/TestWebappClassLoaderExecutorMemoryLeak.java b/test/org/apache/catalina/loader/TestWebappClassLoaderExecutorMemoryLeak.java index 6a1775041c..0481afdc8d 100644 --- a/test/org/apache/catalina/loader/TestWebappClassLoaderExecutorMemoryLeak.java +++ b/test/org/apache/catalina/loader/TestWebappClassLoaderExecutorMemoryLeak.java @@ -114,16 +114,15 @@ public class TestWebappClassLoaderExecutorMemoryLeak extends TomcatBaseTest { @Override public void run() { + Thread currentThread = Thread.currentThread(); try { - while (!Thread.currentThread().isInterrupted()) { + while (!currentThread.isInterrupted()) { Thread.sleep(20000); - System.out.println(Thread.currentThread().getClass() - + " [" + Thread.currentThread().getName() - + "] executing " + this._id); + System.out.println( + currentThread.getClass() + " [" + currentThread.getName() + "] executing " + this._id); } } catch (InterruptedException e) { - System.out.println(Thread.currentThread().getClass() + " [" - + Thread.currentThread().getName() + "] EXITING"); + System.out.println(currentThread.getClass() + " [" + currentThread.getName() + "] EXITING"); } } } diff --git a/test/org/apache/catalina/startup/TestTomcatClassLoader.java b/test/org/apache/catalina/startup/TestTomcatClassLoader.java index e9292173d5..d1df88c356 100644 --- a/test/org/apache/catalina/startup/TestTomcatClassLoader.java +++ b/test/org/apache/catalina/startup/TestTomcatClassLoader.java @@ -54,10 +54,9 @@ public class TestTomcatClassLoader extends TomcatBaseTest { @Test public void testNonDefaultClassLoader() throws Exception { - ClassLoader cl = new URLClassLoader(new URL[0], - Thread.currentThread().getContextClassLoader()); - - Thread.currentThread().setContextClassLoader(cl); + Thread currentThread = Thread.currentThread(); + ClassLoader cl = new URLClassLoader(new URL[0], currentThread.getContextClassLoader()); + currentThread.setContextClassLoader(cl); Tomcat tomcat = getTomcatInstance(); tomcat.getServer().setParentClassLoader(cl); diff --git a/test/org/apache/juli/TestClassLoaderLogManager.java b/test/org/apache/juli/TestClassLoaderLogManager.java index 674600edf4..b2482af790 100644 --- a/test/org/apache/juli/TestClassLoaderLogManager.java +++ b/test/org/apache/juli/TestClassLoaderLogManager.java @@ -93,9 +93,10 @@ public class TestClassLoaderLogManager { @Test public void testBug66184() throws IOException { final ClassLoader cl = new TestClassLoader(); - final ClassLoader oldCL = Thread.currentThread().getContextClassLoader(); + final Thread currentThread = Thread.currentThread(); + final ClassLoader oldCL = currentThread.getContextClassLoader(); try { - Thread.currentThread().setContextClassLoader(cl); + currentThread.setContextClassLoader(cl); final ClassLoaderLogManager logManager = new ClassLoaderLogManager(); logManager.readConfiguration(); final Logger rootLogger = logManager.getLogger(""); @@ -103,7 +104,7 @@ public class TestClassLoaderLogManager { Assert.assertNull("root logger has a parent", rootLogger.getParent()); Assert.assertEquals(Level.INFO, rootLogger.getLevel()); } finally { - Thread.currentThread().setContextClassLoader(oldCL); + currentThread.setContextClassLoader(oldCL); } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org