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