You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bu...@apache.org on 2002/01/24 16:54:09 UTC

DO NOT REPLY [Bug 6010] New: - Catalina ContainerServlet classloader issues

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6010>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6010

Catalina ContainerServlet classloader issues

           Summary: Catalina ContainerServlet classloader issues
           Product: Tomcat 4
           Version: Nightly Build
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: Catalina
        AssignedTo: tomcat-dev@jakarta.apache.org
        ReportedBy: anewberger@plumbdesign.com


I posted a patch to the developer mailing list without response so I'm entering 
it as a bug to see whether it's actually dismissed, resolved, etc.  The bug is 
that while it should be sufficient for a class to be put in server/lib to be 
loaded in the catalina class loader (where ContainerServlets need to be), 
arbitrary ContainerServlets placed into server/lib are _not_ being loaded 
properly into the catalina class loader due to a hardcoded reference to 
the 'org.apache.catalina' package in StandardWrapper.java.  This patch resolves 
the issue by doing an extra classloader load check _only_ when privileged is 
set to true for a context.  Since all we know about a servlet from a web.xml 
file is its class name as a string, which tells us nothing about interfaces it 
implements, the only reliable way to see if a servlet is a container servlet is 
to try and load it in the catalina class loader, instantiating the object from 
that class loader only if it actually implements ContainerServlet, otherwise 
using the webapp classloader as usual.  Without this resolution it is a major 
hassle to deploy a ContainerServlet in an arbitrary package.


Index: StandardWrapper.java
===================================================================
RCS file: /home/cvspublic/jakarta-tomcat-
4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java,v
retrieving revision 1.35
diff -u -r1.35 StandardWrapper.java
--- StandardWrapper.java	11 Dec 2001 18:56:03 -0000	1.35
+++ StandardWrapper.java	22 Jan 2002 18:59:00 -0000
@@ -851,34 +851,44 @@
         }
 
         ClassLoader classLoader = loader.getClassLoader();
+        Class classClass = null;
 
-        // Special case class loader for a Catalina internal servlet
-        if (isContainerServlet(actualClass)) {
-            classLoader = this.getClass().getClassLoader();
-            log(sm.getString
-                  ("standardWrapper.containerServlet", getName()));
-        }
+        //if privileged, try loading in catalina classloader
+        if (((Context) getParent()).getPrivileged()) {
+            try {
+                classLoader = this.getClass().getClassLoader();
+                Class sClass = classLoader.loadClass(actualClass);
 
+                if (ContainerServlet.class.isAssignableFrom(sClass)) {
+                    classClass = sClass;
+                }
+
+                log(sm.getString("standardWrapper.containerServlet", getName
()));
+            } catch (ClassNotFoundException e) {}
+        }
+        
         // Load the specified servlet class from the appropriate class loader
-        Class classClass = null;
-        try {
-            if (classLoader != null) {
-                classClass = classLoader.loadClass(actualClass);
-            } else {
-                classClass = Class.forName(actualClass);
+        if (classClass == null) {
+            try {
+                if (classLoader != null) {
+                    classClass = classLoader.loadClass(actualClass);
+                } else {
+                    classClass = Class.forName(actualClass);
+                }
+            } catch (ClassNotFoundException e) {
+                unavailable(null);
+                throw new ServletException
+                    (sm.getString("standardWrapper.missingClass", actualClass),
+                     e);
             }
-        } catch (ClassNotFoundException e) {
-            unavailable(null);
-            throw new ServletException
-                (sm.getString("standardWrapper.missingClass", actualClass),
-                 e);
         }
+
         if (classClass == null) {
             unavailable(null);
             throw new ServletException
                 (sm.getString("standardWrapper.missingClass", actualClass));
         }
-
+        
         // Instantiate and initialize an instance of the servlet class itself
         Servlet servlet = null;
         try {
@@ -903,9 +913,10 @@
                               actualClass));
         }
 
-        // Special handling for ContainerServlet instances
+        // Special handling for ContainerServlet instances, if loaded by
+        // this classloader
         if ((servlet instanceof ContainerServlet) &&
-            isContainerServlet(actualClass)) {
+            classLoader == this.getClass().getClassLoader()) {
             ((ContainerServlet) servlet).setWrapper(this);
         }
 
@@ -1197,22 +1208,6 @@
     protected void addDefaultMapper(String mapperClass) {
 
         ;       // No need for a default Mapper on a Wrapper
-
-    }
-
-
-    /**
-     * Return <code>true</code> if the specified class name represents a
-     * container class that should be loaded by the system class loader.
-     *
-     * @param name Name of the class to be checked
-     */
-    private boolean isContainerServlet(String classname) {
-
-        if (classname.startsWith("org.apache.catalina."))
-            return (true);
-        else
-            return (false);
 
     }

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>