Author: markt
Date: Fri Jan 17 15:37:20 2014
New Revision: 1559153
URL: http://svn.apache.org/r1559153
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/tc7.0.x/trunk/ (props changed)
tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
Merged /tomcat/trunk:r1559134
Modified:
tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java?rev=1559153&r1=1559152&r2=1559153&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
Fri Jan 17 15:37:20 2014
@@ -227,14 +227,26 @@ public class WebappClassLoader
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();
}
-
}
@@ -251,11 +263,22 @@ public class WebappClassLoader
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();
}
@@ -413,6 +436,15 @@ public class WebappClassLoader
/**
+ * 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 j2seClassLoader;
+
+
+ /**
* Has this component been started?
*/
protected boolean started = false;
@@ -1396,10 +1428,7 @@ public class WebappClassLoader
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() + "'");
@@ -1433,10 +1462,7 @@ public class WebappClassLoader
// (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() + "'");
@@ -1480,10 +1506,7 @@ public class WebappClassLoader
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())
@@ -1515,10 +1538,7 @@ public class WebappClassLoader
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())
@@ -1617,7 +1637,7 @@ public class WebappClassLoader
// (0.2) Try loading the class with the system class loader, to prevent
// the webapp from overriding J2SE classes
try {
- clazz = system.loadClass(name);
+ clazz = j2seClassLoader.loadClass(name);
if (clazz != null) {
if (resolve)
resolveClass(clazz);
@@ -1648,11 +1668,8 @@ public class WebappClassLoader
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");
@@ -1685,11 +1702,8 @@ public class WebappClassLoader
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");
Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1559153&r1=1559152&r2=1559153&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Fri Jan 17 15:37:20 2014
@@ -71,6 +71,13 @@
<code>/ROOT</code> as equivalent to <code>/</code>. (markt)
</fix>
<fix>
+ <bug>55943</bug>: Improve the implementation of the class loader check
+ that prevents web applications from trying to override J2SE
+ implementation classes. As part of this fix, refactor the way a null
+ parent class loader is handled which enables a number of null checks
and
+ object creation calls to be removed. (markt)
+ </fix>
+ <fix>
<bug>55958</bug>: Differentiate between <code>foo.war</code> the WAR
file and <code>foo.war</code> the directory. (markt)
</fix>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]