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

Reply via email to