Commit da07cdf4 authored by Phillip Webb's avatar Phillip Webb

Fix TomcatEmbeddedWebappClassLoader for Tomcat 8

Rework TomcatEmbeddedWebappClassLoader to deal with the fact that
the 'system' field is final in Tomcat 8.

Issue: #53945989
parent 1df48e23
package org.springframework.bootstrap.context.embedded.tomcat;
/* /*
* Copyright 2012-2013 the original author or authors. * Copyright 2012-2013 the original author or authors.
* *
...@@ -14,11 +16,6 @@ ...@@ -14,11 +16,6 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.bootstrap.context.embedded.tomcat;
import java.net.URL;
import java.net.URLClassLoader;
import org.apache.catalina.loader.WebappClassLoader; import org.apache.catalina.loader.WebappClassLoader;
/** /**
...@@ -33,27 +30,86 @@ public class TomcatEmbeddedWebappClassLoader extends WebappClassLoader { ...@@ -33,27 +30,86 @@ public class TomcatEmbeddedWebappClassLoader extends WebappClassLoader {
public TomcatEmbeddedWebappClassLoader() { public TomcatEmbeddedWebappClassLoader() {
super(); super();
this.system = new EmbeddedSystemClassLoader();
} }
public TomcatEmbeddedWebappClassLoader(ClassLoader parent) { public TomcatEmbeddedWebappClassLoader(ClassLoader parent) {
super(parent); super(parent);
this.system = new EmbeddedSystemClassLoader();
} }
private static class EmbeddedSystemClassLoader extends URLClassLoader { @Override
public synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
Class<?> resultClass = null;
// Check local class caches
resultClass = (resultClass == null ? findLoadedClass0(name) : resultClass);
resultClass = (resultClass == null ? findLoadedClass(name) : resultClass);
if (resultClass != null) {
return resolveIfNecessary(resultClass, resolve);
}
// Check security
checkPackageAccess(name);
// Perform the actual load
boolean delegateLoad = (this.delegate || filter(name));
if (delegateLoad) {
resultClass = (resultClass == null ? loadFromParent(name) : resultClass);
}
resultClass = (resultClass == null ? findClassIgnoringNotFound(name)
: resultClass);
if (!delegateLoad) {
resultClass = (resultClass == null ? loadFromParent(name) : resultClass);
}
if (resultClass == null) {
throw new ClassNotFoundException(name);
}
return resolveIfNecessary(resultClass, resolve);
}
private Class<?> resolveIfNecessary(Class<?> resultClass, boolean resolve) {
if (resolve) {
resolveClass(resultClass);
}
return (resultClass);
}
public EmbeddedSystemClassLoader() { private Class<?> loadFromParent(String name) {
super(new URL[] {}); if (this.parent == null) {
return null;
} }
try {
return Class.forName(name, false, this.parent);
}
catch (ClassNotFoundException e) {
return null;
}
}
@Override private Class<?> findClassIgnoringNotFound(String name) {
public Class<?> loadClass(String name) throws ClassNotFoundException { try {
throw new ClassNotFoundException( return findClass(name);
"System ClassLoader disabled for embedded context, unable to load "
+ name);
} }
catch (ClassNotFoundException e) {
return null;
}
}
private void checkPackageAccess(String name) throws ClassNotFoundException {
if (this.securityManager != null && name.lastIndexOf('.') >= 0) {
try {
this.securityManager.checkPackageAccess(name.substring(0,
name.lastIndexOf('.')));
}
catch (SecurityException se) {
throw new ClassNotFoundException("Security Violation, attempt to use "
+ "Restricted Class: " + name, se);
}
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment