Author: remm Date: Mon Nov 23 16:19:33 2015 New Revision: 1715866 URL: http://svn.apache.org/viewvc?rev=1715866&view=rev Log: Extract Context.bind and unbind to an interface to make the CL bind cleaner for the upgrade code (including using a PA if needed).
Added: tomcat/trunk/java/org/apache/tomcat/ContextBind.java (with props) Modified: tomcat/trunk/java/org/apache/catalina/Context.java tomcat/trunk/java/org/apache/catalina/connector/Request.java tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java tomcat/trunk/java/org/apache/coyote/UpgradeToken.java tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/catalina/Context.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Context.java?rev=1715866&r1=1715865&r2=1715866&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/Context.java (original) +++ tomcat/trunk/java/org/apache/catalina/Context.java Mon Nov 23 16:19:33 2015 @@ -29,6 +29,7 @@ import javax.servlet.ServletSecurityElem import javax.servlet.descriptor.JspConfigDescriptor; import org.apache.catalina.deploy.NamingResourcesImpl; +import org.apache.tomcat.ContextBind; import org.apache.tomcat.InstanceManager; import org.apache.tomcat.JarScanner; import org.apache.tomcat.util.descriptor.web.ApplicationParameter; @@ -57,7 +58,7 @@ import org.apache.tomcat.util.http.Cooki * * @author Craig R. McClanahan */ -public interface Context extends Container { +public interface Context extends Container, ContextBind { // ----------------------------------------------------- Manifest Constants @@ -1626,45 +1627,6 @@ public interface Context extends Contain public Map<String, String> findPreDestroyMethods(); /** - * Change the current thread context class loader to the web application - * class loader. If no web application class loader is defined, or if the - * current thread is already using the web application class loader then no - * change will be made. If the class loader is changed and a - * {@link ThreadBindingListener} is configured then - * {@link ThreadBindingListener#bind()} will be called after the change has - * been made. - * - * @param usePrivilegedAction - * Should a {@link java.security.PrivilegedAction} be used when - * obtaining the current thread context class loader and setting - * the new one? - * @param originalClassLoader - * The current class loader if known to save this method having to - * look it up - * - * @return If the class loader has been changed by the method it will return - * the thread context class loader in use when the method was - * called. If no change was made then this method returns null. - */ - public ClassLoader bind(boolean usePrivilegedAction, ClassLoader originalClassLoader); - - /** - * Restore the current thread context class loader to the original class - * loader in used before {@link #bind(boolean, ClassLoader)} was called. If - * no original class loader is passed to this method then no change will be - * made. If the class loader is changed and a {@link ThreadBindingListener} - * is configured then {@link ThreadBindingListener#unbind()} will be called - * before the change is made. - * - * @param usePrivilegedAction - * Should a {@link java.security.PrivilegedAction} be used when - * setting the current thread context class loader? - * @param originalClassLoader - * The class loader to restore as the thread context class loader - */ - public void unbind(boolean usePrivilegedAction, ClassLoader originalClassLoader); - - /** * Obtain the token necessary for operations on the associated JNDI naming * context. */ Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=1715866&r1=1715865&r2=1715866&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Mon Nov 23 16:19:33 2015 @@ -1865,7 +1865,7 @@ public class Request implements HttpServ throw new ServletException(e); } UpgradeToken upgradeToken = new UpgradeToken(handler, - getContext().getLoader().getClassLoader(), instanceManager); + getContext(), instanceManager); coyoteRequest.action(ActionCode.UPGRADE, upgradeToken); Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1715866&r1=1715865&r2=1715866&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java Mon Nov 23 16:19:33 2015 @@ -780,14 +780,11 @@ public abstract class AbstractProtocol<S if (upgradeToken.getInstanceManager() == null) { httpUpgradeHandler.init((WebConnection) processor); } else { - Thread thread = Thread.currentThread(); - // Set context class loader environment for user class call - ClassLoader originalClassLoader = thread.getContextClassLoader(); + ClassLoader oldCL = upgradeToken.getContextBind().bind(false, null); try { - thread.setContextClassLoader(upgradeToken.getApplicationClassLoader()); httpUpgradeHandler.init((WebConnection) processor); } finally { - thread.setContextClassLoader(originalClassLoader); + upgradeToken.getContextBind().unbind(false, oldCL); } } } @@ -833,15 +830,12 @@ public abstract class AbstractProtocol<S if (instanceManager == null) { httpUpgradeHandler.destroy(); } else { - Thread thread = Thread.currentThread(); - // Set context class loader environment for user class call - ClassLoader originalClassLoader = thread.getContextClassLoader(); + ClassLoader oldCL = upgradeToken.getContextBind().bind(false, null); try { - thread.setContextClassLoader(upgradeToken.getApplicationClassLoader()); httpUpgradeHandler.destroy(); instanceManager.destroyInstance(httpUpgradeHandler); } finally { - thread.setContextClassLoader(originalClassLoader); + upgradeToken.getContextBind().unbind(false, oldCL); } } } else { Modified: tomcat/trunk/java/org/apache/coyote/UpgradeToken.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/UpgradeToken.java?rev=1715866&r1=1715865&r2=1715866&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/UpgradeToken.java (original) +++ tomcat/trunk/java/org/apache/coyote/UpgradeToken.java Mon Nov 23 16:19:33 2015 @@ -19,6 +19,7 @@ package org.apache.coyote; import javax.servlet.http.HttpUpgradeHandler; +import org.apache.tomcat.ContextBind; import org.apache.tomcat.InstanceManager; /** @@ -26,19 +27,19 @@ import org.apache.tomcat.InstanceManager */ public final class UpgradeToken { - private final ClassLoader applicationClassLoader; + private final ContextBind contextBind; private final HttpUpgradeHandler httpUpgradeHandler; private final InstanceManager instanceManager; public UpgradeToken(HttpUpgradeHandler httpUpgradeHandler, - ClassLoader applicationClassLoader, InstanceManager instanceManager) { - this.applicationClassLoader = applicationClassLoader; + ContextBind contextBind, InstanceManager instanceManager) { + this.contextBind = contextBind; this.httpUpgradeHandler = httpUpgradeHandler; this.instanceManager = instanceManager; } - public final ClassLoader getApplicationClassLoader() { - return applicationClassLoader; + public final ContextBind getContextBind() { + return contextBind; } public final HttpUpgradeHandler getHttpUpgradeHandler() { Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=1715866&r1=1715865&r2=1715866&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Mon Nov 23 16:19:33 2015 @@ -1041,8 +1041,7 @@ public class Http11Processor extends Abs InternalHttpUpgradeHandler upgradeHandler = upgradeProtocol.getInternalUpgradeHandler( getAdapter(), cloneRequest(request)); - UpgradeToken upgradeToken = new UpgradeToken( - upgradeHandler, Http11Processor.class.getClassLoader(), null); + UpgradeToken upgradeToken = new UpgradeToken(upgradeHandler, null, null); action(ActionCode.UPGRADE, upgradeToken); return SocketState.UPGRADING; } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java?rev=1715866&r1=1715865&r2=1715866&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java Mon Nov 23 16:19:33 2015 @@ -206,10 +206,8 @@ public class UpgradeServletInputStream e return; } ready = Boolean.TRUE; - Thread thread = Thread.currentThread(); - ClassLoader originalClassLoader = thread.getContextClassLoader(); + ClassLoader oldCL = processor.getUpgradeToken().getContextBind().bind(false, null); try { - thread.setContextClassLoader(processor.getUpgradeToken().getApplicationClassLoader()); if (!eof) { listener.onDataAvailable(); } @@ -220,7 +218,7 @@ public class UpgradeServletInputStream e ExceptionUtils.handleThrowable(t); onError(t); } finally { - thread.setContextClassLoader(originalClassLoader); + processor.getUpgradeToken().getContextBind().unbind(false, oldCL); } } @@ -229,16 +227,14 @@ public class UpgradeServletInputStream e if (listener == null) { return; } - Thread thread = Thread.currentThread(); - ClassLoader originalClassLoader = thread.getContextClassLoader(); + ClassLoader oldCL = processor.getUpgradeToken().getContextBind().bind(false, null); try { - thread.setContextClassLoader(processor.getUpgradeToken().getApplicationClassLoader()); listener.onError(t); } catch (Throwable t2) { ExceptionUtils.handleThrowable(t2); log.warn(sm.getString("upgrade.sis.onErrorFail"), t2); } finally { - thread.setContextClassLoader(originalClassLoader); + processor.getUpgradeToken().getContextBind().unbind(false, oldCL); } try { close(); Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java?rev=1715866&r1=1715865&r2=1715866&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java Mon Nov 23 16:19:33 2015 @@ -245,16 +245,14 @@ public class UpgradeServletOutputStream } if (fire) { - Thread thread = Thread.currentThread(); - ClassLoader originalClassLoader = thread.getContextClassLoader(); + ClassLoader oldCL = processor.getUpgradeToken().getContextBind().bind(false, null); try { - thread.setContextClassLoader(processor.getUpgradeToken().getApplicationClassLoader()); listener.onWritePossible(); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); onError(t); } finally { - thread.setContextClassLoader(originalClassLoader); + processor.getUpgradeToken().getContextBind().unbind(false, oldCL); } } } @@ -264,16 +262,14 @@ public class UpgradeServletOutputStream if (listener == null) { return; } - Thread thread = Thread.currentThread(); - ClassLoader originalClassLoader = thread.getContextClassLoader(); + ClassLoader oldCL = processor.getUpgradeToken().getContextBind().bind(false, null); try { - thread.setContextClassLoader(processor.getUpgradeToken().getApplicationClassLoader()); listener.onError(t); } catch (Throwable t2) { ExceptionUtils.handleThrowable(t2); log.warn(sm.getString("upgrade.sos.onErrorFail"), t2); } finally { - thread.setContextClassLoader(originalClassLoader); + processor.getUpgradeToken().getContextBind().unbind(false, oldCL); } try { close(); Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java?rev=1715866&r1=1715865&r2=1715866&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java Mon Nov 23 16:19:33 2015 @@ -73,7 +73,7 @@ public class Http2Protocol implements Up @Override public Processor getProcessor(SocketWrapperBase<?> socketWrapper, Adapter adapter) { UpgradeProcessorInternal processor = new UpgradeProcessorInternal(socketWrapper, null, - new UpgradeToken(getInternalUpgradeHandler(adapter, null), Http2Protocol.class.getClassLoader(), null)); + new UpgradeToken(getInternalUpgradeHandler(adapter, null), null, null)); return processor; } Added: tomcat/trunk/java/org/apache/tomcat/ContextBind.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/ContextBind.java?rev=1715866&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/ContextBind.java (added) +++ tomcat/trunk/java/org/apache/tomcat/ContextBind.java Mon Nov 23 16:19:33 2015 @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat; + +public interface ContextBind { + + /** + * Change the current thread context class loader to the web application + * class loader. If no web application class loader is defined, or if the + * current thread is already using the web application class loader then no + * change will be made. If the class loader is changed and a + * {@link ThreadBindingListener} is configured then + * {@link ThreadBindingListener#bind()} will be called after the change has + * been made. + * + * @param usePrivilegedAction + * Should a {@link java.security.PrivilegedAction} be used when + * obtaining the current thread context class loader and setting + * the new one? + * @param originalClassLoader + * The current class loader if known to save this method having to + * look it up + * + * @return If the class loader has been changed by the method it will return + * the thread context class loader in use when the method was + * called. If no change was made then this method returns null. + */ + public ClassLoader bind(boolean usePrivilegedAction, ClassLoader originalClassLoader); + + /** + * Restore the current thread context class loader to the original class + * loader in used before {@link #bind(boolean, ClassLoader)} was called. If + * no original class loader is passed to this method then no change will be + * made. If the class loader is changed and a {@link ThreadBindingListener} + * is configured then {@link ThreadBindingListener#unbind()} will be called + * before the change is made. + * + * @param usePrivilegedAction + * Should a {@link java.security.PrivilegedAction} be used when + * setting the current thread context class loader? + * @param originalClassLoader + * The class loader to restore as the thread context class loader + */ + public void unbind(boolean usePrivilegedAction, ClassLoader originalClassLoader); + +} Propchange: tomcat/trunk/java/org/apache/tomcat/ContextBind.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1715866&r1=1715865&r2=1715866&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Mon Nov 23 16:19:33 2015 @@ -98,6 +98,10 @@ OpenSSL. Both could be allowed, but it would likely create support issues. This type is used by the OpenSSL implementation for NIOx. (remm) </fix> + <fix> + Improve upgrade context classloader handling by using Context.bind and + unbind. (remm) + </fix> </changelog> </subsection> <subsection name="Cluster"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org