[jboss-cvs] JBossAS SVN: r75300 - in projects/jboss-cl/trunk/classloader/src: main/org/jboss/classloader/spi/base and 2 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Wed Jul 2 05:40:49 EDT 2008
Author: adrian at jboss.org
Date: 2008-07-02 05:40:49 -0400 (Wed, 02 Jul 2008)
New Revision: 75300
Modified:
projects/jboss-cl/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomain.java
projects/jboss-cl/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java
projects/jboss-cl/trunk/classloader/src/tests/org/jboss/test/classloader/domain/support/MockLoader.java
projects/jboss-cl/trunk/classloader/src/tests/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java
Log:
[JBCL-17] - Use loadClass() to load from the parent unless it is a ClassLoaderDomain by default
Modified: projects/jboss-cl/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomain.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomain.java 2008-07-02 09:28:58 UTC (rev 75299)
+++ projects/jboss-cl/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomain.java 2008-07-02 09:40:49 UTC (rev 75300)
@@ -69,6 +69,9 @@
/** The object name */
private ObjectName objectName;
+ /** Whether to use load class for the parent */
+ private boolean useLoadClassForParent = false;
+
/**
* Create a new ClassLoaderDomain with the {@link ParentPolicy#BEFORE} loading rules.
*
@@ -152,6 +155,26 @@
fixUpParent();
}
+ /**
+ * Get the useLoadClassForParent.
+ *
+ * @return the useLoadClassForParent.
+ */
+ public boolean isUseLoadClassForParent()
+ {
+ return useLoadClassForParent;
+ }
+
+ /**
+ * Set the useLoadClassForParent.
+ *
+ * @param useLoadClassForParent the useLoadClassForParent.
+ */
+ public void setUseLoadClassForParent(boolean useLoadClassForParent)
+ {
+ this.useLoadClassForParent = useLoadClassForParent;
+ }
+
public ObjectName getParentDomain()
{
if (parent == null || parent instanceof ClassLoaderDomain == false)
@@ -273,6 +296,63 @@
}
@Override
+ protected Class<?> loadClassBefore(String name)
+ {
+ boolean trace = log.isTraceEnabled();
+ ClassFilter filter = getParentPolicy().getBeforeFilter();
+ if (filter.matchesClassName(name))
+ {
+ if (trace)
+ log.trace(this + " " + name + " matches parent beforeFilter=" + filter);
+ return loadClassFromParent(name);
+ }
+ if (trace)
+ log.trace(this + " " + name + " does NOT match parent beforeFilter=" + filter);
+ return null;
+ }
+
+ @Override
+ protected Class<?> loadClassAfter(String name)
+ {
+ boolean trace = log.isTraceEnabled();
+ ClassFilter filter = getParentPolicy().getAfterFilter();
+ if (filter.matchesClassName(name))
+ {
+ if (trace)
+ log.trace(this + " " + name + " matches parent afterFilter=" + filter);
+ return loadClassFromParent(name);
+ }
+ if (trace)
+ log.trace(this + " " + name + " does NOT match parent afterFilter=" + filter);
+ return null;
+ }
+
+ /**
+ * Try to find a load a from the parent
+ *
+ * @param name the name
+ * @return the class if found
+ */
+ protected Class<?> loadClassFromParent(String name)
+ {
+ Loader parentLoader = getParent();
+
+ boolean trace = log.isTraceEnabled();
+ if (parentLoader == null)
+ {
+ if (trace)
+ log.trace(this + " not loading from non-existant parent");
+ return null;
+ }
+
+ if (trace)
+ log.trace(this + " load class from parent " + name + " parent=" + parent);
+
+ // Recurse into parent domains
+ return parentLoader.loadClass(name);
+ }
+
+ @Override
protected Loader findBeforeLoader(String name)
{
boolean trace = log.isTraceEnabled();
@@ -581,20 +661,27 @@
*/
private void fixUpParent()
{
- if (parent == null)
+ try
{
- final ClassLoader classLoader = getParentClassLoader();
- if (classLoader != null)
+ if (parent == null)
{
- parent = AccessController.doPrivileged(new PrivilegedAction<Loader>()
+ final ClassLoader classLoader = getParentClassLoader();
+ if (classLoader != null)
{
- public Loader run()
+ parent = AccessController.doPrivileged(new PrivilegedAction<Loader>()
{
- return new ClassLoaderToLoaderAdapter(classLoader);
- }
- });
+ public Loader run()
+ {
+ return new ClassLoaderToLoaderAdapter(classLoader);
+ }
+ });
+ }
}
}
+ finally
+ {
+ setUseLoadClassForParent(parent instanceof ClassLoaderDomain == false);
+ }
}
public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception
Modified: projects/jboss-cl/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java 2008-07-02 09:28:58 UTC (rev 75299)
+++ projects/jboss-cl/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java 2008-07-02 09:40:49 UTC (rev 75300)
@@ -153,6 +153,13 @@
}
/**
+ * Whether to use load class for parent
+ *
+ * @return true to load class on the parent loader
+ */
+ public abstract boolean isUseLoadClassForParent();
+
+ /**
* Transform the byte code<p>
*
* By default, this delegates to the classloader system
@@ -184,10 +191,20 @@
protected Class<?> loadClass(BaseClassLoader classLoader, String name, boolean allExports) throws ClassNotFoundException
{
boolean trace = log.isTraceEnabled();
+
+ boolean findInParent = (isUseLoadClassForParent() == false);
+ // Should we directly load from the parent?
+ if (findInParent == false)
+ {
+ Class<?> clazz = loadClassBefore(name);
+ if (clazz != null)
+ return clazz;
+ }
+
String path = ClassLoaderUtils.classNameToPath(name);
-
- Loader loader = findLoader(classLoader, path, allExports);
+
+ Loader loader = findLoader(classLoader, path, allExports, findInParent);
if (loader != null)
{
Thread thread = Thread.currentThread();
@@ -195,8 +212,17 @@
ClassLoaderManager.scheduleTask(task, loader, false);
return ClassLoaderManager.process(thread, task);
}
+
+ // Should we directly load from the parent?
+ if (findInParent == false)
+ {
+ Class<?> clazz = loadClassAfter(name);
+ if (clazz != null)
+ return clazz;
+ }
+
// Finally see whether this is the JDK assuming it can load its classes from any classloader
- else if (classLoader != null)
+ if (classLoader != null)
{
BaseClassLoaderPolicy policy = classLoader.getPolicy();
ClassLoader hack = policy.isJDKRequest(name);
@@ -226,7 +252,7 @@
*/
protected Loader findLoader(String name)
{
- return findLoader(null, name, true);
+ return findLoader(null, name, true, true);
}
/**
@@ -237,17 +263,19 @@
* @param allExports whether we should look at all exports
* @return the loader
*/
- Loader findLoader(BaseClassLoader classLoader, String name, boolean allExports)
+ Loader findLoader(BaseClassLoader classLoader, String name, boolean allExports, boolean findInParent)
{
boolean trace = log.isTraceEnabled();
if (trace)
- log.trace(this + " findLoader " + name + " classLoader=" + classLoader + " allExports=" + allExports);
+ log.trace(this + " findLoader " + name + " classLoader=" + classLoader + " allExports=" + allExports + " findInParent=" + findInParent);
if (getClassLoaderSystem() == null)
throw new IllegalStateException("Domain is not registered with a classloader system: " + toLongString());
// Try the before attempt (e.g. from the parent)
- Loader loader = findBeforeLoader(name);
+ Loader loader = null;
+ if (findInParent)
+ loader = findBeforeLoader(name);
if (loader != null)
return loader;
@@ -290,7 +318,10 @@
}
// Try the after attempt (e.g. from the parent)
- return findAfterLoader(name);
+ if (findInParent)
+ return findAfterLoader(name);
+
+ return null;
}
/**
@@ -907,6 +938,22 @@
/**
* Invoked before classloading is attempted to allow a preload attempt, e.g. from the parent
*
+ * @param name the class name
+ * @return the loader if found or null otherwise
+ */
+ protected abstract Class<?> loadClassBefore(String name);
+
+ /**
+ * Invoked after classloading is attempted to allow a postload attempt, e.g. from the parent
+ *
+ * @param name the class name
+ * @return the loader if found or null otherwise
+ */
+ protected abstract Class<?> loadClassAfter(String name);
+
+ /**
+ * Invoked before classloading is attempted to allow a preload attempt, e.g. from the parent
+ *
* @param name the class resource name
* @return the loader if found or null otherwise
*/
Modified: projects/jboss-cl/trunk/classloader/src/tests/org/jboss/test/classloader/domain/support/MockLoader.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/tests/org/jboss/test/classloader/domain/support/MockLoader.java 2008-07-02 09:28:58 UTC (rev 75299)
+++ projects/jboss-cl/trunk/classloader/src/tests/org/jboss/test/classloader/domain/support/MockLoader.java 2008-07-02 09:40:49 UTC (rev 75300)
@@ -36,10 +36,22 @@
*/
public class MockLoader implements Loader
{
+ private boolean doLoadClass;
+
public Set<String> getResource = new HashSet<String>();
public Set<String> getResources = new HashSet<String>();
public Set<String> loadClass = new HashSet<String>();
+ public MockLoader()
+ {
+ this(true);
+ }
+
+ public MockLoader(boolean doLoadClass)
+ {
+ this.doLoadClass = doLoadClass;
+ }
+
public URL getResource(String name)
{
getResource.add(name);
@@ -54,6 +66,8 @@
public Class<?> loadClass(String className)
{
loadClass.add(className);
+ if (doLoadClass == false)
+ return null;
try
{
return getClass().getClassLoader().loadClass(className);
Modified: projects/jboss-cl/trunk/classloader/src/tests/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/tests/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java 2008-07-02 09:28:58 UTC (rev 75299)
+++ projects/jboss-cl/trunk/classloader/src/tests/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java 2008-07-02 09:40:49 UTC (rev 75300)
@@ -69,17 +69,91 @@
ClassLoader classLoader = system.registerClassLoaderPolicy(domain, policy);
assertLoadClass(MockLoader.class, classLoader, null, true);
- checkGetResource(loader, MockLoader.class);
checkLoadClass(loader, MockLoader.class);
}
public void testCustomLoaderBeforeNotFound() throws Exception
{
ClassLoaderSystem system = createClassLoaderSystem();
+ MockLoader loader = new MockLoader(false);
+ ClassLoaderDomain domain = system.createAndRegisterDomain("test", ParentPolicy.BEFORE, loader);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy();
+ policy.setPathsAndPackageNames(ClassLoaderDomain.class);
+ ClassLoader classLoader = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClass(ClassLoaderDomain.class, classLoader);
+ checkLoadClassAttempted(loader, ClassLoaderDomain.class);
+ }
+
+ public void testCustomLoaderAfterNotReached() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystem();
MockLoader loader = new MockLoader();
+ ClassLoaderDomain domain = system.createAndRegisterDomain("test", ParentPolicy.AFTER, loader);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy();
+ policy.setPathsAndPackageNames(MockLoader.class, Loader.class);
+ ClassLoader classLoader = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClass(MockLoader.class, classLoader);
+ checkLoadClassNotAttempted(loader, MockLoader.class);
+ }
+
+ public void testCustomLoaderAfterReached() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystem();
+ MockLoader loader = new MockLoader();
+ ClassLoaderDomain domain = system.createAndRegisterDomain("test", ParentPolicy.AFTER, loader);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy();
+ ClassLoader classLoader = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClass(MockLoader.class, classLoader, null, true);
+ checkLoadClass(loader, MockLoader.class);
+ }
+
+ public void testCustomLoaderFiltered() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystem();
+ MockLoader loader = new MockLoader();
+ NoMatchClassFilter filter = new NoMatchClassFilter(MockLoader.class);
+ ParentPolicy parentPolicy = new ParentPolicy(filter, ClassFilter.NOTHING);
+ ClassLoaderDomain domain = system.createAndRegisterDomain("test", parentPolicy, loader);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy();
+ policy.setPathsAndPackageNames(MockLoader.class, Loader.class);
+ ClassLoader classLoader = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClass(MockLoader.class, classLoader);
+ checkLoadClassNotAttempted(loader, MockLoader.class);
+ assertTrue("Should have been filtered", filter.filtered);
+ }
+
+ public void testCustomLoaderBeforeGetResource() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystem();
+ MockLoader loader = new MockLoader();
ClassLoaderDomain domain = system.createAndRegisterDomain("test", ParentPolicy.BEFORE, loader);
+ domain.setUseLoadClassForParent(false);
MockClassLoaderPolicy policy = createMockClassLoaderPolicy();
+ policy.setPathsAndPackageNames(MockLoader.class);
+ ClassLoader classLoader = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClass(MockLoader.class, classLoader, null, true);
+ checkGetResource(loader, MockLoader.class);
+ checkLoadClass(loader, MockLoader.class);
+ }
+
+ public void testCustomLoaderBeforeNotFoundGetResource() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystem();
+ MockLoader loader = new MockLoader();
+ ClassLoaderDomain domain = system.createAndRegisterDomain("test", ParentPolicy.BEFORE, loader);
+ domain.setUseLoadClassForParent(false);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy();
policy.setPathsAndPackageNames(ClassLoaderDomain.class);
ClassLoader classLoader = system.registerClassLoaderPolicy(domain, policy);
@@ -88,11 +162,12 @@
checkLoadClass(loader);
}
- public void testCustomLoaderAfterNotReached() throws Exception
+ public void testCustomLoaderAfterNotReachedGetResource() throws Exception
{
ClassLoaderSystem system = createClassLoaderSystem();
MockLoader loader = new MockLoader();
ClassLoaderDomain domain = system.createAndRegisterDomain("test", ParentPolicy.AFTER, loader);
+ domain.setUseLoadClassForParent(false);
MockClassLoaderPolicy policy = createMockClassLoaderPolicy();
policy.setPathsAndPackageNames(MockLoader.class, Loader.class);
@@ -103,11 +178,12 @@
checkLoadClass(loader);
}
- public void testCustomLoaderAfterReached() throws Exception
+ public void testCustomLoaderAfterReachedGetResource() throws Exception
{
ClassLoaderSystem system = createClassLoaderSystem();
MockLoader loader = new MockLoader();
ClassLoaderDomain domain = system.createAndRegisterDomain("test", ParentPolicy.AFTER, loader);
+ domain.setUseLoadClassForParent(false);
MockClassLoaderPolicy policy = createMockClassLoaderPolicy();
ClassLoader classLoader = system.registerClassLoaderPolicy(domain, policy);
@@ -117,13 +193,14 @@
checkLoadClass(loader, MockLoader.class);
}
- public void testCustomLoaderFiltered() throws Exception
+ public void testCustomLoaderFilteredGetResource() throws Exception
{
ClassLoaderSystem system = createClassLoaderSystem();
MockLoader loader = new MockLoader();
NoMatchClassFilter filter = new NoMatchClassFilter(MockLoader.class);
ParentPolicy parentPolicy = new ParentPolicy(filter, ClassFilter.NOTHING);
ClassLoaderDomain domain = system.createAndRegisterDomain("test", parentPolicy, loader);
+ domain.setUseLoadClassForParent(false);
MockClassLoaderPolicy policy = createMockClassLoaderPolicy();
policy.setPathsAndPackageNames(MockLoader.class, Loader.class);
@@ -160,4 +237,14 @@
classNames.add(clazz.getName());
assertEquals(classNames, loader.loadClass);
}
+
+ protected void checkLoadClassNotAttempted(MockLoader loader, Class<?> clazz)
+ {
+ assertFalse("Didn't expect " + clazz.getName() + " in " + loader.loadClass, loader.loadClass.contains(clazz.getName()));
+ }
+
+ protected void checkLoadClassAttempted(MockLoader loader, Class<?> clazz)
+ {
+ assertTrue("Expected " + clazz.getName() + " in " + loader.loadClass, loader.loadClass.contains(clazz.getName()));
+ }
}
More information about the jboss-cvs-commits
mailing list