Author: markt
Date: Fri Jan 17 15:16:35 2014
New Revision: 1559134

URL: http://svn.apache.org/r1559134
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=55943
Better implementation of the class loader check that prevents web applications 
from trying to override J2SE implementation classes.
Refactor the way a null parent class loader was handled which enables a number 
of null checks and object creation calls to be removed

Modified:
    tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java

Modified: tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java?rev=1559134&r1=1559133&r2=1559134&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java Fri Jan 
17 15:16:35 2014
@@ -216,14 +216,26 @@ public class WebappClassLoader extends U
     public WebappClassLoader() {
 
         super(new URL[0]);
-        this.parent = getParent();
-        system = getSystemClassLoader();
-        securityManager = System.getSecurityManager();
 
+        ClassLoader p = getParent();
+        if (p == null) {
+            p = getSystemClassLoader();
+        }
+        this.parent = p;
+
+        ClassLoader j = String.class.getClassLoader();
+        if (j == null) {
+            j = getSystemClassLoader();
+            while (j.getParent() != null) {
+                j = j.getParent();
+            }
+        }
+        this.j2seClassLoader = j;
+
+        securityManager = System.getSecurityManager();
         if (securityManager != null) {
             refreshPolicy();
         }
-
     }
 
 
@@ -240,11 +252,22 @@ public class WebappClassLoader extends U
 
         super(new URL[0], parent);
 
-        this.parent = getParent();
+        ClassLoader p = getParent();
+        if (p == null) {
+            p = getSystemClassLoader();
+        }
+        this.parent = p;
 
-        system = getSystemClassLoader();
-        securityManager = System.getSecurityManager();
+        ClassLoader j = String.class.getClassLoader();
+        if (j == null) {
+            j = getSystemClassLoader();
+            while (j.getParent() != null) {
+                j = j.getParent();
+            }
+        }
+        this.j2seClassLoader = j;
 
+        securityManager = System.getSecurityManager();
         if (securityManager != null) {
             refreshPolicy();
         }
@@ -310,13 +333,16 @@ public class WebappClassLoader extends U
     /**
      * The parent class loader.
      */
-    protected ClassLoader parent = null;
+    protected final ClassLoader parent;
 
 
     /**
-     * The system class loader.
+     * The bootstrap class loader used to load the J2SE classes. In some
+     * implementations this class loader is always <code>null</null> and in
+     * those cases {@link ClassLoader#getParent()} will be called recursively 
on
+     * the system class loader and the last non-null result used.
      */
-    protected final ClassLoader system;
+    protected final ClassLoader j2seClassLoader;
 
 
     /**
@@ -678,7 +704,7 @@ public class WebappClassLoader extends U
     @Override
     public WebappClassLoader copyWithoutTransformers() {
 
-        WebappClassLoader result = new WebappClassLoader(this.parent);
+        WebappClassLoader result = new WebappClassLoader(getParent());
 
         result.resources = this.resources;
         result.delegate = this.delegate;
@@ -987,10 +1013,7 @@ public class WebappClassLoader extends U
         if (delegate) {
             if (log.isDebugEnabled())
                 log.debug("  Delegating to parent classloader " + parent);
-            ClassLoader loader = parent;
-            if (loader == null)
-                loader = system;
-            url = loader.getResource(name);
+            url = parent.getResource(name);
             if (url != null) {
                 if (log.isDebugEnabled())
                     log.debug("  --> Returning '" + url.toString() + "'");
@@ -1008,10 +1031,7 @@ public class WebappClassLoader extends U
 
         // (3) Delegate to parent unconditionally if not already attempted
         if( !delegate ) {
-            ClassLoader loader = parent;
-            if (loader == null)
-                loader = system;
-            url = loader.getResource(name);
+            url = parent.getResource(name);
             if (url != null) {
                 if (log.isDebugEnabled())
                     log.debug("  --> Returning '" + url.toString() + "'");
@@ -1055,10 +1075,7 @@ public class WebappClassLoader extends U
         if (delegate) {
             if (log.isDebugEnabled())
                 log.debug("  Delegating to parent classloader " + parent);
-            ClassLoader loader = parent;
-            if (loader == null)
-                loader = system;
-            stream = loader.getResourceAsStream(name);
+            stream = parent.getResourceAsStream(name);
             if (stream != null) {
                 // FIXME - cache???
                 if (log.isDebugEnabled())
@@ -1084,10 +1101,7 @@ public class WebappClassLoader extends U
         if (!delegate) {
             if (log.isDebugEnabled())
                 log.debug("  Delegating to parent classloader unconditionally 
" + parent);
-            ClassLoader loader = parent;
-            if (loader == null)
-                loader = system;
-            stream = loader.getResourceAsStream(name);
+            stream = parent.getResourceAsStream(name);
             if (stream != null) {
                 // FIXME - cache???
                 if (log.isDebugEnabled())
@@ -1186,9 +1200,9 @@ public class WebappClassLoader extends U
         // (0.2) Try loading the class with the system class loader, to prevent
         //       the webapp from overriding J2SE classes
         String resourceName = binaryNameToPath(name, false);
-        if (system.getResource(resourceName) != null) {
+        if (j2seClassLoader.getResource(resourceName) != null) {
             try {
-                clazz = system.loadClass(name);
+                clazz = j2seClassLoader.loadClass(name);
                 if (clazz != null) {
                     if (resolve)
                         resolveClass(clazz);
@@ -1220,11 +1234,8 @@ public class WebappClassLoader extends U
         if (delegateLoad) {
             if (log.isDebugEnabled())
                 log.debug("  Delegating to parent classloader1 " + parent);
-            ClassLoader loader = parent;
-            if (loader == null)
-                loader = system;
             try {
-                clazz = Class.forName(name, false, loader);
+                clazz = Class.forName(name, false, parent);
                 if (clazz != null) {
                     if (log.isDebugEnabled())
                         log.debug("  Loading class from parent");
@@ -1257,11 +1268,8 @@ public class WebappClassLoader extends U
         if (!delegateLoad) {
             if (log.isDebugEnabled())
                 log.debug("  Delegating to parent classloader at end: " + 
parent);
-            ClassLoader loader = parent;
-            if (loader == null)
-                loader = system;
             try {
-                clazz = Class.forName(name, false, loader);
+                clazz = Class.forName(name, false, parent);
                 if (clazz != null) {
                     if (log.isDebugEnabled())
                         log.debug("  Loading class from parent");
@@ -1443,7 +1451,6 @@ public class WebappClassLoader extends U
         resourceEntries.clear();
         jarModificationTimes.clear();
         resources = null;
-        parent = null;
 
         permissionList.clear();
         loaderPC.clear();



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to