You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2015/11/23 17:19:33 UTC

svn commit: r1715866 - in /tomcat/trunk: java/org/apache/catalina/ java/org/apache/catalina/connector/ java/org/apache/coyote/ java/org/apache/coyote/http11/ java/org/apache/coyote/http11/upgrade/ java/org/apache/coyote/http2/ java/org/apache/tomcat/ w...

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org