[jboss-cvs] JBossAS SVN: r70070 - in projects/microcontainer/trunk/classloader/src: main/org/jboss/classloader/spi/base and 5 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Feb 25 18:31:55 EST 2008


Author: adrian at jboss.org
Date: 2008-02-25 18:31:55 -0500 (Mon, 25 Feb 2008)
New Revision: 70070

Added:
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomainMBean.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderSystemMBean.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/support/a/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/support/a/A.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/support/b/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/support/b/B.java
Modified:
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomain.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderPolicy.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderSystem.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoader.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderMBean.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoaderInformation.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/test/JMXUnitTestCase.java
Log:
[JBMICROCONT-241] - JMX operations for the classloaders, etc.

Modified: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomain.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomain.java	2008-02-25 23:00:32 UTC (rev 70069)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomain.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -25,12 +25,22 @@
 import java.net.URL;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.Map.Entry;
 
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
 import org.jboss.classloader.plugins.loader.ClassLoaderToLoaderAdapter;
 import org.jboss.classloader.spi.base.BaseClassLoaderDomain;
 import org.jboss.classloader.spi.filter.ClassFilter;
+import org.jboss.classloading.spi.RealClassLoader;
 import org.jboss.logging.Logger;
 
 /**
@@ -39,7 +49,7 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
-public class ClassLoaderDomain extends BaseClassLoaderDomain implements Loader
+public class ClassLoaderDomain extends BaseClassLoaderDomain implements Loader, ClassLoaderDomainMBean, MBeanRegistration
 {
    /** The log */
    private static final Logger log = Logger.getLogger(ClassLoaderDomain.class);
@@ -53,6 +63,12 @@
    /** The parent */
    private Loader parent;
    
+   /** The MBeanServer */
+   private MBeanServer mbeanServer;
+   
+   /** The object name */
+   private ObjectName objectName;
+   
    /**
     * Create a new ClassLoaderDomain with the {@link ParentPolicy#BEFORE} loading rules.
     * 
@@ -78,6 +94,16 @@
    }
    
    /**
+    * Get the object name
+    * 
+    * @return the object name
+    */
+   public ObjectName getObjectName()
+   {
+      return objectName;
+   }
+   
+   /**
     * Get the parent policy
     * 
     * @return the parent policy.
@@ -100,6 +126,11 @@
       this.parentPolicy = parentPolicy;
    }
 
+   public String getParentPolicyName()
+   {
+      return parentPolicy.toString();
+   }
+
    /**
     * Get the parent
     * 
@@ -120,7 +151,100 @@
       this.parent = parent;
       fixUpParent();
    }
-   
+
+   public ObjectName getParentDomain()
+   {
+      if (parent == null || parent instanceof ClassLoaderDomain == false)
+         return null;
+      ClassLoaderDomain parentDomain = (ClassLoaderDomain) parent;
+      return parentDomain.getObjectName();
+   }
+
+   public String getParentDomainName()
+   {
+      if (parent == null || parent instanceof ClassLoaderDomain == false)
+         return null;
+      ClassLoaderDomain parentDomain = (ClassLoaderDomain) parent;
+      return parentDomain.getName();
+   }
+
+   public ObjectName getSystem()
+   {
+      ClassLoaderSystem system = (ClassLoaderSystem) getClassLoaderSystem();
+      if (system == null)
+         return null;
+      return system.getObjectName();
+   }
+
+   public List<ObjectName> getClassLoaders()
+   {
+      List<ObjectName> result = new ArrayList<ObjectName>();
+      for (ClassLoader cl : super.getAllClassLoaders())
+      {
+         if (cl instanceof RealClassLoader)
+            result.add(((RealClassLoader) cl).getObjectName());
+      }
+      return result;
+   }
+
+   public Map<String, List<ObjectName>> getExportingClassLoaders()
+   {
+      HashMap<String, List<ObjectName>> result = new HashMap<String, List<ObjectName>>();
+      for (Entry<String, List<ClassLoader>> entry : getClassLoadersByPackage().entrySet())
+      {
+         List<ObjectName> names = new ArrayList<ObjectName>();
+         for (ClassLoader cl : entry.getValue())
+         {
+            if (cl instanceof RealClassLoader)
+               names.add(((RealClassLoader) cl).getObjectName());
+            
+         }
+         result.put(entry.getKey(), names);
+      }
+      return result;
+   }
+
+   public List<ObjectName> getExportingClassLoaders(String packageName)
+   {
+      if (packageName == null)
+         throw new IllegalArgumentException("Null package name");
+      
+      List<ObjectName> result = new ArrayList<ObjectName>();
+      for (ClassLoader cl : getClassLoaders(packageName))
+      {
+         if (cl instanceof RealClassLoader)
+            result.add(((RealClassLoader) cl).getObjectName());
+      }
+      return result;
+   }
+
+   public ObjectName findClassLoaderForClass(String name) throws ClassNotFoundException
+   {
+      final Class<?> clazz = loadClass(null, name, true);
+      if (clazz == null)
+         return null;
+      
+      ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+      {
+         public ClassLoader run()
+         {
+            return clazz.getClassLoader(); 
+         }
+      });
+      
+      if (cl != null && cl instanceof RealClassLoader)
+         return ((RealClassLoader) cl).getObjectName();
+      
+      return null;
+   }
+
+   public Set<URL> loadResources(String name) throws IOException
+   {
+      HashSet<URL> result = new HashSet<URL>();
+      getResources(name, result);
+      return result;
+   }
+
    /**
     * For subclasses to add information for toLongString()
     * 
@@ -472,4 +596,98 @@
          }
       }
    }
+
+   public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception
+   {
+      this.mbeanServer = server;
+      this.objectName = name;
+      return name;
+   }
+   
+   public void postRegister(Boolean registrationDone)
+   {
+      if (registrationDone.booleanValue())
+      {
+         // Register any classloaders that were added before we were registered in the MBeanServer
+         for (ClassLoader cl : getAllClassLoaders())
+            registerClassLoaderMBean(cl);
+      }
+      else
+      {
+         postDeregister();
+      }
+   }
+
+   public void preDeregister() throws Exception
+   {
+      // Unregister any remaining classloaders from the MBeanServer
+      for (ClassLoader cl : getAllClassLoaders())
+         unregisterClassLoaderMBean(cl);
+   }
+   
+   public void postDeregister()
+   {
+      this.mbeanServer = null;
+      this.objectName = null;
+   }
+
+   @Override
+   protected void afterRegisterClassLoader(ClassLoader classLoader, ClassLoaderPolicy policy)
+   {
+      registerClassLoaderMBean(classLoader);
+   }
+
+   @Override
+   protected void beforeUnregisterClassLoader(ClassLoader classLoader, ClassLoaderPolicy policy)
+   {
+      unregisterClassLoaderMBean(classLoader);
+   }
+
+   /**
+    * Register a classloader with the MBeanServer
+    * 
+    * @param cl the classloader
+    */
+   protected void registerClassLoaderMBean(ClassLoader cl)
+   {
+      if (mbeanServer == null)
+         return;
+      
+      if (cl instanceof RealClassLoader)
+      {
+         ObjectName name = ((RealClassLoader) cl).getObjectName();
+         try
+         {
+            mbeanServer.registerMBean(cl, name);
+         }
+         catch (Exception e)
+         {
+            log.warn("Error registering classloader: " + cl, e);
+         }
+      }
+   }
+
+   /**
+    * Unregister a classloader from the MBeanServer
+    * 
+    * @param cl the classloader
+    */
+   protected void unregisterClassLoaderMBean(ClassLoader cl)
+   {
+      if (mbeanServer == null)
+         return;
+      
+      if (cl instanceof RealClassLoader)
+      {
+         ObjectName name = ((RealClassLoader) cl).getObjectName();
+         try
+         {
+            mbeanServer.unregisterMBean(name);
+         }
+         catch (Exception e)
+         {
+            log.warn("Error unregistering classloader: " + cl, e);
+         }
+      }
+   }
 }

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomainMBean.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomainMBean.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomainMBean.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -0,0 +1,128 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2007, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.io.IOException;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.ObjectName;
+
+/**
+ * ClassLoaderSystemMBean.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface ClassLoaderDomainMBean
+{
+   /**
+    * Get the classloader system
+    * 
+    * @return the system
+    */
+   ObjectName getSystem();
+
+   /**
+    * Get the name.
+    * 
+    * @return the name.
+    */
+   String getName();
+   
+   /**
+    * Get the parent policy name
+    * 
+    * @return the parent policy name.
+    */
+   String getParentPolicyName();
+
+   /**
+    * Get the parent
+    * 
+    * @return the parent.
+    */
+   ObjectName getParentDomain();
+
+   /**
+    * Get the parent
+    * 
+    * @return the parent.
+    */
+   String getParentDomainName();
+
+   /**
+    * Get the classloaders
+    * 
+    * @return the classloaders
+    */
+   List<ObjectName> getClassLoaders();
+
+   /**
+    * Get the exporting classloaders
+    * 
+    * @return a map of packages to classloaders
+    */
+   Map<String, List<ObjectName>> getExportingClassLoaders();
+
+   /**
+    * Get the classloaders export a package
+    * 
+    * @param packageName the package name
+    * @return the classloaders
+    */
+   List<ObjectName> getExportingClassLoaders(String packageName);
+   
+   /**
+    * Load a class
+    * 
+    * @param name the class name
+    * @return the class
+    * @throws ClassNotFoundException when the class is not found
+    */
+   Class<?> loadClass(String name) throws ClassNotFoundException;
+   
+   /**
+    * Get resources
+    * 
+    * @param name the name of the resource
+    * @return the resource urls
+    * @throws IOException for any error
+    */
+   Set<URL> loadResources(String name) throws IOException;
+   
+   /**
+    * Find the classloader for a class
+    * 
+    * @param name the class name
+    * @return the classloader or null if it is not loaded by a managed classloader
+    * @throws ClassNotFoundException when the class is not found
+    */
+   ObjectName findClassLoaderForClass(String name) throws ClassNotFoundException; 
+   
+   /**
+    * Flush the caches
+    */
+   void flushCaches();
+}

Modified: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderPolicy.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderPolicy.java	2008-02-25 23:00:32 UTC (rev 70069)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderPolicy.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -223,15 +223,14 @@
       return null;
    }
 
-   /**
-    * Get the object name the classloader is registered in the MBeanServer with
-    * 
-    * @return the object name
-    */
+   @Override
    public ObjectName getObjectName()
    {
       try
       {
+         String name = getName();
+         if (name != null && name.trim().length() > 0)
+            return ObjectName.getInstance("jboss.classloader", "id", "'" + name + "'");
          return ObjectName.getInstance("jboss.classloader", "id", "" + System.identityHashCode(this));
       }
       catch (MalformedObjectNameException e)

Modified: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderSystem.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderSystem.java	2008-02-25 23:00:32 UTC (rev 70069)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderSystem.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -24,10 +24,18 @@
 import java.security.ProtectionDomain;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
 import org.jboss.classloader.plugins.system.ClassLoaderSystemBuilder;
 import org.jboss.classloader.spi.base.BaseClassLoaderSystem;
 import org.jboss.logging.Logger;
@@ -39,7 +47,7 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
-public abstract class ClassLoaderSystem extends BaseClassLoaderSystem
+public abstract class ClassLoaderSystem extends BaseClassLoaderSystem implements ClassLoaderSystemMBean, MBeanRegistration
 {
    /** The log */
    private static final Logger log = Logger.getLogger(ClassLoaderSystem.class);
@@ -62,6 +70,12 @@
    /** Whether the system is shutdown */
    private boolean shutdown = false;
    
+   /** The MBeanServer */
+   private MBeanServer mbeanServer;
+   
+   /** The object name */
+   private ObjectName objectName;
+   
    /**
     * Get the classloading system instance
     * 
@@ -253,6 +267,8 @@
 
       registeredDomains.put(name, domain);
       super.registerDomain(domain);
+
+      registerDomainMBean(domain);
       
       log.debug(this + " registered domain=" + domain.toLongString());
    }
@@ -284,6 +300,8 @@
     */
    private synchronized void internalUnregisterDomain(ClassLoaderDomain domain)
    {
+      unregisterDomainMBean(domain);
+      
       registeredDomains.remove(domain.getName());
       super.unregisterDomain(domain);
       
@@ -498,7 +516,128 @@
          log.warn("Error unregistering classloader from translator " + classLoader, t);
       }
    }
+   
+   /**
+    * Get the object name
+    * 
+    * @return the object name
+    */
+   public ObjectName getObjectName()
+   {
+      return objectName;
+   }
 
+   public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception
+   {
+      this.mbeanServer = server;
+      this.objectName = name;
+      return name;
+   }
+
+   public void postRegister(Boolean registrationDone)
+   {
+      if (registrationDone.booleanValue())
+      {
+         for (ClassLoaderDomain domain : registeredDomains.values())
+            registerDomainMBean(domain);
+      }
+      else
+      {
+         postDeregister();
+      }
+   }
+
+   public void preDeregister() throws Exception
+   {
+      for (ClassLoaderDomain domain : registeredDomains.values())
+         unregisterDomainMBean(domain);
+   }
+   
+   public void postDeregister()
+   {
+      this.mbeanServer = null;
+      this.objectName = null;
+   }
+
+   public Set<String> getDomainNames()
+   {
+      return registeredDomains.keySet();
+   }
+
+   public Set<ObjectName> getDomains()
+   {
+      Set<ObjectName> names = new HashSet<ObjectName>();
+      for (ClassLoaderDomain domain : registeredDomains.values())
+         names.add(domain.getObjectName());
+      return names;
+   }
+
+   /**
+    * Get an object name for the domain
+    * 
+    * @param domain the domain
+    * @return the object name
+    */
+   protected ObjectName getObjectName(ClassLoaderDomain domain)
+   {
+      if (domain == null)
+         throw new IllegalArgumentException("Null domain");
+      
+      Hashtable<String, String> properties = new Hashtable<String, String>();
+      properties.put("domain", "'" + domain.getName() + "'");
+      properties.put("system", "" + System.identityHashCode(this));
+      try
+      {
+         return ObjectName.getInstance("jboss.classloader", properties);
+      }
+      catch (MalformedObjectNameException e)
+      {
+         throw new RuntimeException("Unexpected error", e);
+      }
+   }
+   
+   /**
+    * Register a domain with the MBeanServer
+    * 
+    * @param domain the domain
+    */
+   protected void registerDomainMBean(ClassLoaderDomain domain)
+   {
+      if (mbeanServer == null)
+         return;
+
+      try
+      {
+         ObjectName name = getObjectName(domain);
+         mbeanServer.registerMBean(domain, name);
+      }
+      catch (Exception e)
+      {
+         log.warn("Error registering domain: " + domain, e);
+      }
+   }
+
+   /**
+    * Unregister a domain from the MBeanServer
+    * 
+    * @param domain the domain
+    */
+   protected void unregisterDomainMBean(ClassLoaderDomain domain)
+   {
+      if (mbeanServer == null)
+         return;
+
+      try
+      {
+         ObjectName name = getObjectName(domain);
+         mbeanServer.unregisterMBean(name);
+      }
+      catch (Exception e)
+      {
+         log.warn("Error unregistering domain: " + domain, e);
+      }
+   }
+
    @Override
    protected void toLongString(StringBuilder builder)
    {

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderSystemMBean.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderSystemMBean.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderSystemMBean.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -0,0 +1,49 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2007, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.Set;
+
+import javax.management.ObjectName;
+
+/**
+ * ClassLoaderSystemMBean.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface ClassLoaderSystemMBean
+{
+   /**
+    * Get the domains
+    * 
+    * @return the domains
+    */
+   Set<ObjectName> getDomains();
+
+   /**
+    * Get the domain names
+    * 
+    * @return the domain names
+    */
+   Set<String> getDomainNames();
+}

Modified: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoader.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoader.java	2008-02-25 23:00:32 UTC (rev 70069)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoader.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -31,17 +31,22 @@
 import java.security.PrivilegedExceptionAction;
 import java.security.ProtectionDomain;
 import java.security.SecureClassLoader;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.ReentrantLock;
+
 import javax.management.ObjectName;
 
 import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.ClassLoaderDomain;
 import org.jboss.classloader.spi.ClassLoaderPolicy;
 import org.jboss.classloader.spi.DelegateLoader;
 import org.jboss.classloader.spi.PackageInformation;
@@ -69,6 +74,9 @@
    /** Our Loader front end */
    private DelegateLoader loader;
    
+   /** The loaded classes */
+   private Set<String> loadedClasses = new CopyOnWriteArraySet<String>();
+   
    /** Our resource cache */
    private Map<String, URL> resourceCache;
    
@@ -108,6 +116,106 @@
       return policy.getObjectName();
    }
    
+   public ObjectName getClassLoaderDomain()
+   {
+      BaseClassLoaderPolicy basePolicy = policy;
+      ClassLoaderDomain domain = (ClassLoaderDomain) basePolicy.getClassLoaderDomain();
+      return domain.getObjectName();
+   }
+
+   public String getName()
+   {
+      return policy.getName();
+   }
+   
+   public boolean isBlackListable()
+   {
+      BaseClassLoaderPolicy basePolicy = policy;
+      return basePolicy.isBlackListable();
+   }
+
+   public boolean isCacheable()
+   {
+      BaseClassLoaderPolicy basePolicy = policy;
+      return basePolicy.isCacheable();
+   }
+
+   public boolean isImportAll()
+   {
+      BaseClassLoaderPolicy basePolicy = policy;
+      return basePolicy.isImportAll();
+   }
+
+   public Set<String> getExportedPackages()
+   {
+      HashSet<String> result = new HashSet<String>();
+      String[] packageNames = policy.getPackageNames();
+      if (packageNames != null)
+         Collections.addAll(result, packageNames);
+      return result;
+   }
+
+   public List<ObjectName> getImports()
+   {
+      ArrayList<ObjectName> result = new ArrayList<ObjectName>();
+      BaseClassLoaderPolicy basePolicy = policy;
+      List<? extends DelegateLoader> delegates = basePolicy.getDelegates();
+      if (delegates != null)
+      {
+         for (DelegateLoader delegate : delegates)
+         {
+            BaseDelegateLoader baseDelegate = delegate;
+            BaseClassLoaderPolicy otherPolicy = baseDelegate.getPolicy();
+            result.add(otherPolicy.getObjectName());
+         }
+      }
+      return result;
+   }
+   
+   public String getPolicyDetails()
+   {
+      return policy.toLongString();
+   }
+
+   public ObjectName findClassLoaderForClass(String name) throws ClassNotFoundException
+   {
+      final Class<?> clazz = loadClass(name);
+      if (clazz == null)
+         return null;
+      
+      ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+      {
+         public ClassLoader run()
+         {
+            return clazz.getClassLoader(); 
+         }
+      });
+      
+      if (cl != null && cl instanceof RealClassLoader)
+         return ((RealClassLoader) cl).getObjectName();
+      
+      return null;
+   }
+
+   public Set<String> getLoadedClasses()
+   {
+      return new HashSet<String>(loadedClasses);
+   }
+
+   public Set<String> getLoadedResourceNames()
+   {
+      if (resourceCache == null)
+         return Collections.emptySet();
+      return new HashSet<String>(resourceCache.keySet());
+   }
+
+   public Set<URL> getLoadedResources()
+   {
+      if (resourceCache == null)
+         return Collections.emptySet();
+      return new HashSet<URL>(resourceCache.values());
+   }
+
    /**
     * Get the policy.
     * 
@@ -204,17 +312,15 @@
          packages.add(pkg);
    }
    
-   @Override
-   protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
+   /**
+    * Check to see if the class is already loaded
+    * 
+    * @param name the name of the class
+    * @param trace whether trace is enabled
+    * @return the class is if it is already loaded, null otherwise
+    */
+   protected Class<?> isLoadedClass(String name, boolean trace)
    {
-      boolean trace = log.isTraceEnabled();
-      if (trace)
-         log.trace(this + " loadClass " + name + " resolve=" + resolve);
-      
-      // Validate the class name makes sense
-      ClassLoaderUtils.checkClassName(name);
-      
-      // Did we already load this class?
       Class<?> result = findLoadedClass(name);
       if (result != null)
       {
@@ -234,6 +340,21 @@
       }
       if (result != null && trace)
          log.trace(this + " already loaded class " + ClassLoaderUtils.classToString(result));
+      return result;
+   }
+   
+   @Override
+   protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
+   {
+      boolean trace = log.isTraceEnabled();
+      if (trace)
+         log.trace(this + " loadClass " + name + " resolve=" + resolve);
+      
+      // Validate the class name makes sense
+      ClassLoaderUtils.checkClassName(name);
+      
+      // Did we already load this class?
+      Class<?> result = isLoadedClass(name, trace);
 
       // If this is an array, use Class.forName() to resolve it
       if (result == null && name.charAt(0) == '[')
@@ -286,6 +407,12 @@
    @SuppressWarnings("unchecked")
    protected Enumeration<URL> findResources(String name) throws IOException
    {
+      Set<URL> resourceURLs = loadResources(name);
+      return Iterators.toEnumeration(resourceURLs.iterator());
+   }
+
+   public Set<URL> loadResources(String name) throws IOException
+   {
       BaseClassLoaderPolicy basePolicy = policy;
       BaseClassLoaderDomain domain = basePolicy.getClassLoaderDomain();
       boolean trace = log.isTraceEnabled();
@@ -295,9 +422,9 @@
       Set<URL> resourceURLs = new HashSet<URL>();
       if (domain != null)
          domain.getResources(this, name, resourceURLs);
-      return Iterators.toEnumeration(resourceURLs.iterator());
+      return resourceURLs;
    }
-
+   
    /**
     * Try to load the class locally
     * 
@@ -322,18 +449,14 @@
          log.trace(this + " load class locally " + name);
 
       // This is really a double check but the request may not have entered through loadClass on this classloader
-      Class<?> result = findLoadedClass(name);
+      Class<?> result = isLoadedClass(name, trace);
       if (result != null)
-      {
-         if (trace)
-            log.trace(this + " already loaded " + ClassLoaderUtils.classToString(result));
          return result;
-      }
 
       // Look for the resource
       final String resourcePath = ClassLoaderUtils.classNameToPath(name);
       
-      return AccessController.doPrivileged(new PrivilegedAction<Class<?>>()
+      result = AccessController.doPrivileged(new PrivilegedAction<Class<?>>()
       {
          public Class<?> run()
          {
@@ -383,6 +506,10 @@
             return result;
          }
       }, policy.getAccessControlContext());
+      
+      loadedClasses.add(name);
+      
+      return result;
    }
 
    /**
@@ -626,6 +753,15 @@
       return null;
    }
 
+   public void clearBlackList()
+   {
+      if (blackList != null)
+      {
+         for (String name : blackList)
+            clearBlackList(name);
+      }
+   }
+
    public void clearBlackList(String name)
    {
       if (blackList != null)

Modified: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java	2008-02-25 23:00:32 UTC (rev 70069)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -24,10 +24,13 @@
 import java.io.IOException;
 import java.net.URL;
 import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CopyOnWriteArraySet;
@@ -95,7 +98,7 @@
     * 
     * @return the classloader system
     */
-   synchronized BaseClassLoaderSystem getClassLoaderSystem()
+   protected synchronized BaseClassLoaderSystem getClassLoaderSystem()
    {
       return system;
    }
@@ -168,7 +171,7 @@
          return system.transform(classLoader, className, byteCode, protectionDomain);
       return byteCode;
    }
-   
+
    /**
     * Load a class from the domain
     * 
@@ -178,7 +181,7 @@
     * @return the class
     * @throws ClassNotFoundException for any error
     */
-   Class<?> loadClass(BaseClassLoader classLoader, String name, boolean allExports) throws ClassNotFoundException
+   protected Class<?> loadClass(BaseClassLoader classLoader, String name, boolean allExports) throws ClassNotFoundException
    {
       boolean trace = log.isTraceEnabled();
       
@@ -1270,8 +1273,54 @@
          log.warn("Error in afterUnegisterClassLoader: " + this + " classLoader=" + classLoader.toLongString(), t);
       }
    }
-   
+
    /**
+    * Get all the classloaders
+    * 
+    * @return the list of classloaders
+    */
+   protected List<ClassLoader> getAllClassLoaders()
+   {
+      List<ClassLoader> result = new ArrayList<ClassLoader>();
+      for (ClassLoaderInformation info : classLoaders)
+         result.add(info.getClassLoader());
+      return result;
+   }
+
+   /**
+    * Get a map of packages to classloader
+    * 
+    * @return a map of packages to a list of classloaders for that package
+    */
+   protected Map<String, List<ClassLoader>> getClassLoadersByPackage()
+   {
+      HashMap<String, List<ClassLoader>> result = new HashMap<String, List<ClassLoader>>();
+      for (Entry<String, List<ClassLoaderInformation>> entry : classLoadersByPackageName.entrySet())
+      {
+         List<ClassLoader> cls = new ArrayList<ClassLoader>();
+         for (ClassLoaderInformation info : entry.getValue())
+            cls.add(info.getClassLoader());
+         result.put(entry.getKey(), cls);
+      }
+      return result;
+   }
+
+   protected List<ClassLoader> getClassLoaders(String packageName)
+   {
+      if (packageName == null)
+         throw new IllegalArgumentException("Null package name");
+      
+      List<ClassLoader> result = new ArrayList<ClassLoader>();
+      List<ClassLoaderInformation> infos = classLoadersByPackageName.get(packageName);
+      if (infos != null)
+      {
+         for (ClassLoaderInformation info : infos)
+            result.add(info.getClassLoader());
+      }
+      return result;
+   }
+
+   /**
     * Cleans the entry with the given name from the blackList
     *
     * @param name the name of the resource to clear from the blackList

Modified: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderMBean.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderMBean.java	2008-02-25 23:00:32 UTC (rev 70069)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderMBean.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -21,6 +21,13 @@
  */
 package org.jboss.classloader.spi.base;
 
+import java.io.IOException;
+import java.net.URL;
+import java.util.List;
+import java.util.Set;
+
+import javax.management.ObjectName;
+
 /**
  * BaseClassLoaderMBean.
  * 
@@ -29,4 +36,126 @@
  */
 public interface BaseClassLoaderMBean
 {
+   /**
+    * Get the classloader domain
+    * 
+    * @return the domain
+    */
+   ObjectName getClassLoaderDomain();
+   
+   /**
+    * Get the name of the classloader
+    * 
+    * @return the name
+    */
+   String getName();
+   
+   /**
+    * Whether to import all exports from other classloaders in the domain
+    * 
+    * @return true to import all
+    */
+   boolean isImportAll();
+
+   /**
+    * Whether to cache<
+    * 
+    * @return true to cache
+    */
+   boolean isCacheable();
+
+   /**
+    * Whether to cache misses
+    * 
+    * @return true to cache misses
+    */
+   boolean isBlackListable();
+   
+   /**
+    * Whether the classloader is still valid
+    * 
+    * @return true when still valid
+    */
+   boolean isValid();
+   
+   /**
+    * Get the exported packages
+    * 
+    * @return the exported packages
+    */
+   Set<String> getExportedPackages();
+
+   /**
+    * Get the imports of this classloader
+    * 
+    * @return the imports
+    */
+   List<ObjectName> getImports();
+   
+   /**
+    * Get the policy as a string
+    * 
+    * @return the policy string
+    */
+   String getPolicyDetails();
+   
+   /**
+    * Get the loaded classes
+    * 
+    * @return the loaded classes
+    */
+   Set<String> getLoadedClasses();
+   
+   /**
+    * Get the loaded resource names
+    * 
+    * @return the loaded resources names
+    */
+   Set<String> getLoadedResourceNames();
+   
+   /**
+    * Get the loaded resources
+    * 
+    * @return the loaded resources
+    */
+   Set<URL> getLoadedResources();
+   
+   /**
+    * Load a class
+    * 
+    * @param name the class name
+    * @return the class
+    * @throws ClassNotFoundException when the class is not found
+    */
+   Class<?> loadClass(String name) throws ClassNotFoundException;
+   
+   /**
+    * Get resources
+    * 
+    * @param name the name of the resource
+    * @return the resource urls
+    * @throws IOException for any error
+    */
+   Set<URL> loadResources(String name) throws IOException;
+   
+   /**
+    * Find the classloader for a class
+    * 
+    * @param name the class name
+    * @return the classloader or null if it is not loaded by a managed classloader
+    * @throws ClassNotFoundException when the class is not found
+    */
+   ObjectName findClassLoaderForClass(String name) throws ClassNotFoundException; 
+
+   /**
+    * Clear the black list
+    */
+   void clearBlackList();
+
+   /**
+    * Clear an entry from the black list
+    * 
+    * @param name the name of the entry to remove
+    */
+   void clearBlackList(String name);
 }

Modified: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java	2008-02-25 23:00:32 UTC (rev 70069)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -26,6 +26,8 @@
 import java.security.ProtectionDomain;
 import java.util.List;
 
+import javax.management.ObjectName;
+
 import org.jboss.classloader.spi.ClassLoaderDomain;
 import org.jboss.classloader.spi.DelegateLoader;
 import org.jboss.logging.Logger;
@@ -166,6 +168,13 @@
    protected abstract boolean isBlackListable();
 
    /**
+    * Get the object name the classloader is registered in the MBeanServer with
+    * 
+    * @return the object name
+    */
+   public abstract ObjectName getObjectName();
+
+   /**
     * Check whether this a request from the jdk if it is return the relevant classloader
     * 
     * @param name the class name

Modified: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoaderInformation.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoaderInformation.java	2008-02-25 23:00:32 UTC (rev 70069)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoaderInformation.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -92,6 +92,8 @@
       {
          for (DelegateLoader delegate : delegates)
          {
+            if (delegate == null)
+               throw new IllegalStateException(policy + " null delegate in " + delegates);
             BaseDelegateLoader baseDelegate = delegate;
             BaseClassLoaderPolicy delegatePolicy = baseDelegate.getPolicy();
             if (delegatePolicy.isCacheable() == false)

Modified: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java	2008-02-25 23:00:32 UTC (rev 70069)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -23,11 +23,13 @@
 
 import java.util.HashSet;
 import java.util.Set;
+import javax.management.MBeanRegistration;
 
 import junit.framework.Test;
 
 import org.jboss.classloader.plugins.ClassLoaderUtils;
 import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderDomainMBean;
 import org.jboss.classloader.spi.ClassLoaderSystem;
 import org.jboss.classloader.spi.Loader;
 import org.jboss.classloader.spi.ParentPolicy;
@@ -82,7 +84,7 @@
       ClassLoader classLoader = system.registerClassLoaderPolicy(domain, policy);
       
       assertLoadClass(ClassLoaderDomain.class, classLoader);
-      checkGetResource(loader, ClassLoaderDomain.class, BaseClassLoaderDomain.class, Loader.class, Object.class);
+      checkGetResource(loader, ClassLoaderDomain.class, BaseClassLoaderDomain.class, ClassLoaderDomainMBean.class, MBeanRegistration.class, Loader.class, Object.class);
       checkLoadClass(loader);
    }
    

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/support/a/A.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/support/a/A.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/support/a/A.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -0,0 +1,33 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2007, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.jmx.support.a;
+
+/**
+ * A.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class A
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/support/b/B.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/support/b/B.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/support/b/B.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -0,0 +1,33 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2007, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.jmx.support.b;
+
+/**
+ * B.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class B
+{
+
+}

Modified: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/test/JMXUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/test/JMXUnitTestCase.java	2008-02-25 23:00:32 UTC (rev 70069)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/jmx/test/JMXUnitTestCase.java	2008-02-25 23:31:55 UTC (rev 70070)
@@ -21,18 +21,34 @@
  */
 package org.jboss.test.classloader.jmx.test;
 
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import javax.management.MBeanInfo;
 import javax.management.MBeanServer;
 import javax.management.MBeanServerFactory;
+import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
 import junit.framework.Test;
 
+import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.plugins.jdk.AbstractJDKChecker;
+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.classloading.spi.RealClassLoader;
 import org.jboss.test.classloader.AbstractClassLoaderTest;
 import org.jboss.test.classloader.jmx.support.Simple;
+import org.jboss.test.classloader.jmx.support.a.A;
+import org.jboss.test.classloader.jmx.support.b.B;
 
 /**
  * JMXUnitTestCase
@@ -42,6 +58,21 @@
  */
 public class JMXUnitTestCase extends AbstractClassLoaderTest
 {
+   private static final ObjectName CLASSLOADER_SYSTEM_OBJECT_NAME;
+   
+   static
+   {
+      try
+      {
+         CLASSLOADER_SYSTEM_OBJECT_NAME = new ObjectName("test:type=ClassLoaderSystem");
+      }
+      catch (MalformedObjectNameException e)
+      {
+         throw new RuntimeException("Unexpected error", e);
+      }
+      AbstractJDKChecker.getExcluded().add(JMXUnitTestCase.class);
+   }
+   
    public static Test suite()
    {
       return suite(JMXUnitTestCase.class);
@@ -75,4 +106,328 @@
       getLog().debug("Actual ClassLoader=" + actual + " expected " + cl);
       assertEquals(cl, actual);
    }
+
+   @SuppressWarnings("unchecked")
+   public void testClassLoaderSystemMBean() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MBeanServer server = MBeanServerFactory.newMBeanServer();
+      server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
+      
+      Set<String> domainNames = (Set) server.getAttribute(CLASSLOADER_SYSTEM_OBJECT_NAME, "DomainNames");
+      Set<String> expected = makeSet(ClassLoaderSystem.DEFAULT_DOMAIN_NAME);
+      assertEquals(expected, domainNames);
+
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ObjectName defaultDomainObjectName = defaultDomain.getObjectName();
+      Set<ObjectName> domains = (Set) server.getAttribute(CLASSLOADER_SYSTEM_OBJECT_NAME, "Domains");
+      Set<ObjectName> expectedObjectNames = makeSet(defaultDomainObjectName);
+      assertEquals(expectedObjectNames, domains);
+      
+      String domainName = (String) server.getAttribute(defaultDomainObjectName, "Name");
+      assertEquals(ClassLoaderSystem.DEFAULT_DOMAIN_NAME, domainName);
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testRegisterDomain() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MBeanServer server = MBeanServerFactory.newMBeanServer();
+      server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
+      
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ObjectName defaultDomainObjectName = defaultDomain.getObjectName();
+      
+      ClassLoaderDomain domain = system.createAndRegisterDomain("test");
+      ObjectName testObjectName = domain.getObjectName();
+      
+      Set<String> domainNames = (Set) server.getAttribute(CLASSLOADER_SYSTEM_OBJECT_NAME, "DomainNames");
+      Set<String> expected = makeSet("test", ClassLoaderSystem.DEFAULT_DOMAIN_NAME);
+      assertEquals(expected, domainNames);
+      
+      Set<ObjectName> domains = (Set) server.getAttribute(CLASSLOADER_SYSTEM_OBJECT_NAME, "Domains");
+      Set<ObjectName> expectedObjectNames = makeSet(defaultDomainObjectName, testObjectName);
+      assertEquals(expectedObjectNames, domains);
+      
+      String domainName = (String) server.getAttribute(testObjectName, "Name");
+      assertEquals("test", domainName);
+      
+      system.unregisterDomain(domain);
+      
+      assertFalse(server.isRegistered(testObjectName));
+
+      domainNames = (Set) server.getAttribute(CLASSLOADER_SYSTEM_OBJECT_NAME, "DomainNames");
+      expected = makeSet(ClassLoaderSystem.DEFAULT_DOMAIN_NAME);
+      assertEquals(expected, domainNames);
+      
+      domains = (Set) server.getAttribute(CLASSLOADER_SYSTEM_OBJECT_NAME, "Domains");
+      expectedObjectNames = makeSet(defaultDomainObjectName);
+      assertEquals(expectedObjectNames, domains);
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testLazyRegisterDomain() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MBeanServer server = MBeanServerFactory.newMBeanServer();
+      ClassLoaderDomain test = system.createAndRegisterDomain("test");
+      server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
+      
+      Set<String> domainNames = (Set) server.getAttribute(CLASSLOADER_SYSTEM_OBJECT_NAME, "DomainNames");
+      Set<String> expected = makeSet("test", ClassLoaderSystem.DEFAULT_DOMAIN_NAME);
+      assertEquals(expected, domainNames);
+      
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ObjectName defaultDomainObjectName = defaultDomain.getObjectName();
+      ObjectName testObjectName = test.getObjectName();
+      Set<ObjectName> domains = (Set) server.getAttribute(CLASSLOADER_SYSTEM_OBJECT_NAME, "Domains");
+      Set<ObjectName> expectedObjectNames = makeSet(defaultDomainObjectName, testObjectName);
+      assertEquals(expectedObjectNames, domains);
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testUnregisterClassLoaderSystemUnregistersDomains() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MBeanServer server = MBeanServerFactory.newMBeanServer();
+      ClassLoaderDomain test = system.createAndRegisterDomain("test");
+      server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
+      
+      Set<String> domainNames = (Set) server.getAttribute(CLASSLOADER_SYSTEM_OBJECT_NAME, "DomainNames");
+      Set<String> expected = makeSet("test", ClassLoaderSystem.DEFAULT_DOMAIN_NAME);
+      assertEquals(expected, domainNames);
+      
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ObjectName defaultDomainObjectName = defaultDomain.getObjectName();
+      ObjectName testObjectName = test.getObjectName();
+      Set<ObjectName> domains = (Set) server.getAttribute(CLASSLOADER_SYSTEM_OBJECT_NAME, "Domains");
+      Set<ObjectName> expectedObjectNames = makeSet(defaultDomainObjectName, testObjectName);
+      assertEquals(expectedObjectNames, domains);
+      
+      server.unregisterMBean(CLASSLOADER_SYSTEM_OBJECT_NAME);
+      assertFalse(server.isRegistered(CLASSLOADER_SYSTEM_OBJECT_NAME));
+      for (ObjectName domain : domains)
+         assertFalse(server.isRegistered(domain));
+   }
+
+   public void testClassLoaderDomainMBean() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MBeanServer server = MBeanServerFactory.newMBeanServer();
+      server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
+
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ClassLoaderDomain domain = system.createAndRegisterDomain("test", ParentPolicy.AFTER_BUT_JAVA_BEFORE, defaultDomain);
+
+      ObjectName testObjectName = domain.getObjectName();
+      assertEquals(CLASSLOADER_SYSTEM_OBJECT_NAME, server.getAttribute(testObjectName, "System"));
+      assertEquals(domain.getName(), server.getAttribute(testObjectName, "Name"));
+      assertEquals(ParentPolicy.AFTER_BUT_JAVA_BEFORE.toString(), server.getAttribute(testObjectName, "ParentPolicyName"));
+      assertEquals(defaultDomain.getObjectName(), server.getAttribute(testObjectName, "ParentDomain"));
+      assertEquals(defaultDomain.getName(), server.getAttribute(testObjectName, "ParentDomainName"));
+   }
+
+   public void testRegisterClassLoader() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MBeanServer server = MBeanServerFactory.newMBeanServer();
+      server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
+
+      ClassLoaderDomain domain = system.createAndRegisterDomain("test");
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("simple");
+      policy.setPathsAndPackageNames(Simple.class);
+      RealClassLoader cl = (RealClassLoader) system.registerClassLoaderPolicy(domain.getName(), policy);
+      
+      assertTrue(server.isRegistered(cl.getObjectName()));
+      
+      system.unregisterClassLoader((ClassLoader) cl);
+
+      assertFalse(server.isRegistered(cl.getObjectName()));
+   }
+
+   public void testLazyRegisterClassLoader() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MBeanServer server = MBeanServerFactory.newMBeanServer();
+
+      ClassLoaderDomain domain = system.createAndRegisterDomain("test");
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("simple");
+      policy.setPathsAndPackageNames(Simple.class);
+      RealClassLoader cl = (RealClassLoader) system.registerClassLoaderPolicy(domain.getName(), policy);
+      
+      server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
+      assertTrue(server.isRegistered(cl.getObjectName()));
+   }
+
+   public void testUnregisterClassLoaderSystemUnregistersClassLoader() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MBeanServer server = MBeanServerFactory.newMBeanServer();
+      server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
+
+      ClassLoaderDomain domain = system.createAndRegisterDomain("test");
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("simple");
+      policy.setPathsAndPackageNames(Simple.class);
+      RealClassLoader cl = (RealClassLoader) system.registerClassLoaderPolicy(domain.getName(), policy);
+      
+      assertTrue(server.isRegistered(cl.getObjectName()));
+      
+      server.unregisterMBean(CLASSLOADER_SYSTEM_OBJECT_NAME);
+
+      assertFalse(server.isRegistered(cl.getObjectName()));
+   }
+
+   public void testUnregisterDomainUnregistersClassLoader() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MBeanServer server = MBeanServerFactory.newMBeanServer();
+      server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
+
+      ClassLoaderDomain domain = system.createAndRegisterDomain("test");
+
+      MockClassLoaderPolicy policy = createMockClassLoaderPolicy("simple");
+      policy.setPathsAndPackageNames(Simple.class);
+      RealClassLoader cl = (RealClassLoader) system.registerClassLoaderPolicy(domain.getName(), policy);
+      
+      assertTrue(server.isRegistered(cl.getObjectName()));
+
+      system.unregisterDomain(domain);
+
+      assertFalse(server.isRegistered(cl.getObjectName()));
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testClassLoaderDomainClassLoaders() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MBeanServer server = MBeanServerFactory.newMBeanServer();
+      server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
+
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ClassLoaderDomain domain = system.createAndRegisterDomain("test", ParentPolicy.BEFORE_BUT_JAVA_ONLY, defaultDomain);
+
+      MockClassLoaderPolicy a1 = createMockClassLoaderPolicy("a1");
+      a1.setPathsAndPackageNames(A.class);
+      RealClassLoader clA1 = (RealClassLoader) system.registerClassLoaderPolicy(domain, a1);
+
+      MockClassLoaderPolicy a2 = createMockClassLoaderPolicy("a2");
+      a2.setPathsAndPackageNames(A.class);
+      RealClassLoader clA2 = (RealClassLoader) system.registerClassLoaderPolicy(domain, a2);
+
+      MockClassLoaderPolicy b1 = createMockClassLoaderPolicy("b1");
+      b1.setPathsAndPackageNames(B.class);
+      RealClassLoader clB1 = (RealClassLoader) system.registerClassLoaderPolicy(domain, b1);
+
+      MockClassLoaderPolicy b2 = createMockClassLoaderPolicy("b2");
+      b2.setPaths(B.class);
+      RealClassLoader clB2 = (RealClassLoader) system.registerClassLoaderPolicy(domain, b2);
+      
+      ObjectName testDomain = domain.getObjectName();
+      List<ObjectName> classLoaders = (List) server.getAttribute(testDomain, "ClassLoaders");
+      List<ObjectName> expected = Arrays.asList(clA1.getObjectName(), clA2.getObjectName(), clB1.getObjectName(), clB2.getObjectName());
+      assertEquals(expected, classLoaders);
+      
+      Map<String, List<ObjectName>> packageClassLoaders = (Map) server.getAttribute(testDomain, "ExportingClassLoaders");
+      Map<String, List<ObjectName>> expectedMap = new HashMap<String, List<ObjectName>>();
+      expectedMap.put(A.class.getPackage().getName(), Arrays.asList(clA1.getObjectName(), clA2.getObjectName()));
+      expectedMap.put(B.class.getPackage().getName(), Arrays.asList(clB1.getObjectName()));
+      assertEquals(expectedMap, packageClassLoaders);
+      
+      classLoaders = (List) server.invoke(testDomain, "getExportingClassLoaders", new Object[] { A.class.getPackage().getName() }, new String[] { String.class.getName()});
+      expected = Arrays.asList(clA1.getObjectName(), clA2.getObjectName());
+
+      classLoaders = (List) server.invoke(testDomain, "getExportingClassLoaders", new Object[] { B.class.getPackage().getName() }, new String[] { String.class.getName()});
+      expected = Arrays.asList(clB1.getObjectName());
+
+      Class<?> clazz = (Class<?>) server.invoke(testDomain, "loadClass", new Object[] { A.class.getName() }, new String[] { String.class.getName() });
+      assertEquals(((ClassLoader) clA1).loadClass(A.class.getName()), clazz);
+
+      ObjectName result = (ObjectName) server.invoke(testDomain, "findClassLoaderForClass", new Object[] { A.class.getName() }, new String[] { String.class.getName() });
+      assertEquals(clA1.getObjectName(), result);
+      assertNull(server.invoke(testDomain, "findClassLoaderForClass", new Object[] { Object.class.getName() }, new String[] { String.class.getName() }));
+
+      String resourceName = ClassLoaderUtils.classNameToPath(A.class.getName());
+      Set<URL> urls = (Set) server.invoke(testDomain, "loadResources", new Object[] { resourceName }, new String[] { String.class.getName()});
+      Set<URL> expectedURLs = makeSet(getClass().getClassLoader().getResource(resourceName));
+      assertEquals(expectedURLs, urls);
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testClassLoaderMBean() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MBeanServer server = MBeanServerFactory.newMBeanServer();
+      server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
+
+      ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+      ClassLoaderDomain domain = system.createAndRegisterDomain("test", ParentPolicy.BEFORE_BUT_JAVA_ONLY, defaultDomain);
+
+      MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+      a.setPathsAndPackageNames(A.class);
+      RealClassLoader clA = (RealClassLoader) system.registerClassLoaderPolicy(domain.getName(), a);
+
+      MockClassLoaderPolicy b = createMockClassLoaderPolicy("b");
+      b.setPathsAndPackageNames(B.class);
+      RealClassLoader clB = (RealClassLoader) system.registerClassLoaderPolicy(domain.getName(), b);
+      
+      MockClassLoaderPolicy test = createMockClassLoaderPolicy("test");
+      test.setImportAll(true);
+      test.setDelegates(Arrays.asList(a.getExported(), b.getExported()));
+      test.setPathsAndPackageNames(A.class, B.class);
+      RealClassLoader cl = (RealClassLoader) system.registerClassLoaderPolicy(domain, test);
+      
+      ObjectName testObjectName = cl.getObjectName();
+      assertEquals(domain.getObjectName(), server.getAttribute(testObjectName, "ClassLoaderDomain"));
+      assertEquals("test", server.getAttribute(testObjectName, "Name"));
+      assertTrue((Boolean) server.getAttribute(testObjectName, "ImportAll"));
+      assertTrue((Boolean) server.getAttribute(testObjectName, "Valid"));
+      Set<String> expectedPackages = makeSet(A.class.getPackage().getName(), B.class.getPackage().getName());
+      assertEquals(expectedPackages, server.getAttribute(testObjectName, "ExportedPackages"));
+      List<ObjectName> expectedImports = Arrays.asList(clA.getObjectName(), clB.getObjectName()); 
+      assertEquals(expectedImports, server.getAttribute(testObjectName, "Imports"));
+      assertEquals(test.toLongString(), server.getAttribute(testObjectName, "PolicyDetails"));
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testClassLoader() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MBeanServer server = MBeanServerFactory.newMBeanServer();
+      server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
+      system.getDefaultDomain().setParentPolicy(ParentPolicy.BEFORE_BUT_JAVA_ONLY);
+
+      MockClassLoaderPolicy test = createMockClassLoaderPolicy("test");
+      test.setPathsAndPackageNames(A.class, B.class);
+      RealClassLoader cl = (RealClassLoader) system.registerClassLoaderPolicy(test);
+      
+      ObjectName testObjectName = cl.getObjectName();
+
+      Set<String> loadedClasses = (Set) server.getAttribute(testObjectName, "LoadedClasses");
+      assertFalse(loadedClasses.contains(A.class.getName()));
+      Class<?> expected = ((ClassLoader) cl).loadClass(A.class.getName());
+      assertEquals(expected, server.invoke(testObjectName, "loadClass", new Object[] { A.class.getName() }, new String[] { String.class.getName() }));
+      loadedClasses = (Set) server.getAttribute(testObjectName, "LoadedClasses");
+      assertTrue(loadedClasses.contains(A.class.getName()));
+
+      assertEquals(cl.getObjectName(), server.invoke(testObjectName, "findClassLoaderForClass", new Object[] { A.class.getName() }, new String[] { String.class.getName() }));
+      assertNull(server.invoke(testObjectName, "findClassLoaderForClass", new Object[] { Object.class.getName() }, new String[] { String.class.getName() }));
+      
+      String resourceName = ClassLoaderUtils.classNameToPath(B.class.getName());
+      Set<String> loadedResourceNames = (Set) server.getAttribute(testObjectName, "LoadedResourceNames");
+      assertFalse(loadedResourceNames.contains(resourceName));
+      Set<URL> expectedURLs = makeSet(((ClassLoader) cl).getResource(resourceName));
+      assertEquals(expectedURLs, server.invoke(testObjectName, "loadResources", new Object[] { resourceName }, new String[] { String.class.getName() }));
+      loadedResourceNames = (Set) server.getAttribute(testObjectName, "LoadedResourceNames");
+      assertTrue(loadedResourceNames.contains(resourceName));
+   }
+      
+   protected static <T> Set<T> makeSet(T... values)
+   {
+      Set<T> result = new HashSet<T>();
+      Collections.addAll(result, values);
+      return result;
+   }
 }




More information about the jboss-cvs-commits mailing list