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