[jboss-cvs] JBossAS SVN: r96497 - in projects/jboss-cl/branches/Branch_2_0/classloader/src: main/java/org/jboss/classloader/spi/base and 6 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Nov 18 11:55:49 EST 2009


Author: adrian at jboss.org
Date: 2009-11-18 11:55:47 -0500 (Wed, 18 Nov 2009)
New Revision: 96497

Added:
   projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundEvent.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundHandler.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEvent.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEventHandler.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundEvent.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundHandler.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/
   projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/ClassLoaderNotificationsTestSuite.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/support/
   projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/support/a/
   projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/support/a/A.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/
   projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassFoundHandlerUnitTestCase.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassLoaderEventHandlerUnitTestCase.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassNotFoundHandlerUnitTestCase.java
Modified:
   projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomain.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystem.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoader.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/ClassLoaderAllTestSuite.java
   projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java
Log:
[JBCL-127] [JBCL-128] - Notifications and handlers for ClassLoader create/destroy, ClassNotFound and ClassFound

Added: projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundEvent.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundEvent.java	                        (rev 0)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundEvent.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -0,0 +1,87 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloader.spi;
+
+import java.util.EventObject;
+
+/**
+ * ClassFoundEvent.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassFoundEvent extends EventObject
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -8258925782380851534L;
+
+   /** The class */
+   private Class<?> clazz;
+   
+   /**
+    * Create a new ClassFoundEvent.
+    * 
+    * @param classLoader classLoader
+    * @param clazz the class
+    */
+   public ClassFoundEvent(ClassLoader classLoader, Class<?> clazz)
+   {
+      super(classLoader);
+      this.clazz = clazz;
+   }
+
+   /**
+    * Get the className.
+    * 
+    * @return the className.
+    */
+   public String getClassName()
+   {
+      return clazz.getName();
+   }
+
+   /**
+    * Get the class.
+    * 
+    * @return the class.
+    */
+   public Class<?> getClazz()
+   {
+      return clazz;
+   }
+
+   /**
+    * Get the classLoader.
+    * 
+    * @return the classLoader
+    */
+   public ClassLoader getClassLoader()
+   {
+      return (ClassLoader) getSource();
+   }
+
+   @Override
+   public String toString()
+   {
+      return getClass().getSimpleName() + "[classLoader=" + getClassLoader() + " class=" + getClassName() + "]";
+   }
+}

Added: projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundHandler.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundHandler.java	                        (rev 0)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundHandler.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -0,0 +1,38 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloader.spi;
+
+/**
+ * ClassFoundHandler.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface ClassFoundHandler
+{
+   /**
+    * Fired when a class is found
+    * 
+    * @param event the event
+    */
+   void classFound(ClassFoundEvent event);
+}

Modified: projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomain.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomain.java	2009-11-18 16:54:13 UTC (rev 96496)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomain.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -33,6 +33,7 @@
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.Map.Entry;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 import javax.management.MBeanRegistration;
 import javax.management.MBeanServer;
@@ -41,6 +42,7 @@
 import org.jboss.classloader.plugins.ClassLoaderUtils;
 import org.jboss.classloader.plugins.loader.ClassLoaderToLoaderAdapter;
 import org.jboss.classloader.spi.base.BaseClassLoaderDomain;
+import org.jboss.classloader.spi.base.BaseClassLoaderSource;
 import org.jboss.classloader.spi.filter.ClassFilter;
 import org.jboss.classloading.spi.RealClassLoader;
 import org.jboss.logging.Logger;
@@ -51,7 +53,7 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
-public class ClassLoaderDomain extends BaseClassLoaderDomain implements Loader, ClassLoaderDomainMBean, MBeanRegistration
+public class ClassLoaderDomain extends BaseClassLoaderDomain implements Loader, ClassLoaderDomainMBean, MBeanRegistration, ClassNotFoundHandler, ClassFoundHandler
 {
    /** The log */
    private static final Logger log = Logger.getLogger(ClassLoaderDomain.class);
@@ -73,6 +75,15 @@
    
    /** Whether to use load class for the parent */
    private boolean useLoadClassForParent = false;
+
+   /** The class not found handlers */
+   private List<ClassNotFoundHandler> classNotFoundHandlers;
+
+   /** The class found handlers */
+   private List<ClassFoundHandler> classFoundHandlers;
+
+   /** The class loader event handlers */
+   private List<ClassLoaderEventHandler> classLoaderEventHandlers;
    
    /**
     * Create a new ClassLoaderDomain with the {@link ParentPolicy#BEFORE} loading rules.
@@ -287,7 +298,228 @@
       else
          builder.append(getParentClassLoader());
    }
+   
+   /**
+    * Add a ClassNotFoundHandler
+    * 
+    * @param handler the handler
+    */
+   public void addClassNotFoundHandler(ClassNotFoundHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classNotFoundHandlers == null)
+         classNotFoundHandlers = new CopyOnWriteArrayList<ClassNotFoundHandler>();
+      
+      classNotFoundHandlers.add(handler);
+   }
+   
+   /**
+    * Remove a ClassNotFoundHandler
+    * 
+    * @param handler the handler
+    */
+   public void removeClassNotFoundHandler(ClassNotFoundHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classNotFoundHandlers == null)
+         return;
+      classNotFoundHandlers.remove(handler);
+   }
 
+   public boolean classNotFound(ClassNotFoundEvent event)
+   {
+      String className = event.getClassName();
+
+      ClassNotFoundHandler parent = null;
+      Loader parentLoader = getParent();
+      if (parentLoader instanceof ClassNotFoundHandler)
+         parent = (ClassNotFoundHandler) parentLoader;
+
+      ClassLoaderPolicy parentPolicy = getClassLoaderPolicy(parentLoader);
+      if (parentPolicy != null)
+         parent = parentPolicy;
+      
+      boolean parentResult = false;
+      if (parent != null)
+         parentResult = parent.classNotFound(event);
+
+      // Try the parent before
+      if (parentResult && getParentPolicy().getBeforeFilter().matchesClassName(className))
+         return true;
+      
+      if (classNotFoundHandlers != null && classNotFoundHandlers.isEmpty() == false)
+      {
+         for (ClassNotFoundHandler handler : classNotFoundHandlers)
+         {
+            try
+            {
+               if (handler.classNotFound(event))
+                  return true;
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error invoking classNotFoundHandler: " + handler, t);
+            }
+         }
+      }
+
+      // Try the parent after
+      if (parentResult && getParentPolicy().getAfterFilter().matchesClassName(className))
+         return true;
+      
+      ClassLoaderSystem system = (ClassLoaderSystem) getClassLoaderSystem();
+      if (system == null)
+         return false;
+      return system.classNotFound(event);
+   }
+   
+   /**
+    * Add a ClassFoundHandler
+    * 
+    * @param handler the handler
+    */
+   public void addClassFoundHandler(ClassFoundHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classFoundHandlers == null)
+         classFoundHandlers = new CopyOnWriteArrayList<ClassFoundHandler>();
+      
+      classFoundHandlers.add(handler);
+   }
+   
+   /**
+    * Remove a ClassFoundHandler
+    * 
+    * @param handler the handler
+    */
+   public void removeClassFoundHandler(ClassFoundHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classFoundHandlers == null)
+         return;
+      classFoundHandlers.remove(handler);
+   }
+
+   public void classFound(ClassFoundEvent event)
+   {
+      ClassFoundHandler parent = null;
+      Loader parentLoader = getParent();
+      if (parentLoader instanceof ClassFoundHandler)
+         parent = (ClassFoundHandler) parentLoader;
+
+      ClassLoaderPolicy parentPolicy = getClassLoaderPolicy(parentLoader);
+      if (parentPolicy != null)
+         parent = parentPolicy;
+      
+      if (parent != null)
+         parent.classFound(event);
+      
+      if (classFoundHandlers != null && classFoundHandlers.isEmpty() == false)
+      {
+         for (ClassFoundHandler handler : classFoundHandlers)
+         {
+            try
+            {
+               handler.classFound(event);
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error invoking classFoundHandler: " + handler, t);
+            }
+         }
+      }
+      
+      ClassLoaderSystem system = (ClassLoaderSystem) getClassLoaderSystem();
+      if (system == null)
+         return;
+      system.classFound(event);
+   }
+   
+   /**
+    * Add a ClassLoaderEventHandler
+    * 
+    * @param handler the handler
+    */
+   public void addClassLoaderEventHandler(ClassLoaderEventHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classLoaderEventHandlers == null)
+         classLoaderEventHandlers = new CopyOnWriteArrayList<ClassLoaderEventHandler>();
+      
+      classLoaderEventHandlers.add(handler);
+   }
+   
+   /**
+    * Remove a ClassLoaderEventHandler
+    * 
+    * @param handler the handler
+    */
+   public void removeClassLoaderEventHandler(ClassLoaderEventHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classLoaderEventHandlers == null)
+         return;
+      classLoaderEventHandlers.remove(handler);
+   }
+
+   private void fireRegisterClassLoader(ClassLoaderEvent event)
+   {
+      if (classLoaderEventHandlers != null && classLoaderEventHandlers.isEmpty() == false)
+      {
+         for (ClassLoaderEventHandler handler : classLoaderEventHandlers)
+         {
+            try
+            {
+               handler.fireRegisterClassLoader(event);
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error invoking classLoaderEventHandler: " + handler, t);
+            }
+         }
+      }
+      
+      ClassLoaderSystem system = (ClassLoaderSystem) getClassLoaderSystem();
+      if (system == null)
+         return;
+      system.fireRegisterClassLoader(event);
+   }
+
+   private void fireUnregisterClassLoader(ClassLoaderEvent event)
+   {
+      if (classLoaderEventHandlers != null && classLoaderEventHandlers.isEmpty() == false)
+      {
+         for (ClassLoaderEventHandler handler : classLoaderEventHandlers)
+         {
+            try
+            {
+               handler.fireUnregisterClassLoader(event);
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error invoking classLoaderEventHandler: " + handler, t);
+            }
+         }
+      }
+      
+      ClassLoaderSystem system = (ClassLoaderSystem) getClassLoaderSystem();
+      if (system == null)
+         return;
+      system.fireUnregisterClassLoader(event);
+   }
+
    @Override
    public String toString()
    {
@@ -686,7 +918,8 @@
       }
       finally
       {
-         setUseLoadClassForParent(parent instanceof ClassLoaderDomain == false);
+         if ((parent instanceof ClassLoaderDomain == false) && (parent instanceof BaseClassLoaderSource == false))
+            setUseLoadClassForParent(true);
       }
    }
 
@@ -728,11 +961,13 @@
    protected void afterRegisterClassLoader(ClassLoader classLoader, ClassLoaderPolicy policy)
    {
       registerClassLoaderMBean(classLoader);
+      fireRegisterClassLoader(new ClassLoaderEvent(this, classLoader));
    }
 
    @Override
    protected void beforeUnregisterClassLoader(ClassLoader classLoader, ClassLoaderPolicy policy)
    {
+      fireUnregisterClassLoader(new ClassLoaderEvent(this, classLoader));
       unregisterClassLoaderMBean(classLoader);
    }
 

Added: projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEvent.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEvent.java	                        (rev 0)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEvent.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -0,0 +1,77 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloader.spi;
+
+import java.util.EventObject;
+
+/**
+ * ClassLoaderEvent.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassLoaderEvent extends EventObject
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -5874702798336257018L;
+
+   /** The classLoader */
+   private ClassLoader classLoader;
+   
+   /**
+    * Create a new ClassLoaderEvent.
+    *
+    * @param classLoaderDomain the classLoaderDomain
+    * @param classLoader classLoader
+    */
+   public ClassLoaderEvent(ClassLoaderDomain classLoaderDomain, ClassLoader classLoader)
+   {
+      super(classLoaderDomain);
+      this.classLoader = classLoader;
+   }
+
+   /**
+    * Get the classLoader.
+    * 
+    * @return the classLoader
+    */
+   public ClassLoader getClassLoader()
+   {
+      return classLoader;
+   }
+
+   /**
+    * Get the classLoaderDomain.
+    * 
+    * @return the classLoaderDomain
+    */
+   public ClassLoaderDomain getClassLoaderDomain()
+   {
+      return (ClassLoaderDomain) getSource();
+   }
+
+   @Override
+   public String toString()
+   {
+      return getClass().getSimpleName() + "[classLoaderDomain=" + getClassLoaderDomain() + " classLoader=" + getClassLoader() + "]";
+   }
+}

Added: projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEventHandler.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEventHandler.java	                        (rev 0)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEventHandler.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -0,0 +1,45 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloader.spi;
+
+/**
+ * ClassLoaderEventHandler.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface ClassLoaderEventHandler
+{
+   /**
+    * Fired when a classLoader is registered
+    * 
+    * @param event the classloader event
+    */
+   void fireRegisterClassLoader(ClassLoaderEvent event);
+
+   /**
+    * Fired when a classLoader is registered
+    * 
+    * @param event the classloader event
+    */
+   void fireUnregisterClassLoader(ClassLoaderEvent event);
+}

Modified: projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java	2009-11-18 16:54:13 UTC (rev 96496)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -31,6 +31,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
@@ -48,11 +49,17 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
-public abstract class ClassLoaderPolicy extends BaseClassLoaderPolicy
+public abstract class ClassLoaderPolicy extends BaseClassLoaderPolicy implements ClassNotFoundHandler, ClassFoundHandler
 {
    /** The log */
    private static final Logger log = Logger.getLogger(ClassLoaderPolicy.class);
 
+   /** The class not found handlers */
+   private List<ClassNotFoundHandler> classNotFoundHandlers;
+
+   /** The class found handlers */
+   private List<ClassFoundHandler> classFoundHandlers;
+   
    /**
     * Get the delegate loader for exported stuff<p>
     *
@@ -237,7 +244,116 @@
          return getSystemClassLoader();
       return null;
    }
+   
+   /**
+    * Add a ClassNotFoundHandler
+    * 
+    * @param handler the handler
+    */
+   public void addClassNotFoundHandler(ClassNotFoundHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classNotFoundHandlers == null)
+         classNotFoundHandlers = new CopyOnWriteArrayList<ClassNotFoundHandler>();
+      
+      classNotFoundHandlers.add(handler);
+   }
+   
+   /**
+    * Remove a ClassNotFoundHandler
+    * 
+    * @param handler the handler
+    */
+   public void removeClassNotFoundHandler(ClassNotFoundHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classNotFoundHandlers == null)
+         return;
+      classNotFoundHandlers.remove(handler);
+   }
 
+   public boolean classNotFound(ClassNotFoundEvent event)
+   {
+      if (classNotFoundHandlers != null && classNotFoundHandlers.isEmpty() == false)
+      {
+         for (ClassNotFoundHandler handler : classNotFoundHandlers)
+         {
+            try
+            {
+               if (handler.classNotFound(event))
+                  return true;
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error invoking classNotFoundHandler: " + handler, t);
+            }
+         }
+      }
+      
+      ClassLoaderDomain domain = getDomain();
+      if (domain == null)
+         return false;
+      return domain.classNotFound(event);
+   }
+   
+   /**
+    * Add a ClassFoundHandler
+    * 
+    * @param handler the handler
+    */
+   public void addClassFoundHandler(ClassFoundHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classFoundHandlers == null)
+         classFoundHandlers = new CopyOnWriteArrayList<ClassFoundHandler>();
+      
+      classFoundHandlers.add(handler);
+   }
+   
+   /**
+    * Remove a ClassFoundHandler
+    * 
+    * @param handler the handler
+    */
+   public void removeClassFoundHandler(ClassFoundHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classFoundHandlers == null)
+         return;
+      classFoundHandlers.remove(handler);
+   }
+
+   public void classFound(ClassFoundEvent event)
+   {
+      if (classFoundHandlers != null && classFoundHandlers.isEmpty() == false)
+      {
+         for (ClassFoundHandler handler : classFoundHandlers)
+         {
+            try
+            {
+               handler.classFound(event);
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error invoking classFoundHandler: " + handler, t);
+            }
+         }
+      }
+      
+      ClassLoaderDomain domain = getDomain();
+      if (domain == null)
+         return;
+      domain.classFound(event);
+   }
+
    @Override
    public ObjectName getObjectName()
    {

Modified: projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystem.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystem.java	2009-11-18 16:54:13 UTC (rev 96496)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystem.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -31,6 +31,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 import javax.management.MBeanRegistration;
 import javax.management.MBeanServer;
@@ -50,7 +51,7 @@
  * @author <a href="ales.justin at jboss.com">Ales Justin</a>
  * @version $Revision: 1.1 $
  */
-public abstract class ClassLoaderSystem extends BaseClassLoaderSystem implements ClassLoaderSystemMBean, MBeanRegistration
+public abstract class ClassLoaderSystem extends BaseClassLoaderSystem implements ClassLoaderSystemMBean, MBeanRegistration, ClassNotFoundHandler, ClassFoundHandler, ClassLoaderEventHandler
 {
    /** The log */
    private static final Logger log = Logger.getLogger(ClassLoaderSystem.class);
@@ -78,6 +79,15 @@
    
    /** The object name */
    private ObjectName objectName;
+
+   /** The class not found handlers */
+   private List<ClassNotFoundHandler> classNotFoundHandlers;
+
+   /** The class found handlers */
+   private List<ClassFoundHandler> classFoundHandlers;
+
+   /** The class loader event handlers */
+   private List<ClassLoaderEventHandler> classLoaderEventHandlers;
    
    /**
     * Get the classloading system instance
@@ -686,7 +696,174 @@
          log.warn("Error unregistering domain: " + domain, e);
       }
    }
+   
+   /**
+    * Add a ClassNotFoundHandler
+    * 
+    * @param handler the handler
+    */
+   public void addClassNotFoundHandler(ClassNotFoundHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classNotFoundHandlers == null)
+         classNotFoundHandlers = new CopyOnWriteArrayList<ClassNotFoundHandler>();
+      
+      classNotFoundHandlers.add(handler);
+   }
+   
+   /**
+    * Remove a ClassNotFoundHandler
+    * 
+    * @param handler the handler
+    */
+   public void removeClassNotFoundHandler(ClassNotFoundHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classNotFoundHandlers == null)
+         return;
+      classNotFoundHandlers.remove(handler);
+   }
 
+   public boolean classNotFound(ClassNotFoundEvent event)
+   {
+      if (classNotFoundHandlers != null && classNotFoundHandlers.isEmpty() == false)
+      {
+         for (ClassNotFoundHandler handler : classNotFoundHandlers)
+         {
+            try
+            {
+               if (handler.classNotFound(event))
+                  return true;
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error invoking classNotFoundHandler: " + handler, t);
+            }
+         }
+      }
+      return false;
+   }
+   
+   /**
+    * Add a ClassFoundHandler
+    * 
+    * @param handler the handler
+    */
+   public void addClassFoundHandler(ClassFoundHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classFoundHandlers == null)
+         classFoundHandlers = new CopyOnWriteArrayList<ClassFoundHandler>();
+      
+      classFoundHandlers.add(handler);
+   }
+   
+   /**
+    * Remove a ClassFoundHandler
+    * 
+    * @param handler the handler
+    */
+   public void removeClassFoundHandler(ClassFoundHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classFoundHandlers == null)
+         return;
+      classFoundHandlers.remove(handler);
+   }
+
+   public void classFound(ClassFoundEvent event)
+   {
+      if (classFoundHandlers != null && classFoundHandlers.isEmpty() == false)
+      {
+         for (ClassFoundHandler handler : classFoundHandlers)
+         {
+            try
+            {
+               handler.classFound(event);
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error invoking classFoundHandler: " + handler, t);
+            }
+         }
+      }
+   }
+   
+   /**
+    * Add a ClassLoaderEventHandler
+    * 
+    * @param handler the handler
+    */
+   public void addClassLoaderEventHandler(ClassLoaderEventHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classLoaderEventHandlers == null)
+         classLoaderEventHandlers = new CopyOnWriteArrayList<ClassLoaderEventHandler>();
+      
+      classLoaderEventHandlers.add(handler);
+   }
+   
+   /**
+    * Remove a ClassLoaderEventHandler
+    * 
+    * @param handler the handler
+    */
+   public void removeClassLoaderEventHandler(ClassLoaderEventHandler handler)
+   {
+      if (handler == null)
+         throw new IllegalArgumentException("Null handler");
+      
+      if (classLoaderEventHandlers == null)
+         return;
+      classLoaderEventHandlers.remove(handler);
+   }
+
+   public void fireRegisterClassLoader(ClassLoaderEvent event)
+   {
+      if (classLoaderEventHandlers != null && classLoaderEventHandlers.isEmpty() == false)
+      {
+         for (ClassLoaderEventHandler handler : classLoaderEventHandlers)
+         {
+            try
+            {
+               handler.fireRegisterClassLoader(event);
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error invoking classLoaderEventHandler: " + handler, t);
+            }
+         }
+      }
+   }
+
+   public void fireUnregisterClassLoader(ClassLoaderEvent event)
+   {
+      if (classLoaderEventHandlers != null && classLoaderEventHandlers.isEmpty() == false)
+      {
+         for (ClassLoaderEventHandler handler : classLoaderEventHandlers)
+         {
+            try
+            {
+               handler.fireUnregisterClassLoader(event);
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error invoking classLoaderEventHandler: " + handler, t);
+            }
+         }
+      }
+   }
+
    @Override
    protected void toLongString(StringBuilder builder)
    {

Added: projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundEvent.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundEvent.java	                        (rev 0)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundEvent.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -0,0 +1,77 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloader.spi;
+
+import java.util.EventObject;
+
+/**
+ * ClassNotFoundEvent.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassNotFoundEvent extends EventObject
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 7445562838711417089L;
+
+   /** The class name */
+   private String className;
+   
+   /**
+    * Create a new ClassNotFoundEvent.
+    * 
+    * @param classLoader the classLoader
+    * @param className the class name
+    */
+   public ClassNotFoundEvent(ClassLoader classLoader, String className)
+   {
+      super(classLoader);
+      this.className = className;
+   }
+
+   /**
+    * Get the className.
+    * 
+    * @return the className.
+    */
+   public String getClassName()
+   {
+      return className;
+   }
+
+   /**
+    * Get the classLoader.
+    * 
+    * @return the classLoader
+    */
+   public ClassLoader getClassLoader()
+   {
+      return (ClassLoader) getSource();
+   }
+
+   @Override
+   public String toString()
+   {
+      return getClass().getSimpleName() + "[classLoader=" + getClassLoader() + " class=" + getClassName() + "]";
+   }
+}

Added: projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundHandler.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundHandler.java	                        (rev 0)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundHandler.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -0,0 +1,39 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloader.spi;
+
+/**
+ * ClassNotFoundHandler.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface ClassNotFoundHandler
+{
+   /**
+    * Fired when a class is not found
+    * 
+    * @param event the event
+    * @return true when the a retry of the classloading should be tried
+    */
+   boolean classNotFound(ClassNotFoundEvent event);
+}

Modified: projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoader.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoader.java	2009-11-18 16:54:13 UTC (rev 96496)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoader.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -46,8 +46,10 @@
 import javax.management.ObjectName;
 
 import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.ClassFoundEvent;
 import org.jboss.classloader.spi.ClassLoaderDomain;
 import org.jboss.classloader.spi.ClassLoaderPolicy;
+import org.jboss.classloader.spi.ClassNotFoundEvent;
 import org.jboss.classloader.spi.DelegateLoader;
 import org.jboss.classloader.spi.Loader;
 import org.jboss.classloader.spi.PackageInformation;
@@ -435,6 +437,58 @@
       if (result != null)
          return result;
 
+      // Try to load the class
+      ClassNotFoundException exception = null;
+      try
+      {
+         result = doLoadClass(name, resolve, trace);
+      }
+      catch (ClassNotFoundException e)
+      {
+         exception = e;
+      }
+      
+      // If we failed, try any class not found handlers and retry if one says it is resolved
+      if (result == null)
+      {
+         ClassLoaderPolicy policy = getPolicy();
+         if (policy != null && policy.classNotFound(new ClassNotFoundEvent(this, name)))
+         {
+            try
+            {
+               result = doLoadClass(name, resolve, trace);
+            }
+            catch (ClassNotFoundException e)
+            {
+               exception = e;
+            }
+         }
+      }
+      
+      if (result == null)
+      {
+         if (trace)
+            log.trace(this + " class not found " + name);
+         if (exception != null)
+            throw exception;
+         throw new ClassNotFoundException(name + " from " + toString());
+      }
+      return result;
+   }
+
+   /**
+    * Do the load class
+    * 
+    * @param name the name
+    * @param resolve whether to resolve
+    * @param trace whether trace is enabled
+    * @return the class or null if not found
+    * @throws ClassNotFoundException if a problem is raised
+    */
+   protected Class<?> doLoadClass(String name, boolean resolve, boolean trace) throws ClassNotFoundException
+   {
+      Class<?> result = null;
+      
       synchronized (this)
       {
          // JBCL-114: did we lose the race to the synchronized?
@@ -446,11 +500,7 @@
 
          // Still not found
          if (result == null)
-         {
-            if (trace)
-               log.trace(this + " class not found " + name);
-            throw new ClassNotFoundException(name + " from " + toLongString());
-         }
+            return null;
 
          // Link the class if requested
          if (resolve)
@@ -584,6 +634,7 @@
       }, policy.getAccessControlContext());
 
       loadedClasses.put(name, name);
+      policy.classFound(new ClassFoundEvent(this, result));
 
       return result;
    }
@@ -906,6 +957,7 @@
    protected void shutdownClassLoader()
    {
       log.debug(toString() + " shutdown!");
+      loadedClasses.clear();
       if (resourceCache != null)
          resourceCache.clear();
       if (blackList != null)
@@ -1083,7 +1135,7 @@
          }
       }
    }
-
+   
    /**
     * Get the classloader for a class
     *

Modified: projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java	2009-11-18 16:54:13 UTC (rev 96496)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -1195,6 +1195,23 @@
    }
 
    /**
+    * Get the classloader policy associated with an object
+    * 
+    * @param object the  object
+    * @return the classloader policy or null if one is not associated
+    */
+   protected ClassLoaderPolicy getClassLoaderPolicy(Object object)
+   {
+      if (object instanceof BaseClassLoader)
+         return ((BaseClassLoader) object).getPolicy();
+      
+      if (object instanceof BaseClassLoaderSource)
+         return getClassLoaderPolicy(((BaseClassLoaderSource) object).getClassLoader());
+      
+      return null;
+   }
+   
+   /**
     * A long version of toString()
     * 
     * @return the long string

Modified: projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java	2009-11-18 16:54:13 UTC (rev 96496)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -256,6 +256,16 @@
     * 
     * @return the domain
     */
+   protected ClassLoaderDomain getDomain()
+   {
+      return (ClassLoaderDomain) getClassLoaderDomain();
+   }
+   
+   /**
+    * Get the classloader domain
+    * 
+    * @return the domain
+    */
    BaseClassLoaderDomain getClassLoaderDomain()
    {
       return domain;

Modified: projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/ClassLoaderAllTestSuite.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/ClassLoaderAllTestSuite.java	2009-11-18 16:54:13 UTC (rev 96496)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/ClassLoaderAllTestSuite.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -30,6 +30,7 @@
 import org.jboss.test.classloader.filter.FilterTestSuite;
 import org.jboss.test.classloader.jmx.JMXTestSuite;
 import org.jboss.test.classloader.junit.JUnitTestSuite;
+import org.jboss.test.classloader.notifications.ClassLoaderNotificationsTestSuite;
 import org.jboss.test.classloader.old.OldTestSuite;
 import org.jboss.test.classloader.policy.test.ClassLoaderPolicyUnitTestCase;
 import org.jboss.test.classloader.resources.ResourceTestSuite;
@@ -75,6 +76,7 @@
       suite.addTest(JMXTestSuite.suite());
       suite.addTest(JUnitTestSuite.suite());
       suite.addTest(TransformTestSuite.suite());
+      suite.addTest(ClassLoaderNotificationsTestSuite.suite());
 
       return suite;
    }

Modified: projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java	2009-11-18 16:54:13 UTC (rev 96496)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -29,9 +29,11 @@
 import junit.framework.Test;
 
 import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.ClassFoundHandler;
 import org.jboss.classloader.spi.ClassLoaderDomain;
 import org.jboss.classloader.spi.ClassLoaderDomainMBean;
 import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.spi.ClassNotFoundHandler;
 import org.jboss.classloader.spi.Loader;
 import org.jboss.classloader.spi.ParentPolicy;
 import org.jboss.classloader.spi.base.BaseClassLoaderDomain;
@@ -159,7 +161,7 @@
       ClassLoader classLoader = system.registerClassLoaderPolicy(domain, policy);
       
       assertLoadClass(ClassLoaderDomain.class, classLoader);
-      checkGetResource(loader, ClassLoaderDomain.class, BaseClassLoaderDomain.class, ClassLoaderDomainMBean.class, MBeanRegistration.class, Loader.class, Object.class);
+      checkGetResource(loader, ClassLoaderDomain.class, BaseClassLoaderDomain.class, ClassLoaderDomainMBean.class, MBeanRegistration.class, Loader.class, ClassNotFoundHandler.class, ClassFoundHandler.class, Object.class);
       checkLoadClass(loader);
    }
    

Added: projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/ClassLoaderNotificationsTestSuite.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/ClassLoaderNotificationsTestSuite.java	                        (rev 0)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/ClassLoaderNotificationsTestSuite.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloader.notifications;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import org.jboss.test.classloader.notifications.test.ClassFoundHandlerUnitTestCase;
+import org.jboss.test.classloader.notifications.test.ClassLoaderEventHandlerUnitTestCase;
+import org.jboss.test.classloader.notifications.test.ClassNotFoundHandlerUnitTestCase;
+
+/**
+ * Notifications Test Suite.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 37459 $
+ */
+public class ClassLoaderNotificationsTestSuite extends TestSuite
+{
+   /**
+    * For running the testsuite from the command line
+    * 
+    * @param args the command line args
+    */
+   public static void main(String[] args)
+   {
+      TestRunner.run(suite());
+   }
+
+   /**
+    * Create the testsuite
+    * 
+    * @return the testsuite
+    */
+   public static Test suite()
+   {
+      TestSuite suite = new TestSuite("Notifications Tests");
+
+      suite.addTest(ClassLoaderEventHandlerUnitTestCase.suite());
+      suite.addTest(ClassNotFoundHandlerUnitTestCase.suite());
+      suite.addTest(ClassFoundHandlerUnitTestCase.suite());
+      
+      return suite;
+   }
+}

Added: projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/support/a/A.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/support/a/A.java	                        (rev 0)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/support/a/A.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -0,0 +1,32 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.classloader.notifications.support.a;
+
+/**
+ * A.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class A
+{
+}

Added: projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassFoundHandlerUnitTestCase.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassFoundHandlerUnitTestCase.java	                        (rev 0)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassFoundHandlerUnitTestCase.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -0,0 +1,286 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloader.notifications.test;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import junit.framework.Test;
+
+import org.jboss.classloader.plugins.loader.ClassLoaderToLoaderAdapter;
+import org.jboss.classloader.spi.ClassFoundEvent;
+import org.jboss.classloader.spi.ClassFoundHandler;
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.spi.ParentPolicy;
+import org.jboss.classloader.test.support.MockClassLoaderPolicy;
+import org.jboss.test.classloader.AbstractClassLoaderTestWithSecurity;
+import org.jboss.test.classloader.notifications.support.a.A;
+
+/**
+ * ClassFoundHnadlerUnitTestCase
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassFoundHandlerUnitTestCase extends AbstractClassLoaderTestWithSecurity implements ClassFoundHandler
+{
+   public static Test suite()
+   {
+      return suite(ClassFoundHandlerUnitTestCase.class);
+   }
+
+   public ClassFoundHandlerUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   List<ClassFoundEvent> events = new CopyOnWriteArrayList<ClassFoundEvent>();
+   
+   public void classFound(ClassFoundEvent event)
+   {
+      events.add(event);
+   }
+
+   public void testClassFoundHandlerPolicy() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setPathsAndPackageNames(A.class);
+      policy.addClassFoundHandler(this);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      assertLoadClass(A.class, cl);
+      assertLoadClassNoEvent(A.class, cl);
+   }
+
+   public void testClassFoundHandlerDomain() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain domain = system.getDefaultDomain();
+      domain.addClassFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setPathsAndPackageNames(A.class);
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      assertLoadClass(A.class, cl);
+      assertLoadClassNoEvent(A.class, cl);
+   }
+
+   public void testClassFoundHandlerParentDomain() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, defaultDomain);
+      defaultDomain.addClassFoundHandler(this);
+
+      MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+      parentPolicy.setPathsAndPackageNames(A.class);
+      ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      assertLoadClass(A.class, cl, parentCl);
+      assertLoadClassNoEvent(A.class, cl, parentCl);
+   }
+
+   public void testClassFoundHandlerParentClassLoader() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      defaultDomain.addClassFoundHandler(this);
+
+      MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+      parentPolicy.setPathsAndPackageNames(A.class);
+      ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+      ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, new ClassLoaderToLoaderAdapter(parentCl));
+      domain.setUseLoadClassForParent(false);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      assertLoadClass(A.class, cl, parentCl);
+      assertLoadClassNoEvent(A.class, cl, parentCl);
+   }
+
+   public void testClassFoundHandlerSystem() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      system.addClassFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setPathsAndPackageNames(A.class);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      assertLoadClass(A.class, cl);
+      assertLoadClassNoEvent(A.class, cl);
+   }
+
+   public void testClassFoundHandlerPolicyNoEvent() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setPathsAndPackageNames(A.class);
+      policy.addClassFoundHandler(this);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      assertLoadClassFail("does.not.exist.Class", cl);
+   }
+
+   public void testClassFoundHandlerDomainNoEvent() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain domain = system.getDefaultDomain();
+      domain.addClassFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setPathsAndPackageNames(A.class);
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      assertLoadClassFail("does.not.exist.Class", cl);
+   }
+
+   public void testClassFoundHandlerParentDomainNoEvent() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, defaultDomain);
+      defaultDomain.addClassFoundHandler(this);
+
+      MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+      parentPolicy.setPathsAndPackageNames(A.class);
+      system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      assertLoadClassFail("does.not.exist.Class", cl);
+   }
+
+   public void testClassFoundHandlerParentClassLoaderNoEvent() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      defaultDomain.addClassFoundHandler(this);
+
+      MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+      parentPolicy.setPathsAndPackageNames(A.class);
+      ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+      ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, new ClassLoaderToLoaderAdapter(parentCl));
+      domain.setUseLoadClassForParent(false);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      assertLoadClassFail("does.not.exist.Class", cl);
+   }
+
+   public void testClassFoundHandlerSystemNoEvent() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      system.addClassFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setPathsAndPackageNames(A.class);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      assertLoadClassFail("does.not.exist.Class", cl);
+   }
+
+   public void testClassFoundHandlerWrongPolicy() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setImportAll(true);
+      policy.addClassFoundHandler(this);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+      a.setPathsAndPackageNames(A.class);
+      ClassLoader clA = system.registerClassLoaderPolicy(a);
+
+      assertLoadClassNoEvent(A.class, cl, clA);
+   }
+
+   public void testClassFoundHandlerDifferentPolicy() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setImportAll(true);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+      a.setPathsAndPackageNames(A.class);
+      a.addClassFoundHandler(this);
+      ClassLoader clA = system.registerClassLoaderPolicy(a);
+
+      assertLoadClass(A.class, cl, clA);
+      assertLoadClassNoEvent(A.class, cl, clA);
+   }
+
+   protected Class<?> assertLoadClassNoEvent(Class<?> reference, ClassLoader start)
+   {
+      return assertLoadClass(reference, start, start);
+   }
+
+   protected Class<?> assertLoadClassNoEvent(Class<?> reference, ClassLoader start, ClassLoader expected)
+   {
+      Class<?> result = super.assertLoadClass(reference, start, expected);
+      assertNoEvent();
+      return result;
+   }
+
+   protected Class<?> assertLoadClass(Class<?> reference, ClassLoader start, ClassLoader expected)
+   {
+      Class<?> result = super.assertLoadClass(reference, start, expected);
+      assertEvent(reference.getName(), expected);
+      return result;
+   }
+
+   protected void assertLoadClassFail(String name, ClassLoader start)
+   {
+      super.assertLoadClassFail(name, start);
+      assertNoEvent();
+   }
+
+   protected void assertEvent(String name, ClassLoader expected)
+   {
+      assertTrue("Expected an event", events.isEmpty() == false);
+      ClassFoundEvent event = events.remove(0);
+      assertEquals(name, event.getClassName());
+      assertEquals(expected, event.getClassLoader());
+      assertEquals(expected, event.getSource());
+   }
+
+   protected void assertNoEvent()
+   {
+      assertTrue("Expected no events: " + events, events.isEmpty());
+   }
+}

Added: projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassLoaderEventHandlerUnitTestCase.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassLoaderEventHandlerUnitTestCase.java	                        (rev 0)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassLoaderEventHandlerUnitTestCase.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -0,0 +1,186 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloader.notifications.test;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import junit.framework.Test;
+
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderEvent;
+import org.jboss.classloader.spi.ClassLoaderEventHandler;
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.test.support.MockClassLoaderPolicy;
+import org.jboss.test.classloader.AbstractClassLoaderTestWithSecurity;
+
+/**
+ * ClassFoundHnadlerUnitTestCase
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassLoaderEventHandlerUnitTestCase extends AbstractClassLoaderTestWithSecurity implements ClassLoaderEventHandler
+{
+   public static Test suite()
+   {
+      return suite(ClassLoaderEventHandlerUnitTestCase.class);
+   }
+
+   public ClassLoaderEventHandlerUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   List<ClassLoaderEvent> registered = new CopyOnWriteArrayList<ClassLoaderEvent>();
+   List<ClassLoaderEvent> unregistered = new CopyOnWriteArrayList<ClassLoaderEvent>();
+   
+   public void fireRegisterClassLoader(ClassLoaderEvent event)
+   {
+      registered.add(event);
+   }
+   
+   public void fireUnregisterClassLoader(ClassLoaderEvent event)
+   {
+      unregistered.add(event);
+   }
+
+   public void testClassLoaderEventDomain() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain domain = system.getDefaultDomain();
+      domain.addClassLoaderEventHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      assertRegistered(domain, cl);
+      
+      system.unregisterClassLoader(cl);
+      assertUnregistered(domain, cl);
+   }
+
+   public void testClassLoaderEventSystem() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain domain = system.getDefaultDomain();
+      system.addClassLoaderEventHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      assertRegistered(domain, cl);
+      
+      system.unregisterClassLoader(cl);
+      assertUnregistered(domain, cl);
+   }
+
+   public void testClassLoaderEventWrongDomain() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain domain1 = system.createAndRegisterDomain("Domain1");
+      ClassLoaderDomain domain2 = system.createAndRegisterDomain("Domain2");
+      domain1.addClassLoaderEventHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain2, policy);
+
+      assertNoRegistered();
+      
+      system.unregisterClassLoader(cl);
+      assertNoUnregistered();
+   }
+
+   public void testClassLoaderEventCorrectDomain() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      system.createAndRegisterDomain("Domain1");
+      ClassLoaderDomain domain2 = system.createAndRegisterDomain("Domain2");
+      domain2.addClassLoaderEventHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain2, policy);
+
+      assertRegistered(domain2, cl);
+      
+      system.unregisterClassLoader(cl);
+      assertUnregistered(domain2, cl);
+   }
+
+   public void testClassLoaderEventShutdownDomain() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain domain = system.getDefaultDomain();
+      domain.addClassLoaderEventHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      assertRegistered(domain, cl);
+      
+      system.shutdown();
+      assertUnregistered(domain, cl);
+   }
+
+   public void testClassLoaderEventShutdownSystem() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain domain = system.getDefaultDomain();
+      system.addClassLoaderEventHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      assertRegistered(domain, cl);
+      
+      system.shutdown();
+      assertUnregistered(domain, cl);
+   }
+
+   protected void assertRegistered(ClassLoaderDomain domain, ClassLoader expected)
+   {
+      assertTrue("Expected a registered", registered.isEmpty() == false);
+      ClassLoaderEvent event = registered.remove(0);
+      assertEquals(domain, event.getClassLoaderDomain());
+      assertEquals(domain, event.getSource());
+      assertEquals(expected, event.getClassLoader());
+   }
+
+   protected void assertNoRegistered()
+   {
+      assertTrue("Expected no registered: " + registered, registered.isEmpty());
+   }
+
+   protected void assertUnregistered(ClassLoaderDomain domain, ClassLoader expected)
+   {
+      assertTrue("Expected an unregistered", unregistered.isEmpty() == false);
+      ClassLoaderEvent event = unregistered.remove(0);
+      assertEquals(domain, event.getClassLoaderDomain());
+      assertEquals(domain, event.getSource());
+      assertEquals(expected, event.getClassLoader());
+   }
+
+   protected void assertNoUnregistered()
+   {
+      assertTrue("Expected no unregistered: " + unregistered, unregistered.isEmpty());
+   }
+}

Added: projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassNotFoundHandlerUnitTestCase.java
===================================================================
--- projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassNotFoundHandlerUnitTestCase.java	                        (rev 0)
+++ projects/jboss-cl/branches/Branch_2_0/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassNotFoundHandlerUnitTestCase.java	2009-11-18 16:55:47 UTC (rev 96497)
@@ -0,0 +1,484 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloader.notifications.test;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import junit.framework.Test;
+
+import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.plugins.loader.ClassLoaderToLoaderAdapter;
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderPolicy;
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.spi.ClassNotFoundEvent;
+import org.jboss.classloader.spi.ClassNotFoundHandler;
+import org.jboss.classloader.spi.ParentPolicy;
+import org.jboss.classloader.test.support.MockClassLoaderPolicy;
+import org.jboss.test.classloader.AbstractClassLoaderTestWithSecurity;
+import org.jboss.test.classloader.notifications.support.a.A;
+
+/**
+ * ClassNotFoundHnadlerUnitTestCase
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassNotFoundHandlerUnitTestCase extends AbstractClassLoaderTestWithSecurity implements ClassNotFoundHandler
+{
+   public static Test suite()
+   {
+      return suite(ClassNotFoundHandlerUnitTestCase.class);
+   }
+
+   public ClassNotFoundHandlerUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   List<ClassNotFoundEvent> events = new CopyOnWriteArrayList<ClassNotFoundEvent>();
+   
+   RegisterClassLoader runnable = null;
+   
+   public boolean classNotFound(ClassNotFoundEvent event)
+   {
+      events.add(event);
+
+      if (runnable != null)
+      {
+         runnable.run();
+         return true;
+      }
+      return false;
+   }
+
+   public void testClassNotFoundHandlerPolicy() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.addClassNotFoundHandler(this);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      assertLoadClassFail("does.not.exist.ClassName", cl);
+   }
+
+   public void testClassNotFoundHandlerDomain() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain domain = system.getDefaultDomain();
+      domain.addClassNotFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      assertLoadClassFail("does.not.exist.ClassName", cl);
+   }
+
+   public void testClassNotFoundHandlerSystem() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      system.addClassNotFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      assertLoadClassFail("does.not.exist.ClassName", cl);
+   }
+
+   public void testClassNotFoundHandlerParentDomain() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, defaultDomain);
+      domain.addClassNotFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      assertLoadClassFail("does.not.exist.ClassName", cl);
+   }
+
+   public void testClassNotFoundHandlerParentClassLoader() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+
+      MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+      parentPolicy.addClassNotFoundHandler(this);
+      ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+      ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, new ClassLoaderToLoaderAdapter(parentCl));
+      domain.setUseLoadClassForParent(false);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      assertLoadClassFail("does.not.exist.ClassName", cl);
+   }
+
+   public void testClassNotFoundHandlerPolicyNoEvent() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setImportAll(true);
+      policy.addClassNotFoundHandler(this);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+      a.setPathsAndPackageNames(A.class);
+      ClassLoader expected = system.registerClassLoaderPolicy(a);
+
+      assertLoadClassNoEvent(A.class, cl, expected);
+   }
+
+   public void testClassNotFoundHandlerDomainNoEvent() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain domain = system.getDefaultDomain();
+      domain.addClassNotFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setImportAll(true);
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+      a.setPathsAndPackageNames(A.class);
+      ClassLoader expected = system.registerClassLoaderPolicy(a);
+
+      assertLoadClassNoEvent(A.class, cl, expected);
+   }
+
+   public void testClassNotFoundHandlerParentDomainNoEvent() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, defaultDomain);
+      domain.addClassNotFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+      a.setPathsAndPackageNames(A.class);
+      ClassLoader expected = system.registerClassLoaderPolicy(a);
+
+      assertLoadClassNoEvent(A.class, cl, expected);
+   }
+
+   public void testClassNotFoundHandlerParentClassLoaderNoEvent() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+
+      MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+      parentPolicy.setImportAll(true);
+      parentPolicy.addClassNotFoundHandler(this);
+      ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+      ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, new ClassLoaderToLoaderAdapter(parentCl));
+      domain.setUseLoadClassForParent(false);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+      a.setPathsAndPackageNames(A.class);
+      ClassLoader expected = system.registerClassLoaderPolicy(a);
+
+      assertLoadClassNoEvent(A.class, cl, expected);
+   }
+
+   public void testClassNotFoundHandlerSystemNoEvent() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      system.addClassNotFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setImportAll(true);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+      a.setPathsAndPackageNames(A.class);
+      ClassLoader expected = system.registerClassLoaderPolicy(a);
+
+      assertLoadClassNoEvent(A.class, cl, expected);
+   }
+
+   public void testClassNotFoundHandlerPolicyResolved() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setImportAll(true);
+      policy.addClassNotFoundHandler(this);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+      resolved.setPathsAndPackageNames(A.class);
+      runnable = new RegisterClassLoader(system, null, resolved);
+      assertLoadClass(A.class, cl, runnable);
+      assertLoadClassNoEvent(A.class, cl, runnable.getClassLoader());
+   }
+
+   public void testClassNotFoundHandlerDomainResolved() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain domain = system.getDefaultDomain();
+      domain.addClassNotFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setImportAll(true);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+      resolved.setPathsAndPackageNames(A.class);
+      runnable = new RegisterClassLoader(system, domain, resolved);
+      assertLoadClassFail("does.not.exist.ClassName", cl);
+      assertLoadClassNoEvent(A.class, cl, runnable.getClassLoader());
+   }
+
+   public void testClassNotFoundHandlerParentDomainResolved() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, defaultDomain);
+      domain.addClassNotFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+      resolved.setPathsAndPackageNames(A.class);
+      runnable = new RegisterClassLoader(system, null, resolved);
+      assertLoadClass(A.class, cl, runnable);
+      assertLoadClassNoEvent(A.class, cl, runnable.getClassLoader());
+   }
+
+   public void testClassNotFoundHandlerParentClassLoaderResolved() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+
+      MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+      parentPolicy.setImportAll(true);
+      parentPolicy.addClassNotFoundHandler(this);
+      ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+      ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, new ClassLoaderToLoaderAdapter(parentCl));
+      domain.setUseLoadClassForParent(false);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+      resolved.setPathsAndPackageNames(A.class);
+      runnable = new RegisterClassLoader(system, null, resolved);
+      assertLoadClass(A.class, cl, runnable);
+      assertLoadClassNoEvent(A.class, cl, runnable.getClassLoader());
+   }
+
+   public void testClassNotFoundHandlerSystemResolved() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      system.addClassNotFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setImportAll(true);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+      resolved.setPathsAndPackageNames(A.class);
+      runnable = new RegisterClassLoader(system, null, resolved);
+      assertLoadClass(A.class, cl, runnable);
+      assertLoadClassNoEvent(A.class, cl, runnable.getClassLoader());
+   }
+
+   public void testClassNotFoundHandlerPolicyNotResolved() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setImportAll(true);
+      policy.addClassNotFoundHandler(this);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+      resolved.setPathsAndPackageNames(A.class);
+      runnable = new RegisterClassLoader(system, null, resolved);
+      assertLoadClassFail("does.not.exist.ClassName", cl);
+   }
+
+   public void testClassNotFoundHandlerDomainNotResolved() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain domain = system.getDefaultDomain();
+      domain.addClassNotFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setImportAll(true);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+      resolved.setPathsAndPackageNames(A.class);
+      runnable = new RegisterClassLoader(system, domain, resolved);
+      assertLoadClassFail("does.not.exist.ClassName", cl);
+   }
+
+   public void testClassNotFoundHandlerParentDomainNotResolved() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, defaultDomain);
+      domain.addClassNotFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+      resolved.setPathsAndPackageNames(A.class);
+      runnable = new RegisterClassLoader(system, null, resolved);
+      assertLoadClassFail("does.not.exist.ClassName", cl);
+   }
+
+   public void testClassNotFoundHandlerParentClassLoaderNotResolved() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+
+      MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+      parentPolicy.setImportAll(true);
+      parentPolicy.addClassNotFoundHandler(this);
+      ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+      ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, new ClassLoaderToLoaderAdapter(parentCl));
+      domain.setUseLoadClassForParent(false);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+      MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+      resolved.setPathsAndPackageNames(A.class);
+      runnable = new RegisterClassLoader(system, null, resolved);
+      assertLoadClassFail("does.not.exist.ClassName", cl);
+   }
+
+   public void testClassNotFoundHandlerSystemNotResolved() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      system.addClassNotFoundHandler(this);
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+      policy.setImportAll(true);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+      resolved.setPathsAndPackageNames(A.class);
+      runnable = new RegisterClassLoader(system, null, resolved);
+      assertLoadClassFail("does.not.exist.ClassName", cl);
+   }
+
+   protected Class<?> assertLoadClassNoEvent(Class<?> reference, ClassLoader start, ClassLoader expected)
+   {
+      Class<?> result = assertLoadClass(reference, start, expected);
+      assertNoEvent();
+      return result;
+   }
+
+   protected Class<?> assertLoadClass(Class<?> reference, ClassLoader start, RegisterClassLoader runnable)
+   {
+      return assertLoadClass(reference, start, runnable, false);
+   }
+
+   protected Class<?> assertLoadClass(Class<?> reference, ClassLoader start, RegisterClassLoader runnable, boolean isReference)
+   {
+      String name = reference.getName();
+      Class<?> result = null;
+      try
+      {
+         result = start.loadClass(name);
+         getLog().debug("Got class: " + ClassLoaderUtils.classToString(result) + " for " + name + " from " + start);
+      }
+      catch (ClassNotFoundException e)
+      {
+         failure("Did not expect CNFE for " + name + " from " + start, e);
+      }
+      assertClassLoader(result, runnable.getClassLoader());
+      if (isReference)
+         assertClassEquality(reference, result);
+      else
+         assertNoClassEquality(reference, result);
+      assertEvent(name, start);
+      return result;
+   }
+
+   protected void assertLoadClassFail(String name, ClassLoader start)
+   {
+      super.assertLoadClassFail(name, start);
+      assertEvent(name, start);
+   }
+
+   protected void assertEvent(String name, ClassLoader start)
+   {
+      assertTrue("Expected an event", events.isEmpty() == false);
+      ClassNotFoundEvent event = events.remove(0);
+      assertEquals(name, event.getClassName());
+      assertEquals(start, event.getClassLoader());
+      assertEquals(start, event.getSource());
+   }
+
+   protected void assertNoEvent()
+   {
+      assertTrue("Expected no events: " + events, events.isEmpty());
+   }
+   
+   class RegisterClassLoader implements Runnable
+   {
+      private ClassLoaderSystem system;
+      private ClassLoaderDomain domain;
+      private ClassLoaderPolicy policy;
+      private ClassLoader classLoader;
+      
+      public RegisterClassLoader(ClassLoaderSystem system, ClassLoaderDomain domain, ClassLoaderPolicy policy)
+      {
+         this.system = system;
+         if (domain == null)
+            domain = system.getDefaultDomain();
+         this.domain = domain;
+         this.policy = policy;
+      }
+      
+      public void run()
+      {
+         classLoader = system.registerClassLoaderPolicy(domain, policy);
+      }
+      
+      public ClassLoader getClassLoader()
+      {
+         if (classLoader == null)
+            throw new Error("No classloader registered");
+         return classLoader;
+      }
+   }
+}




More information about the jboss-cvs-commits mailing list