Author: markt Date: Wed Jan 12 18:13:11 2011 New Revision: 1058259 URL: http://svn.apache.org/viewvc?rev=1058259&view=rev Log: Better class loader control when embedding
Added: tomcat/trunk/test/org/apache/catalina/startup/TestTomcatClassLoader.java (with props) Modified: tomcat/trunk/java/org/apache/catalina/Container.java tomcat/trunk/java/org/apache/catalina/Server.java tomcat/trunk/java/org/apache/catalina/Service.java tomcat/trunk/java/org/apache/catalina/core/StandardServer.java tomcat/trunk/java/org/apache/catalina/core/StandardService.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/catalina/Container.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Container.java?rev=1058259&r1=1058258&r2=1058259&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/Container.java (original) +++ tomcat/trunk/java/org/apache/catalina/Container.java Wed Jan 12 18:13:11 2011 @@ -282,14 +282,16 @@ public interface Container extends Lifec /** - * Return the parent class loader (if any) for web applications. + * Return the parent class loader for this component. If not set, return + * {...@link Container#getParent()#getParentClassLoader()}. If no parent has + * been set, return the system class loader. */ public ClassLoader getParentClassLoader(); /** - * Set the parent class loader (if any) for web applications. - * This call is meaningful only <strong>before</strong> a Loader has + * Set the parent class loader for this component. For {...@link Context}s + * this call is meaningful only <strong>before</strong> a Loader has * been configured, and the specified value (if non-null) should be * passed as an argument to the class loader constructor. * Modified: tomcat/trunk/java/org/apache/catalina/Server.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Server.java?rev=1058259&r1=1058258&r2=1058259&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/Server.java (original) +++ tomcat/trunk/java/org/apache/catalina/Server.java Wed Jan 12 18:13:11 2011 @@ -118,10 +118,20 @@ public interface Server extends Lifecycl /** - * Return the parent class loader. + * Return the parent class loader for this component. If not set, return + * {...@link Server#getCatalina()#getParentClassLoader(). If no catalina has + * been set, return the system class loader. */ public ClassLoader getParentClassLoader(); + + /** + * Set the parent class loader for this server. + * + * @param parent The new parent class loader + */ + public void setParentClassLoader(ClassLoader parent); + /** * Return the outer Catalina startup/shutdown component if present. Modified: tomcat/trunk/java/org/apache/catalina/Service.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Service.java?rev=1058259&r1=1058258&r2=1058259&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/Service.java (original) +++ tomcat/trunk/java/org/apache/catalina/Service.java Wed Jan 12 18:13:11 2011 @@ -85,10 +85,19 @@ public interface Service extends Lifecyc public void setServer(Server server); /** - * Return the parent class loader. + * Return the parent class loader for this component. If not set, return + * {...@link Service#getServer()#getParentClassLoader(). If no server has + * been set, return the system class loader. */ public ClassLoader getParentClassLoader(); - + + /** + * Set the parent class loader for this service. + * + * @param parent The new parent class loader + */ + public void setParentClassLoader(ClassLoader parent); + // --------------------------------------------------------- Public Methods Modified: tomcat/trunk/java/org/apache/catalina/core/StandardServer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardServer.java?rev=1058259&r1=1058258&r2=1058259&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/StandardServer.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/StandardServer.java Wed Jan 12 18:13:11 2011 @@ -14,11 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - - package org.apache.catalina.core; - import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.io.IOException; @@ -56,8 +53,7 @@ import org.apache.tomcat.util.res.String * @author Craig R. McClanahan * @version $Id$ */ -public final class StandardServer extends LifecycleMBeanBase - implements Server { +public final class StandardServer extends LifecycleMBeanBase implements Server { private static final Log log = LogFactory.getLog(StandardServer.class); @@ -159,6 +155,8 @@ public final class StandardServer extend private Catalina catalina = null; + private ClassLoader parentClassLoader = null; + // ------------------------------------------------------------- Properties @@ -751,12 +749,28 @@ public final class StandardServer extend */ @Override public ClassLoader getParentClassLoader() { + if (parentClassLoader != null) + return (parentClassLoader); if (catalina != null) { return (catalina.getParentClassLoader()); } return (ClassLoader.getSystemClassLoader()); } + /** + * Set the parent class loader for this server. + * + * @param parent The new parent class loader + */ + @Override + public void setParentClassLoader(ClassLoader parent) { + ClassLoader oldParentClassLoader = this.parentClassLoader; + this.parentClassLoader = parent; + support.firePropertyChange("parentClassLoader", oldParentClassLoader, + this.parentClassLoader); + } + + private ObjectName onameStringCache; private ObjectName onameMBeanFactory; private ObjectName onameNamingResoucres; Modified: tomcat/trunk/java/org/apache/catalina/core/StandardService.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardService.java?rev=1058259&r1=1058258&r2=1058259&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/StandardService.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/StandardService.java Wed Jan 12 18:13:11 2011 @@ -103,6 +103,7 @@ public class StandardService extends Lif */ protected Container container = null; + private ClassLoader parentClassLoader = null; // ------------------------------------------------------------- Properties @@ -600,12 +601,26 @@ public class StandardService extends Lif */ @Override public ClassLoader getParentClassLoader() { + if (parentClassLoader != null) + return (parentClassLoader); if (server != null) { return (server.getParentClassLoader()); } return (ClassLoader.getSystemClassLoader()); } + /** + * Set the parent class loader for this server. + * + * @param parent The new parent class loader + */ + @Override + public void setParentClassLoader(ClassLoader parent) { + ClassLoader oldParentClassLoader = this.parentClassLoader; + this.parentClassLoader = parent; + support.firePropertyChange("parentClassLoader", oldParentClassLoader, + this.parentClassLoader); + } @Override protected String getDomainInternal() { Added: tomcat/trunk/test/org/apache/catalina/startup/TestTomcatClassLoader.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/startup/TestTomcatClassLoader.java?rev=1058259&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/catalina/startup/TestTomcatClassLoader.java (added) +++ tomcat/trunk/test/org/apache/catalina/startup/TestTomcatClassLoader.java Wed Jan 12 18:13:11 2011 @@ -0,0 +1,106 @@ +/* + * 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.catalina.startup; + +import java.io.IOException; +import java.io.PrintWriter; +import java.net.URL; +import java.net.URLClassLoader; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.catalina.Context; +import org.apache.catalina.loader.WebappClassLoader; +import org.apache.tomcat.util.buf.ByteChunk; + +public class TestTomcatClassLoader extends TomcatBaseTest { + + public void testDefaultClassLoader() throws Exception { + Tomcat tomcat = getTomcatInstance(); + + // Must have a real docBase - just use temp + Context ctx = + tomcat.addContext("", System.getProperty("java.io.tmpdir")); + + Tomcat.addServlet(ctx, "ClassLoaderReport", new ClassLoaderReport(null)); + ctx.addServletMapping("/", "ClassLoaderReport"); + + tomcat.start(); + + ByteChunk res = getUrl("http://localhost:" + getPort() + "/"); + assertEquals("WEBAPP,SYSTEM,OTHER,", res.toString()); + } + + public void testNonDefaultClassLoader() throws Exception { + + ClassLoader cl = new URLClassLoader(new URL[0], + Thread.currentThread().getContextClassLoader()); + + Thread.currentThread().setContextClassLoader(cl); + + Tomcat tomcat = getTomcatInstance(); + tomcat.getServer().setParentClassLoader(cl); + + // Must have a real docBase - just use temp + Context ctx = + tomcat.addContext("", System.getProperty("java.io.tmpdir")); + + Tomcat.addServlet(ctx, "ClassLoaderReport", new ClassLoaderReport(cl)); + ctx.addServletMapping("/", "ClassLoaderReport"); + + tomcat.start(); + + ByteChunk res = getUrl("http://localhost:" + getPort() + "/"); + assertEquals("WEBAPP,CUSTOM,SYSTEM,OTHER,", res.toString()); + } + + private static final class ClassLoaderReport extends HttpServlet { + private static final long serialVersionUID = 1L; + + ClassLoader custom; + + public ClassLoaderReport(ClassLoader custom) { + this.custom = custom; + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + resp.setContentType("text/plain"); + PrintWriter out = resp.getWriter(); + + ClassLoader system = ClassLoader.getSystemClassLoader(); + + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + while (cl != null) { + if (system == cl) { + out.print("SYSTEM,"); + } else if (custom == cl) { + out.print("CUSTOM,"); + } else if (cl instanceof WebappClassLoader) { + out.print("WEBAPP,"); + } else { + out.print("OTHER,"); + } + cl = cl.getParent(); + } + } + } +} Propchange: tomcat/trunk/test/org/apache/catalina/startup/TestTomcatClassLoader.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=1058259&r1=1058258&r2=1058259&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Wed Jan 12 18:13:11 2011 @@ -48,6 +48,10 @@ Improve fix for <bug>50205</bug> to trigger an error earlier if invalid configuration is used. (markt) </update> + <add> + Provide additional control over component class loaders, primarily for + use when embedding. (markt) + </add> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org