[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