[jboss-cvs] JBossAS SVN: r99748 - in projects/jboss-cl/trunk: classloader/src/main/java/org/jboss/classloader/spi/base and 20 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Jan 21 08:37:06 EST 2010


Author: adrian at jboss.org
Date: 2010-01-21 08:37:05 -0500 (Thu, 21 Jan 2010)
New Revision: 99748

Added:
   projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ShutdownPolicy.java
   projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/
   projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/GeneralTestSuite.java
   projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/support/
   projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/support/A.java
   projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/test/
   projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/test/ShutdownUnitTestCase.java
   projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/vfs/policy/test/ShutdownUnitTestCase.java
   projects/jboss-cl/trunk/classloading-vfs/src/test/resources/org/jboss/test/classloading/vfs/metadata/xml/test/ModuleShutdown.xml
Modified:
   projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomain.java
   projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomainMBean.java
   projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java
   projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystem.java
   projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystemMBean.java
   projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoader.java
   projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java
   projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderMBean.java
   projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java
   projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderSystem.java
   projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/filter/ClassFilter.java
   projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/AbstractClassLoaderTest.java
   projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/ClassLoaderAllTestSuite.java
   projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/jmx/test/JMXUnitTestCase.java
   projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/junit/test/IsolatedClassLoaderUnitTestCase.java
   projects/jboss-cl/trunk/classloading-vfs/src/main/java/org/jboss/classloading/spi/vfs/dependency/VFSClassLoaderPolicyModule.java
   projects/jboss-cl/trunk/classloading-vfs/src/main/resources/schema/jboss-classloader-1.0.xsd
   projects/jboss-cl/trunk/classloading-vfs/src/main/resources/schema/jboss-classloading-1.0.xsd
   projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/ClassLoadingVFSTestSuite.java
   projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/vfs/metadata/test/ManagedObjectVFSClassLoaderFactoryUnitTestCase.java
   projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/vfs/metadata/xml/test/VFSClassLoaderFactoryXMLUnitTestCase.java
   projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Module.java
   projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java
   projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/helpers/ClassLoadingMetaDataModule.java
   projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/mock/MockClassLoaderPolicyModule.java
   projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/metadata/ClassLoadingMetaData.java
   projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/DependencyUnitTestCase.java
   projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/MockClassLoadingMetaDataUnitTestCase.java
   projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/metadata/test/ClassLoadingMetaDataUnitTestCase.java
   projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/metadata/test/ManagedObjectClassLoadingMetaDataUnitTestCase.java
Log:
[JBCL-138] [JBCL-139] - Shutdown policy and fixes for using a shutdown classloader

Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomain.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomain.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomain.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -67,6 +67,9 @@
    /** The parent */
    private Loader parent;
    
+   /** The shutdown policy */
+   private ShutdownPolicy shutdownPolicy;
+
    /** The MBeanServer */
    private MBeanServer mbeanServer;
    
@@ -148,6 +151,26 @@
    }
 
    /**
+    * Get the shutdownPolicy.
+    * 
+    * @return the shutdownPolicy.
+    */
+   public ShutdownPolicy getShutdownPolicy()
+   {
+      return shutdownPolicy;
+   }
+
+   /**
+    * Set the shutdownPolicy.
+    * 
+    * @param shutdownPolicy the shutdownPolicy.
+    */
+   public void setShutdownPolicy(ShutdownPolicy shutdownPolicy)
+   {
+      this.shutdownPolicy = shutdownPolicy;
+   }
+
+   /**
     * Get the parent
     * 
     * @return the parent.

Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomainMBean.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomainMBean.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomainMBean.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -71,6 +71,13 @@
     * @return the parent.
     */
    String getParentDomainName();
+   
+   /**
+    * Get the shutdown policy
+    * 
+    * @return the shutdown policy
+    */
+   ShutdownPolicy getShutdownPolicy();
 
    /**
     * Get the classloaders

Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -56,6 +56,9 @@
 {
    /** The log */
    private static final Logger log = Logger.getLogger(ClassLoaderPolicy.class);
+   
+   /** The shutdown policy */
+   private ShutdownPolicy shutdownPolicy;
 
    /** The class not found handlers */
    private List<ClassNotFoundHandler> classNotFoundHandlers;
@@ -286,8 +289,28 @@
     * @throws IOException for any error
     */
    public abstract void getResources(String name, Set<URL> urls) throws IOException;
-   
+
    /**
+    * Get the shutdownPolicy.
+    * 
+    * @return the shutdownPolicy.
+    */
+   public ShutdownPolicy getShutdownPolicy()
+   {
+      return shutdownPolicy;
+   }
+
+   /**
+    * Set the shutdownPolicy.
+    * 
+    * @param shutdownPolicy the shutdownPolicy.
+    */
+   public void setShutdownPolicy(ShutdownPolicy shutdownPolicy)
+   {
+      this.shutdownPolicy = shutdownPolicy;
+   }
+
+   /**
     * Get the protection domain<p>
     * 
     * By default there is no protection domain<p>

Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystem.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystem.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystem.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -71,6 +71,9 @@
    /** Any translators */
    private List<Translator> translators;
    
+   /** The shutdown policy */
+   private ShutdownPolicy shutdownPolicy;
+   
    /** Whether the system is shutdown */
    private boolean shutdown = false;
    
@@ -104,6 +107,26 @@
    }
 
    /**
+    * Get the shutdownPolicy.
+    * 
+    * @return the shutdownPolicy.
+    */
+   public ShutdownPolicy getShutdownPolicy()
+   {
+      return shutdownPolicy;
+   }
+
+   /**
+    * Set the shutdownPolicy.
+    * 
+    * @param shutdownPolicy the shutdownPolicy.
+    */
+   public void setShutdownPolicy(ShutdownPolicy shutdownPolicy)
+   {
+      this.shutdownPolicy = shutdownPolicy;
+   }
+
+   /**
     * Get the default classloading domain
     * 
     * @return the default domain

Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystemMBean.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystemMBean.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystemMBean.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -46,4 +46,11 @@
     * @return the domain names
     */
    Set<String> getDomainNames();
+   
+   /**
+    * Get the shutdown policy
+    * 
+    * @return the shutdown policy
+    */
+   ShutdownPolicy getShutdownPolicy();
 }

Added: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ShutdownPolicy.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ShutdownPolicy.java	                        (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ShutdownPolicy.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -0,0 +1,41 @@
+/*
+* 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;
+
+/**
+ * ShutdownPolicy.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public enum ShutdownPolicy
+{
+   /**
+    * Shutdown the classloader when it is unregistered  
+    */
+   UNREGISTER,
+   
+   /**
+    * Shutdown the classloader when garbage collection is done
+    */
+   GARBAGE_COLLECTION
+}

Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoader.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoader.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoader.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -53,6 +53,7 @@
 import org.jboss.classloader.spi.DelegateLoader;
 import org.jboss.classloader.spi.Loader;
 import org.jboss.classloader.spi.PackageInformation;
+import org.jboss.classloader.spi.ShutdownPolicy;
 import org.jboss.classloading.spi.RealClassLoader;
 import org.jboss.logging.Logger;
 import org.jboss.util.collection.Iterators;
@@ -225,6 +226,12 @@
       return result;
    }
 
+   public ShutdownPolicy getShutdownPolicy()
+   {
+      BaseClassLoaderPolicy basePolicy = getPolicy();
+      return basePolicy.determineShutdownPolicy();
+   }
+
    /**
     * Get the policy.
     *
@@ -541,7 +548,7 @@
 
       if (domain != null)
          return domain.getResource(this, name);
-      return null;
+      return getResourceLocally(name, trace);
    }
 
    @Override
@@ -564,6 +571,8 @@
       Set<URL> resourceURLs = new TreeSet<URL>(ClassLoaderUtils.URLComparator.INSTANCE);
       if (domain != null)
          domain.getResources(this, name, resourceURLs);
+      else
+         getResourcesLocally(name, resourceURLs, trace);
       return resourceURLs;
    }
 
@@ -874,6 +883,14 @@
             log.trace(this + " got class from domain " + ClassLoaderUtils.classToString(result));
          return result;
       }
+      catch (ClassNotFoundException e)
+      {
+         throw e;
+      }
+      catch (Exception e)
+      {
+         throw new ClassNotFoundException("Class not found " + name, e);
+      }
       finally
       {
          unlock(trace, true);

Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -39,6 +39,7 @@
 import org.jboss.classloader.spi.ClassLoaderPolicy;
 import org.jboss.classloader.spi.DelegateLoader;
 import org.jboss.classloader.spi.Loader;
+import org.jboss.classloader.spi.ShutdownPolicy;
 import org.jboss.logging.Logger;
 
 /**
@@ -60,9 +61,6 @@
    
    /** The classloaders  in the order they were registered */
    private List<ClassLoaderInformation> classLoaders = new CopyOnWriteArrayList<ClassLoaderInformation>();
-
-   /** The classloader information by classloader */
-   private Map<ClassLoader, ClassLoaderInformation> infos = new ConcurrentHashMap<ClassLoader, ClassLoaderInformation>();
    
    /** The classloaders by package name */
    private Map<String, List<ClassLoaderInformation>> classLoadersByPackageName = new ConcurrentHashMap<String, List<ClassLoaderInformation>>();
@@ -204,8 +202,15 @@
     * @return true to load class on the parent loader
     */
    public abstract boolean isUseLoadClassForParent();
-   
+
    /**
+    * Get the shutdownPolicy.
+    * 
+    * @return the shutdownPolicy.
+    */
+   protected abstract ShutdownPolicy getShutdownPolicy();
+
+   /**
     * Transform the byte code<p>
     * 
     * By default, this delegates to the classloader system
@@ -345,8 +350,8 @@
       BaseClassLoaderPolicy policy;
       if (classLoader != null)
       {
-         info = infos.get(classLoader);
          policy = classLoader.getPolicy();
+         info = policy.getInformation();
          if (policy.isImportAll())
             allExports = true;
       }
@@ -425,7 +430,7 @@
       if (classLoader != null)
       {
          policy = classLoader.getPolicy();
-         info = infos.get(classLoader);
+         info = policy.getInformation();
          if (policy.isImportAll())
             allExports = true;
       }
@@ -483,7 +488,7 @@
       if (classLoader != null)
       {
          policy = classLoader.getPolicy();
-         info = infos.get(classLoader);
+         info = policy.getInformation();
          if (policy.isImportAll())
             allExports = true;
       }
@@ -536,7 +541,7 @@
       if (classLoader != null)
       {
          policy = classLoader.getPolicy();
-         info = infos.get(classLoader);
+         info = policy.getInformation();
          if (policy.isImportAll())
             allExports = true;
       }
@@ -605,7 +610,7 @@
       if (classLoader != null)
       {
          policy = classLoader.getPolicy();
-         info = infos.get(classLoader);
+         info = policy.getInformation();
          if (policy.isImportAll())
             allExports = true;
       }
@@ -1325,7 +1330,7 @@
          // Create the information
          ClassLoaderInformation info = new ClassLoaderInformation(classLoader, policy, order++);
          classLoaders.add(info);
-         infos.put(classLoader, info);
+         basePolicy.setInformation(info);
 
          // Index the packages
          String[] packageNames = policy.getPackageNames();
@@ -1376,14 +1381,20 @@
       }
 
       BaseClassLoaderPolicy policy = classLoader.getPolicy();
-      policy.unsetClassLoaderDomain(this);
+      ShutdownPolicy shutdownPolicy = determineShutdownPolicy(policy);
 
+      boolean shutdownNow = (ShutdownPolicy.UNREGISTER == shutdownPolicy);
+      if (shutdownNow)
+         policy.unsetClassLoaderDomain(this);
+
       // FINDBUGS: This synchronization is correct - more than addIfNotPresent behaviour
       synchronized (classLoaders)
       {
          // Remove the classloader
-         ClassLoaderInformation info = infos.remove(classLoader);
+         ClassLoaderInformation info = policy.getInformation();
          classLoaders.remove(info);
+         if (shutdownNow)
+            policy.setInformation(null);
          
          // Remove the package index
          String[] packageNames = policy.getPackageNames();
@@ -1416,6 +1427,39 @@
    }
 
    /**
+    * Determine the shutdown policy for the classloader policy
+    * 
+    * @param policy the classloader policy
+    * @return the shutdown policy
+    */
+   ShutdownPolicy determineShutdownPolicy(BaseClassLoaderPolicy policy)
+   {
+      if (policy == null)
+         throw new IllegalArgumentException("Null policy");
+
+      // From the policy
+      ShutdownPolicy shutdownPolicy = policy.getShutdownPolicy();
+      
+      // From the domain (us)
+      if (shutdownPolicy == null)
+         shutdownPolicy = this.getShutdownPolicy();
+      
+      // From the clasloader system
+      if (shutdownPolicy == null)
+      {
+         BaseClassLoaderSystem system = getClassLoaderSystem();
+         if (system != null)
+         shutdownPolicy = system.getShutdownPolicy();
+      }
+      
+      // The default behaviour
+      if (shutdownPolicy == null)
+         shutdownPolicy = ShutdownPolicy.UNREGISTER;
+      
+      return shutdownPolicy;
+   }
+   
+   /**
     * Get all the classloaders
     * 
     * @return the list of classloaders

Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderMBean.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderMBean.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderMBean.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -29,6 +29,8 @@
 
 import javax.management.ObjectName;
 
+import org.jboss.classloader.spi.ShutdownPolicy;
+
 /**
  * BaseClassLoaderMBean.
  * 
@@ -80,6 +82,13 @@
    boolean isValid();
    
    /**
+    * Get the shutdown policy
+    * 
+    * @return the shutdown policy
+    */
+   ShutdownPolicy getShutdownPolicy();
+   
+   /**
     * Get the exported packages
     * 
     * @return the exported packages

Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -31,6 +31,7 @@
 
 import org.jboss.classloader.spi.ClassLoaderDomain;
 import org.jboss.classloader.spi.DelegateLoader;
+import org.jboss.classloader.spi.ShutdownPolicy;
 import org.jboss.classloader.spi.translator.TranslatorUtils;
 import org.jboss.logging.Logger;
 import org.jboss.util.loading.Translator;
@@ -56,6 +57,9 @@
    /** The domain for this policy */
    private volatile BaseClassLoaderDomain domain;
 
+   /** The classloader information */
+   private volatile ClassLoaderInformation information;
+   
    /** The access control context for this policy */
    private AccessControlContext access;
 
@@ -77,6 +81,26 @@
    }
 
    /**
+    * Get the information.
+    * 
+    * @return the information.
+    */
+   ClassLoaderInformation getInformation()
+   {
+      return information;
+   }
+
+   /**
+    * Set the information.
+    * 
+    * @param information the information.
+    */
+   void setInformation(ClassLoaderInformation information)
+   {
+      this.information = information;
+   }
+
+   /**
     * Get the access control context for this policy
     * 
     * @return the access control context
@@ -195,6 +219,30 @@
     * @return the classloader
     */
    protected abstract ClassLoader isJDKRequest(String name);
+
+   /**
+    * Get the shutdownPolicy.
+    * 
+    * @return the shutdownPolicy.
+    */
+   protected abstract ShutdownPolicy getShutdownPolicy();
+
+   /**
+    * Determine the shutdown policy for this domain
+    * 
+    * @return the shutdown policy
+    */
+   ShutdownPolicy determineShutdownPolicy()
+   {
+      BaseClassLoaderDomain domain = getClassLoaderDomain();
+      if (domain == null)
+      {
+         ShutdownPolicy result = getShutdownPolicy();
+         if (result == null)
+            result = ShutdownPolicy.UNREGISTER;
+      }
+      return domain.determineShutdownPolicy(this);
+   }
    
    /**
     * A long version of toString()

Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderSystem.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderSystem.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderSystem.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -26,6 +26,7 @@
 import java.security.ProtectionDomain;
 
 import org.jboss.classloader.spi.ClassLoaderPolicy;
+import org.jboss.classloader.spi.ShutdownPolicy;
 
 /**
  * Base ClassLoaderSystem.
@@ -36,6 +37,13 @@
 public abstract class BaseClassLoaderSystem
 {
    /**
+    * Get the shutdownPolicy.
+    * 
+    * @return the shutdownPolicy.
+    */
+   protected abstract ShutdownPolicy getShutdownPolicy();
+
+   /**
     * A long version of toString()
     * 
     * @return the long string

Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/filter/ClassFilter.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/filter/ClassFilter.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/filter/ClassFilter.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -23,6 +23,11 @@
 
 import java.io.Serializable;
 
+import org.jboss.classloader.plugins.filter.EverythingClassFilter;
+import org.jboss.classloader.plugins.filter.JavaOnlyClassFilter;
+import org.jboss.classloader.plugins.filter.NothingButJavaClassFilter;
+import org.jboss.classloader.plugins.filter.NothingClassFilter;
+
 /**
  * ClassFilter.
  * 
@@ -31,6 +36,30 @@
  */
 public interface ClassFilter extends Serializable
 {
+   /** Match evertything
+    * 
+    *  @deprecated use {@link ClassFilterUtils#EVERYTHING}
+    */
+   ClassFilter EVERYTHING = EverythingClassFilter.INSTANCE;
+
+   /** Match nothing
+    * 
+    *  @deprecated use {@link ClassFilterUtils#NOTHING}
+    */
+   ClassFilter NOTHING = NothingClassFilter.INSTANCE;
+
+   /** Match nothing 
+    * 
+    *  @deprecated use {@link ClassFilterUtils#NOTHING_BUT_JAVA}
+    */
+   ClassFilter NOTHING_BUT_JAVA = NothingButJavaClassFilter.INSTANCE;
+
+   /** Java Only
+    * 
+    *  @deprecated use {@link ClassFilterUtils#JAVA_ONLY}
+    */
+   ClassFilter JAVA_ONLY = JavaOnlyClassFilter.INSTANCE;
+
    /** 
     * Whether the class name matches the filter
     * 

Modified: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/AbstractClassLoaderTest.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/AbstractClassLoaderTest.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/AbstractClassLoaderTest.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -21,6 +21,10 @@
  */
 package org.jboss.test.classloader;
 
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+
 import junit.framework.TestCase;
 
 import org.jboss.classloader.plugins.ClassLoaderUtils;
@@ -208,8 +212,8 @@
    {
       try
       {
-         start.loadClass(name);
-         fail("Should not be here!");
+         Class<?> clazz = start.loadClass(name);
+         fail("Should not be here! " + ClassLoaderUtils.classToString(clazz));
       }
       catch (Exception expected)
       {
@@ -295,6 +299,34 @@
       assertEquals(policy.getName(), pkge.getImplementationTitle());
    }
    
+   protected URL assertGetResource(Class<?> reference, ClassLoader start) throws IOException
+   {
+      String resourceName = ClassLoaderUtils.classNameToPath(reference);
+      URL expected = getResource("/" + resourceName);
+
+      URL actual = start.getResource(resourceName);
+      getLog().debug("Got resource " + actual + " for " + resourceName);
+      assertEquals(expected, actual);
+      
+      Enumeration<URL> resources = start.getResources(resourceName);
+      assertTrue("Expected to find resources for " + resourceName, resources.hasMoreElements());
+      actual = resources.nextElement();
+      getLog().debug("Got resources " + actual + " for " + resourceName);
+      assertEquals(expected, actual);
+      assertFalse("Expected to find only one resource for " + resourceName, resources.hasMoreElements());
+      return actual;
+   }
+   
+   protected void assertGetResourceFail(Class<?> reference, ClassLoader start) throws IOException
+   {
+      String resourceName = ClassLoaderUtils.classNameToPath(reference);
+      URL actual = start.getResource(resourceName);
+      assertNull("Didn't expect " + actual + " for " + resourceName, start.getResource(resourceName));
+      
+      Enumeration<URL> resources = start.getResources(resourceName);
+      assertFalse("Didn't expected to find resources for " + resourceName, resources.hasMoreElements());
+   }
+   
    protected void assertFilterMatchesClassName(String test, ClassFilter filter)
    {
       getLog().debug("Checking " + test + " expect it to match filter=" + filter);

Modified: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/ClassLoaderAllTestSuite.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/ClassLoaderAllTestSuite.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/ClassLoaderAllTestSuite.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -28,6 +28,7 @@
 import org.jboss.test.classloader.delegate.DelegateTestSuite;
 import org.jboss.test.classloader.domain.ClassLoaderDomainTestSuite;
 import org.jboss.test.classloader.filter.FilterTestSuite;
+import org.jboss.test.classloader.general.GeneralTestSuite;
 import org.jboss.test.classloader.jmx.JMXTestSuite;
 import org.jboss.test.classloader.junit.JUnitTestSuite;
 import org.jboss.test.classloader.notifications.ClassLoaderNotificationsTestSuite;
@@ -69,6 +70,7 @@
       suite.addTest(ClassLoaderDomainTestSuite.suite());
       suite.addTest(ClassLoaderPolicyUnitTestCase.suite());
       suite.addTest(BootstrapTestSuite.suite());
+      suite.addTest(GeneralTestSuite.suite());
       suite.addTest(OldTestSuite.suite());
       suite.addTest(FilterTestSuite.suite());
       suite.addTest(DelegateTestSuite.suite());

Added: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/GeneralTestSuite.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/GeneralTestSuite.java	                        (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/GeneralTestSuite.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, 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.general;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import org.jboss.test.classloader.general.test.ShutdownUnitTestCase;
+
+/**
+ * General Test Suite.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 37459 $
+ */
+public class GeneralTestSuite 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("General Tests");
+
+      suite.addTest(ShutdownUnitTestCase.suite());
+      
+      return suite;
+   }
+}

Added: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/support/A.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/support/A.java	                        (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/support/A.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -0,0 +1,27 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, 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.general.support;
+
+public class A
+{
+
+}

Added: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/test/ShutdownUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/test/ShutdownUnitTestCase.java	                        (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/general/test/ShutdownUnitTestCase.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -0,0 +1,164 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, 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.general.test;
+
+import java.util.Collections;
+
+import junit.framework.Test;
+
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.spi.DelegateLoader;
+import org.jboss.classloader.spi.ShutdownPolicy;
+import org.jboss.classloader.test.support.MockClassLoaderPolicy;
+import org.jboss.test.classloader.AbstractClassLoaderTest;
+import org.jboss.test.classloader.general.support.A;
+
+/**
+ * ShutdownUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ShutdownUnitTestCase extends AbstractClassLoaderTest
+{
+   public static Test suite()
+   {
+      return suite(ShutdownUnitTestCase.class);
+   }
+
+   public ShutdownUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   public void testSimpleShutdown() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MockClassLoaderPolicy policyA = createMockClassLoaderPolicy("a");
+      policyA.setPathsAndPackageNames(A.class);
+      ClassLoader clA = system.registerClassLoaderPolicy(policyA);
+      assertLoadClass(A.class, clA);
+      assertGetResource(A.class, clA);
+      
+      system.unregisterClassLoader(clA);
+      // This is actually correct, we can load from ourselves after shutdown
+      assertLoadClass(A.class, clA); 
+      assertGetResource(A.class, clA);
+   }
+   
+   public void testShutdownImportAll() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MockClassLoaderPolicy policyA = createMockClassLoaderPolicy("a");
+      policyA.setPathsAndPackageNames(A.class);
+      ClassLoader clA = system.registerClassLoaderPolicy(policyA);
+      assertLoadClass(A.class, clA);
+      assertGetResource(A.class, clA);
+
+      MockClassLoaderPolicy policyB = createMockClassLoaderPolicy("b");
+      policyB.setImportAll(true);
+      ClassLoader clB = system.registerClassLoaderPolicy(policyB);
+      assertLoadClass(A.class, clB, clA);
+      assertGetResource(A.class, clB);
+      
+      system.unregisterClassLoader(clA);
+      assertLoadClassFail(A.class, clB);
+      assertGetResourceFail(A.class, clB);
+   }
+   
+   public void testShutdownImport() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MockClassLoaderPolicy policyA = createMockClassLoaderPolicy("a");
+      policyA.setPathsAndPackageNames(A.class);
+      ClassLoader clA = system.registerClassLoaderPolicy(policyA);
+      assertLoadClass(A.class, clA);
+      assertGetResource(A.class, clA);
+
+      MockClassLoaderPolicy policyB = createMockClassLoaderPolicy("b");
+      policyB.setDelegates(Collections.singletonList(new DelegateLoader(policyA)));
+      ClassLoader clB = system.registerClassLoaderPolicy(policyB);
+      assertLoadClass(A.class, clB, clA);
+      assertGetResource(A.class, clB);
+      
+      system.unregisterClassLoader(clA);
+      assertLoadClassFail(A.class, clB);
+      assertGetResourceFail(A.class, clB);
+   }
+   
+   public void testLazyShutdown() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MockClassLoaderPolicy policyA = createMockClassLoaderPolicy("a");
+      policyA.setPathsAndPackageNames(A.class);
+      policyA.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+      ClassLoader clA = system.registerClassLoaderPolicy(policyA);
+      assertLoadClass(A.class, clA);
+      assertGetResource(A.class, clA);
+      
+      system.unregisterClassLoader(clA);
+      assertLoadClass(A.class, clA); 
+      assertGetResource(A.class, clA);
+   }
+   
+   public void testLazyImportAll() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MockClassLoaderPolicy policyA = createMockClassLoaderPolicy("a");
+      policyA.setPathsAndPackageNames(A.class);
+      policyA.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+      ClassLoader clA = system.registerClassLoaderPolicy(policyA);
+      assertLoadClass(A.class, clA);
+      assertGetResource(A.class, clA);
+
+      MockClassLoaderPolicy policyB = createMockClassLoaderPolicy("b");
+      policyB.setImportAll(true);
+      ClassLoader clB = system.registerClassLoaderPolicy(policyB);
+      assertLoadClass(A.class, clB, clA);
+      assertGetResource(A.class, clB);
+      
+      system.unregisterClassLoader(clA);
+      assertLoadClassFail(A.class, clB);
+      assertGetResourceFail(A.class, clB);
+   }
+   
+   public void testLazyImport() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      MockClassLoaderPolicy policyA = createMockClassLoaderPolicy("a");
+      policyA.setPathsAndPackageNames(A.class);
+      policyA.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+      ClassLoader clA = system.registerClassLoaderPolicy(policyA);
+      assertLoadClass(A.class, clA);
+      assertGetResource(A.class, clA);
+
+      MockClassLoaderPolicy policyB = createMockClassLoaderPolicy("b");
+      policyB.setDelegates(Collections.singletonList(new DelegateLoader(policyA)));
+      ClassLoader clB = system.registerClassLoaderPolicy(policyB);
+      assertLoadClass(A.class, clB, clA);
+      assertGetResource(A.class, clB);
+      
+      system.unregisterClassLoader(clA);
+      assertLoadClass(A.class, clB, clA);
+      assertGetResource(A.class, clB);
+   }
+}

Modified: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/jmx/test/JMXUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/jmx/test/JMXUnitTestCase.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/jmx/test/JMXUnitTestCase.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -43,6 +43,7 @@
 import org.jboss.classloader.spi.ClassLoaderDomain;
 import org.jboss.classloader.spi.ClassLoaderSystem;
 import org.jboss.classloader.spi.ParentPolicy;
+import org.jboss.classloader.spi.ShutdownPolicy;
 import org.jboss.classloader.test.support.MockClassLoaderPolicy;
 import org.jboss.classloading.spi.RealClassLoader;
 import org.jboss.test.classloader.AbstractClassLoaderTest;
@@ -111,6 +112,7 @@
    public void testClassLoaderSystemMBean() throws Exception
    {
       ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      system.setShutdownPolicy(ShutdownPolicy.UNREGISTER);
       MBeanServer server = MBeanServerFactory.newMBeanServer();
       server.registerMBean(system, CLASSLOADER_SYSTEM_OBJECT_NAME);
       
@@ -123,7 +125,7 @@
       Set<ObjectName> domains = (Set) server.getAttribute(CLASSLOADER_SYSTEM_OBJECT_NAME, "Domains");
       Set<ObjectName> expectedObjectNames = makeSet(defaultDomainObjectName);
       assertEquals(expectedObjectNames, domains);
-      
+      assertEquals(ShutdownPolicy.UNREGISTER, server.getAttribute(CLASSLOADER_SYSTEM_OBJECT_NAME, "ShutdownPolicy"));
       String domainName = (String) server.getAttribute(defaultDomainObjectName, "Name");
       assertEquals(ClassLoaderSystem.DEFAULT_DOMAIN_NAME, domainName);
    }
@@ -218,6 +220,7 @@
 
       ClassLoaderDomain defaultDomain = system.getDefaultDomain();
       ClassLoaderDomain domain = system.createAndRegisterDomain("test", ParentPolicy.AFTER_BUT_JAVA_BEFORE, defaultDomain);
+      domain.setShutdownPolicy(ShutdownPolicy.UNREGISTER);
 
       ObjectName testObjectName = domain.getObjectName();
       assertEquals(CLASSLOADER_SYSTEM_OBJECT_NAME, server.getAttribute(testObjectName, "System"));
@@ -225,6 +228,7 @@
       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"));
+      assertEquals(ShutdownPolicy.UNREGISTER, server.getAttribute(testObjectName, "ShutdownPolicy"));
    }
 
    public void testRegisterClassLoader() throws Exception
@@ -383,6 +387,7 @@
       assertEquals("test", server.getAttribute(testObjectName, "Name"));
       assertTrue((Boolean) server.getAttribute(testObjectName, "ImportAll"));
       assertTrue((Boolean) server.getAttribute(testObjectName, "Valid"));
+      assertEquals(ShutdownPolicy.UNREGISTER, server.getAttribute(testObjectName, "ShutdownPolicy"));
       Set<String> expectedPackages = makeSet(A.class.getPackage().getName(), B.class.getPackage().getName());
       assertEquals(expectedPackages, server.invoke(testObjectName, "listExportedPackages", null, null));
       List<ObjectName> expectedImports = Arrays.asList(clA.getObjectName(), clB.getObjectName()); 

Modified: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/junit/test/IsolatedClassLoaderUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/junit/test/IsolatedClassLoaderUnitTestCase.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/junit/test/IsolatedClassLoaderUnitTestCase.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -113,7 +113,7 @@
       }
       catch (Throwable t)
       {
-         checkThrowable(IllegalStateException.class, t);
+         checkThrowable(NoClassDefFoundError.class, t);
       }
       
       try

Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Module.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Module.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/Module.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -41,6 +41,8 @@
 import org.jboss.classloader.spi.ClassLoaderSystem;
 import org.jboss.classloader.spi.DelegateLoader;
 import org.jboss.classloader.spi.ParentPolicy;
+import org.jboss.classloader.spi.ShutdownPolicy;
+import org.jboss.classloader.spi.base.BaseClassLoader;
 import org.jboss.classloader.spi.filter.ClassFilter;
 import org.jboss.classloader.spi.filter.FilteredDelegateLoader;
 import org.jboss.classloader.spi.filter.PackageClassFilter;
@@ -58,6 +60,7 @@
 import org.jboss.dependency.spi.ControllerContext;
 import org.jboss.dependency.spi.ControllerState;
 import org.jboss.dependency.spi.DependencyInfo;
+import org.jboss.dependency.spi.DependencyItem;
 
 /**
  * Module.
@@ -113,11 +116,16 @@
 
       modulesByClassLoader.put(classLoader, module);
 
+      // This is hack - we might not know until the classloader gets constructed whether
+      // it is in a domain that specifies lazy shutdown of the classloader
+      if (module.isCascadeShutdown() == false)
+         module.enableLazyShutdown();
+      
       LifeCycle lifeCycle = module.getLifeCycle();
       if (lifeCycle != null)
          lifeCycle.fireResolved();
    }
-
+   
    /**
     * Register a classloader for a module
     * 
@@ -301,6 +309,33 @@
    }
 
    /**
+    * Get the shutdown policy
+    * 
+    * @return the shutdown policy
+    */
+   public ShutdownPolicy getShutdownPolicy()
+   {
+      return null;
+   }
+
+   /**
+    * Whether to casecade the shutdown
+    * 
+    * @return true to cascade the shutdown
+    */
+   public boolean isCascadeShutdown()
+   {
+      // This is ugly
+      ClassLoader cl = getClassLoader();
+      if (cl != null && cl instanceof BaseClassLoader)
+      {
+         ShutdownPolicy shutdownPolicy = ((BaseClassLoader) cl).getShutdownPolicy();
+         return ShutdownPolicy.GARBAGE_COLLECTION != shutdownPolicy;
+      }
+      return true;
+   }
+
+   /**
     * Get a filter for the included packages
     * 
     * @return the excluded packages
@@ -1060,4 +1095,24 @@
          return false;
       return super.equals(obj);
    }
+
+   // It is lazy shutdown so remove anything that depends upon us for a requirement
+   // We can still handle it after the classloader gets unregistered
+   private void enableLazyShutdown()
+   {
+      ControllerContext ctx = getControllerContext();
+      if (ctx != null)
+      {
+         DependencyInfo info = ctx.getDependencyInfo();
+         if (info != null)
+         {
+            Set<DependencyItem> items = info.getDependsOnMe(RequirementDependencyItem.class);
+            if (items != null && items.isEmpty() == false)
+            {
+               for (DependencyItem item : items)
+                  info.removeDependsOnMe(item);
+            }
+         }
+      }
+   }
 }

Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/RequirementDependencyItem.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -118,7 +118,6 @@
          Object iDependOn = module.getContextName();
          ControllerContext context = controller.getContext(iDependOn, null);
          setIDependOn(context.getName());
-         addDependsOnMe(controller, context);
          setResolved(true);
          return isResolved();
       }
@@ -129,7 +128,8 @@
       if (context != null)
       {
          setIDependOn(context.getName());
-         addDependsOnMe(controller, context);
+         if (module.isCascadeShutdown())
+            addDependsOnMe(controller, context);
          setResolved(true);
          if (module.getClassLoadingSpace() == null)
             log.warn(getModule() + " resolved " + getRequirement() + " to " + module + " which has import-all=true. Cannot check its consistency.");

Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/helpers/ClassLoadingMetaDataModule.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/helpers/ClassLoadingMetaDataModule.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/helpers/ClassLoadingMetaDataModule.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -23,6 +23,7 @@
 
 import java.util.List;
 
+import org.jboss.classloader.spi.ShutdownPolicy;
 import org.jboss.classloader.spi.filter.ClassFilter;
 import org.jboss.classloading.spi.dependency.Module;
 import org.jboss.classloading.spi.metadata.Capability;
@@ -112,6 +113,21 @@
    }
 
    @Override
+   public ShutdownPolicy getShutdownPolicy()
+   {
+      return classLoadingMetaData.getShutdownPolicy();
+   }
+
+   @Override
+   public boolean isCascadeShutdown()
+   {
+      if (super.isCascadeShutdown() == false)
+         return false;
+      ShutdownPolicy shutdownPolicy = getShutdownPolicy();
+      return ShutdownPolicy.GARBAGE_COLLECTION != shutdownPolicy;
+   }
+
+   @Override
    public ClassFilter getIncluded()
    {
       return classLoadingMetaData.getIncluded();

Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/mock/MockClassLoaderPolicyModule.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/mock/MockClassLoaderPolicyModule.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/dependency/policy/mock/MockClassLoaderPolicyModule.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -274,6 +274,7 @@
       policy.setIncluded(metaData.getIncludedClasses());
       policy.setExcluded(metaData.getExcludedClasses());
       policy.setImportAll(isImportAll());
+      policy.setShutdownPolicy(getShutdownPolicy());
       policy.setDelegates(getDelegates());
       return policy;
    }

Modified: projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/metadata/ClassLoadingMetaData.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/metadata/ClassLoadingMetaData.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading/src/main/java/org/jboss/classloading/spi/metadata/ClassLoadingMetaData.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -27,6 +27,7 @@
 import javax.xml.bind.annotation.XmlTransient;
 
 import org.jboss.classloader.plugins.filter.CombiningClassFilter;
+import org.jboss.classloader.spi.ShutdownPolicy;
 import org.jboss.classloader.spi.filter.ClassFilter;
 import org.jboss.classloader.spi.filter.PackageClassFilter;
 import org.jboss.classloading.spi.helpers.NameAndVersionSupport;
@@ -66,6 +67,9 @@
    /** Whether we are blacklistable */
    private boolean blackListable = true;
    
+   /** The shutdown policy */
+   private ShutdownPolicy shutdownPolicy;
+   
    /** Whether to export all */
    private ExportAll exportAll;
    
@@ -429,6 +433,28 @@
    }
 
    /**
+    * Get the shutdown policy
+    * 
+    * @return the shutdown policy.
+    */
+   public ShutdownPolicy getShutdownPolicy()
+   {
+      return shutdownPolicy;
+   }
+
+   /**
+    * Set the shutdown policy.
+    * 
+    * @param shutdownPolicy the sjutdown policy
+    */
+   @ManagementProperty(name="shutdown")
+   @XmlAttribute(name="shutdown")
+   public void setShutdownPolicy(ShutdownPolicy shutdownPolicy)
+   {
+      this.shutdownPolicy = shutdownPolicy;
+   }
+
+   /**
     * Get the capabilities.
     * 
     * @return the capabilities.
@@ -557,6 +583,8 @@
       if (isImportAll())
          builder.append(" IMPORT-ALL");
       builder.append(" parent-first=").append(isJ2seClassLoadingCompliance());
+      if (shutdownPolicy != null)
+         builder.append(" ").append(shutdownPolicy);
       if (isCacheable() == false)
          builder.append(" NO-CACHE");
       if (isBlackListable() == false)
@@ -590,6 +618,8 @@
          return false;
       if (this.isImportAll() != other.isImportAll())
          return false;
+      if (equals(this.getShutdownPolicy(), other.getShutdownPolicy()) == false)
+         return false;
       if (this.isJ2seClassLoadingCompliance() != other.isJ2seClassLoadingCompliance())
          return false;
       if (this.isCacheable() != other.isCacheable())

Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/DependencyUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/DependencyUnitTestCase.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/DependencyUnitTestCase.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -25,6 +25,10 @@
 import java.util.Set;
 
 import junit.framework.Test;
+
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ParentPolicy;
+import org.jboss.classloader.spi.ShutdownPolicy;
 import org.jboss.classloading.spi.dependency.policy.mock.MockClassLoadingMetaData;
 import org.jboss.classloading.spi.metadata.ClassLoadingMetaDataFactory;
 import org.jboss.classloading.spi.metadata.Requirement;
@@ -302,4 +306,102 @@
       }
       assertNoClassLoader(contextA);
    }
+   
+   public void testBDependsALazyShutdownA() throws Exception
+   {
+      MockClassLoadingMetaData a = new MockClassLoadingMetaData("a");
+      a.setPathsAndPackageNames(A.class);
+      a.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+      KernelControllerContext contextA = install(a);
+      try
+      {
+         ClassLoader clA = assertClassLoader(contextA);
+         assertLoadClass(A.class, clA);
+         assertLoadClassFail(B.class, clA);
+
+         MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+         b.setPathsAndPackageNames(B.class);
+         ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+         Requirement requirement = factory.createRequirePackage(A.class.getPackage().getName());
+         b.setRequirements(Collections.singletonList(requirement));
+         KernelControllerContext contextB = install(b);
+         try
+         {
+            assertLoadClass(A.class, clA);
+            assertLoadClassFail(B.class, clA);
+            ClassLoader clB = assertClassLoader(contextB);
+            assertLoadClass(B.class, clB);
+            assertLoadClass(A.class, clB, clA);
+            
+            uninstall(contextA);
+            assertLoadClass(A.class, clA);
+            assertLoadClassFail(B.class, clA);
+            assertModule(contextB);
+            assertLoadClass(B.class, clB);
+            assertLoadClass(A.class, clB, clA);
+         }
+         finally
+         {
+            uninstall(contextB);
+         }
+         assertLoadClass(A.class, clA);
+         assertLoadClassFail(B.class, clA);
+         assertNoClassLoader(contextB);
+      }
+      finally
+      {
+      }
+      assertNoClassLoader(contextA);
+   }
+   
+   public void testBDependsALazyShutdownAConfiguredOnDomain() throws Exception
+   {
+      ClassLoaderDomain domain = system.createAndRegisterDomain("LazyShutdown", ParentPolicy.BEFORE_BUT_JAVA_ONLY);
+      domain.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+      
+      MockClassLoadingMetaData a = new MockClassLoadingMetaData("a");
+      a.setPathsAndPackageNames(A.class);
+      a.setDomain(domain.getName());
+      KernelControllerContext contextA = install(a);
+      try
+      {
+         ClassLoader clA = assertClassLoader(contextA);
+         assertLoadClass(A.class, clA);
+         assertLoadClassFail(B.class, clA);
+
+         MockClassLoadingMetaData b = new MockClassLoadingMetaData("b");
+         b.setPathsAndPackageNames(B.class);
+         b.setDomain(domain.getName());
+         ClassLoadingMetaDataFactory factory = ClassLoadingMetaDataFactory.getInstance();
+         Requirement requirement = factory.createRequirePackage(A.class.getPackage().getName());
+         b.setRequirements(Collections.singletonList(requirement));
+         KernelControllerContext contextB = install(b);
+         try
+         {
+            assertLoadClass(A.class, clA);
+            assertLoadClassFail(B.class, clA);
+            ClassLoader clB = assertClassLoader(contextB);
+            assertLoadClass(B.class, clB);
+            assertLoadClass(A.class, clB, clA);
+            
+            uninstall(contextA);
+            assertLoadClass(A.class, clA);
+            assertLoadClassFail(B.class, clA);
+            assertModule(contextB);
+            assertLoadClass(B.class, clB);
+            assertLoadClass(A.class, clB, clA);
+         }
+         finally
+         {
+            uninstall(contextB);
+         }
+         assertLoadClass(A.class, clA);
+         assertLoadClassFail(B.class, clA);
+         assertNoClassLoader(contextB);
+      }
+      finally
+      {
+      }
+      assertNoClassLoader(contextA);
+   }
 }

Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/MockClassLoadingMetaDataUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/MockClassLoadingMetaDataUnitTestCase.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/dependency/test/MockClassLoadingMetaDataUnitTestCase.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -28,6 +28,7 @@
 import junit.framework.Test;
 
 import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.spi.ShutdownPolicy;
 import org.jboss.classloader.spi.filter.ClassFilterUtils;
 import org.jboss.classloading.spi.dependency.policy.mock.MockClassLoaderPolicyModule;
 import org.jboss.classloading.spi.dependency.policy.mock.MockClassLoadingMetaData;
@@ -156,6 +157,23 @@
       assertNoModule(contextA);
    }
    
+   public void testShutdownPolicy() throws Exception
+   {
+      MockClassLoadingMetaData a = new MockClassLoadingMetaData("a");
+      a.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+      KernelControllerContext contextA = install(a);
+      try
+      {
+         MockClassLoaderPolicyModule module = assertModule(contextA);
+         assertEquals(ShutdownPolicy.GARBAGE_COLLECTION, module.getShutdownPolicy());
+      }
+      finally
+      {
+         uninstall(contextA);
+      }
+      assertNoModule(contextA);
+   }
+   
    public void testIncluded() throws Exception
    {
       MockClassLoadingMetaData a = new MockClassLoadingMetaData("a");

Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/metadata/test/ClassLoadingMetaDataUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/metadata/test/ClassLoadingMetaDataUnitTestCase.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/metadata/test/ClassLoadingMetaDataUnitTestCase.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -26,6 +26,7 @@
 
 import junit.framework.Test;
 
+import org.jboss.classloader.spi.ShutdownPolicy;
 import org.jboss.classloader.spi.filter.ClassFilter;
 import org.jboss.classloader.spi.filter.ClassFilterUtils;
 import org.jboss.classloading.spi.metadata.CapabilitiesMetaData;
@@ -65,6 +66,7 @@
       assertNull(test.getDomain());
       assertNull(test.getParentDomain());
       assertNull(test.getExportAll());
+      assertNull(test.getShutdownPolicy());
       assertNull(test.getIncluded());
       assertNull(test.getExcluded());
       assertNull(test.getExcludedExport());
@@ -154,6 +156,19 @@
       testEquals(test, test2, true);
    }
    
+   public void testSetShutdownPolicy() throws Exception
+   {
+      ClassLoadingMetaData test = new ClassLoadingMetaData();
+      assertNull(test.getShutdownPolicy());
+      test.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+      assertEquals(ShutdownPolicy.GARBAGE_COLLECTION, test.getShutdownPolicy());
+
+      ClassLoadingMetaData test2 = new ClassLoadingMetaData();
+      testEquals(test, test2, false);
+      test2.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+      testEquals(test, test2, true);
+   }
+   
    public void testSetIncludedPackages() throws Exception
    {
       ClassLoadingMetaData test = new ClassLoadingMetaData();
@@ -365,6 +380,7 @@
       test.setParentDomain("parent-domain");
       test.setExportAll(ExportAll.ALL);
       test.setImportAll(true);
+      test.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
       test.setJ2seClassLoadingCompliance(false);
       test.getCapabilities().addCapability(factory.createModule("module", "1.0.0"));
       test.getCapabilities().addCapability(factory.createPackage("package", "1.0.0"));

Modified: projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/metadata/test/ManagedObjectClassLoadingMetaDataUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/metadata/test/ManagedObjectClassLoadingMetaDataUnitTestCase.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading/src/test/java/org/jboss/test/classloading/metadata/test/ManagedObjectClassLoadingMetaDataUnitTestCase.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -27,6 +27,7 @@
 
 import junit.framework.Test;
 
+import org.jboss.classloader.spi.ShutdownPolicy;
 import org.jboss.classloading.spi.metadata.CapabilitiesMetaData;
 import org.jboss.classloading.spi.metadata.ClassLoadingMetaData;
 import org.jboss.classloading.spi.metadata.ClassLoadingMetaDataFactory;
@@ -68,7 +69,7 @@
    {
       ManagedObject result = moFactory.initManagedObject(test, null, null);
       assertNotNull(result);
-      List<String> expectedProperties = Arrays.asList("name", "version", "domain", "parentDomain", "topLevelClassLoader", "exportAll", "included", "excluded", "excludedExport", "importAll", "parentFirst", "cache", "blackList", "capabilities", "requirements");
+      List<String> expectedProperties = Arrays.asList("name", "version", "domain", "parentDomain", "topLevelClassLoader", "exportAll", "shutdown", "included", "excluded", "excludedExport", "importAll", "parentFirst", "cache", "blackList", "capabilities", "requirements");
       Set<String> actualProperties = result.getPropertyNames();
       for (String expected : expectedProperties)
       {
@@ -112,6 +113,7 @@
       assertManagedProperty(mo, "parentDomain", String.class, null);
       assertManagedProperty(mo, "topLevelClassLoader", boolean.class, false);
       assertManagedProperty(mo, "exportAll", ExportAll.class, null);
+      assertManagedProperty(mo, "shutdown", ShutdownPolicy.class, null);
       assertManagedProperty(mo, "included", String.class, null);
       assertManagedProperty(mo, "excluded", String.class, null);
       assertManagedProperty(mo, "excludedExport", String.class, null);
@@ -169,6 +171,14 @@
       assertManagedProperty(mo, "exportAll", ExportAll.class, ExportAll.ALL);
    }
 
+   public void testSetShutdownPolicy() throws Exception
+   {
+      ClassLoadingMetaData test = new ClassLoadingMetaData();
+      test.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+      ManagedObject mo = assertManagedObject(test);
+      assertManagedProperty(mo, "shutdown", ShutdownPolicy.class, ShutdownPolicy.GARBAGE_COLLECTION);
+   }
+
    public void testSetIncludedPackages() throws Exception
    {
       ClassLoadingMetaData test = new ClassLoadingMetaData();

Modified: projects/jboss-cl/trunk/classloading-vfs/src/main/java/org/jboss/classloading/spi/vfs/dependency/VFSClassLoaderPolicyModule.java
===================================================================
--- projects/jboss-cl/trunk/classloading-vfs/src/main/java/org/jboss/classloading/spi/vfs/dependency/VFSClassLoaderPolicyModule.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading-vfs/src/main/java/org/jboss/classloading/spi/vfs/dependency/VFSClassLoaderPolicyModule.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -217,6 +217,7 @@
       policy.setExcludedExport(getExcludedExport());
       policy.setExportAll(getExportAll());
       policy.setImportAll(isImportAll());
+      policy.setShutdownPolicy(getShutdownPolicy());
       policy.setCacheable(isCacheable());
       policy.setBlackListable(isBlackListable());
       policy.setDelegates(getDelegates());

Modified: projects/jboss-cl/trunk/classloading-vfs/src/main/resources/schema/jboss-classloader-1.0.xsd
===================================================================
--- projects/jboss-cl/trunk/classloading-vfs/src/main/resources/schema/jboss-classloader-1.0.xsd	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading-vfs/src/main/resources/schema/jboss-classloader-1.0.xsd	2010-01-21 13:37:05 UTC (rev 99748)
@@ -145,6 +145,15 @@
             </xsd:documentation>
          </xsd:annotation>
       </xsd:attribute>
+      <xsd:attribute name="shutdown" type="shutdown-policy" use="optional">
+         <xsd:annotation>
+            <xsd:documentation>
+               <![CDATA[
+               The shutdown policy for the classloader.
+               ]]>
+            </xsd:documentation>
+         </xsd:annotation>
+      </xsd:attribute>
       <xsd:attribute name="included" type="xsd:string" use="optional">
          <xsd:annotation>
             <xsd:documentation>
@@ -383,4 +392,17 @@
       </xsd:annotation>
       <xsd:restriction base="xsd:string"/>
    </xsd:simpleType>
+
+   <xsd:simpleType name="shutdown-policy">
+      <xsd:annotation>
+         <xsd:documentation>
+            <![CDATA[
+            When to shutdown the classloader
+            UNREGISTER - shutdown when the classloader is unregistered (the default)
+            GARBAGE_COLLECTION - shutdown at garbage collection
+            ]]>
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:restriction base="xsd:string"/>
+   </xsd:simpleType>
 </xsd:schema>

Modified: projects/jboss-cl/trunk/classloading-vfs/src/main/resources/schema/jboss-classloading-1.0.xsd
===================================================================
--- projects/jboss-cl/trunk/classloading-vfs/src/main/resources/schema/jboss-classloading-1.0.xsd	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading-vfs/src/main/resources/schema/jboss-classloading-1.0.xsd	2010-01-21 13:37:05 UTC (rev 99748)
@@ -133,6 +133,15 @@
             </xsd:documentation>
          </xsd:annotation>
       </xsd:attribute>
+      <xsd:attribute name="shutdown" type="shutdown-policy" use="optional">
+         <xsd:annotation>
+            <xsd:documentation>
+               <![CDATA[
+               The shutdown policy for the classloader.
+               ]]>
+            </xsd:documentation>
+         </xsd:annotation>
+      </xsd:attribute>
       <xsd:attribute name="included" type="xsd:string" use="optional">
          <xsd:annotation>
             <xsd:documentation>
@@ -361,4 +370,17 @@
       </xsd:annotation>
       <xsd:restriction base="xsd:string"/>
    </xsd:simpleType>
+
+   <xsd:simpleType name="shutdown-policy">
+      <xsd:annotation>
+         <xsd:documentation>
+            <![CDATA[
+            When to shutdown the classloader
+            UNREGISTER - shutdown when the classloader is unregistered (the default)
+            GARBAGE_COLLECTION - shutdown at garbage collection
+            ]]>
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:restriction base="xsd:string"/>
+   </xsd:simpleType>
 </xsd:schema>

Modified: projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/ClassLoadingVFSTestSuite.java
===================================================================
--- projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/ClassLoadingVFSTestSuite.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/ClassLoadingVFSTestSuite.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -41,6 +41,7 @@
 import org.jboss.test.classloading.vfs.metadata.xml.test.NoopClassLoaderFactoryXMLUnitTestCase;
 import org.jboss.test.classloading.vfs.policy.test.ExportAllUnitTestCase;
 import org.jboss.test.classloading.vfs.policy.test.PackageInfoUnitTestCase;
+import org.jboss.test.classloading.vfs.policy.test.ShutdownUnitTestCase;
 import org.jboss.test.classloading.vfs.policy.test.VFSCLPolicySignedCertsUnitTestCase;
 
 /**
@@ -87,6 +88,7 @@
       suite.addTest(PackageInfoUnitTestCase.suite());
       suite.addTest(GeneratedClassesUnitTestCase.suite());
       suite.addTest(VFSCLPolicySignedCertsUnitTestCase.suite());
+      suite.addTest(ShutdownUnitTestCase.suite());
 
       return suite;
    }

Modified: projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/vfs/metadata/test/ManagedObjectVFSClassLoaderFactoryUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/vfs/metadata/test/ManagedObjectVFSClassLoaderFactoryUnitTestCase.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/vfs/metadata/test/ManagedObjectVFSClassLoaderFactoryUnitTestCase.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -29,6 +29,7 @@
 
 import junit.framework.Test;
 
+import org.jboss.classloader.spi.ShutdownPolicy;
 import org.jboss.classloading.spi.metadata.CapabilitiesMetaData;
 import org.jboss.classloading.spi.metadata.ClassLoadingMetaDataFactory;
 import org.jboss.classloading.spi.metadata.ExportAll;
@@ -70,7 +71,7 @@
    {
       ManagedObject result = moFactory.initManagedObject(test, null, null);
       assertNotNull(result);
-      List<String> expectedProperties = Arrays.asList("name", "version", "context", "domain", "parentDomain", "topLevelClassLoader", "exportAll", "included", "excluded", "excludedExport", "importAll", "parentFirst", "cache", "blackList", "system", "roots", "capabilities", "requirements");
+      List<String> expectedProperties = Arrays.asList("name", "version", "context", "domain", "parentDomain", "topLevelClassLoader", "exportAll", "shutdown", "included", "excluded", "excludedExport", "importAll", "parentFirst", "cache", "blackList", "system", "roots", "capabilities", "requirements");
       Set<String> actualProperties = result.getPropertyNames();
       for (String expected : expectedProperties)
       {
@@ -119,6 +120,7 @@
       assertManagedProperty(mo, "parentDomain", String.class, null);
       assertManagedProperty(mo, "topLevelClassLoader", boolean.class, false);
       assertManagedProperty(mo, "exportAll", ExportAll.class, null);
+      assertManagedProperty(mo, "shutdown", ShutdownPolicy.class, null);
       assertManagedProperty(mo, "included", String.class, null);
       assertManagedProperty(mo, "excluded", String.class, null);
       assertManagedProperty(mo, "excludedExport", String.class, null);
@@ -184,6 +186,14 @@
       assertManagedProperty(mo, "exportAll", ExportAll.class, ExportAll.ALL);
    }
 
+   public void testSetShutdownPolicy() throws Exception
+   {
+      VFSClassLoaderFactory test = new VFSClassLoaderFactory();
+      test.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+      ManagedObject mo = assertManagedObject(test);
+      assertManagedProperty(mo, "shutdown", ShutdownPolicy.class, ShutdownPolicy.GARBAGE_COLLECTION);
+   }
+
    public void testSetIncludedPackages() throws Exception
    {
       VFSClassLoaderFactory test = new VFSClassLoaderFactory();

Modified: projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/vfs/metadata/xml/test/VFSClassLoaderFactoryXMLUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/vfs/metadata/xml/test/VFSClassLoaderFactoryXMLUnitTestCase.java	2010-01-21 13:36:48 UTC (rev 99747)
+++ projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/vfs/metadata/xml/test/VFSClassLoaderFactoryXMLUnitTestCase.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -27,6 +27,7 @@
 
 import junit.framework.Test;
 
+import org.jboss.classloader.spi.ShutdownPolicy;
 import org.jboss.classloading.spi.metadata.Capability;
 import org.jboss.classloading.spi.metadata.ClassLoadingMetaDataFactory;
 import org.jboss.classloading.spi.metadata.ExportAll;
@@ -66,6 +67,7 @@
       assertNull(result.getDomain());
       assertNull(result.getParentDomain());
       assertNull(result.getExportAll());
+      assertNull(result.getShutdownPolicy());
       assertNull(result.getIncludedPackages());
       assertNull(result.getExcludedPackages());
       assertNull(result.getExcludedExportPackages());
@@ -109,6 +111,12 @@
       assertEquals(ExportAll.ALL, result.getExportAll());
    }
 
+   public void testModuleShutdown() throws Exception
+   {
+      VFSClassLoaderFactory result = unmarshal();
+      assertEquals(ShutdownPolicy.GARBAGE_COLLECTION, result.getShutdownPolicy());
+   }
+
    public void testModuleIncluded() throws Exception
    {
       VFSClassLoaderFactory result = unmarshal();

Added: projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/vfs/policy/test/ShutdownUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/vfs/policy/test/ShutdownUnitTestCase.java	                        (rev 0)
+++ projects/jboss-cl/trunk/classloading-vfs/src/test/java/org/jboss/test/classloading/vfs/policy/test/ShutdownUnitTestCase.java	2010-01-21 13:37:05 UTC (rev 99748)
@@ -0,0 +1,115 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, 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.classloading.vfs.policy.test;
+
+import java.net.URL;
+import java.util.Collections;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.plugins.system.DefaultClassLoaderSystem;
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.spi.DelegateLoader;
+import org.jboss.classloader.spi.ShutdownPolicy;
+import org.jboss.classloader.test.support.MockClassLoaderPolicy;
+import org.jboss.classloading.spi.vfs.policy.VFSClassLoaderPolicy;
+import org.jboss.test.BaseTestCase;
+import org.jboss.virtual.VFS;
+import org.jboss.virtual.VirtualFile;
+
+/**
+ * ShutdownUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ShutdownUnitTestCase extends BaseTestCase
+{
+   public void testShutdownUnregisterDefault() throws Exception
+   {
+      VFSClassLoaderPolicy policy = getClassLoaderPolicy();;
+      testShutdown(policy, true);
+   }
+
+   public void testShutdownUnregister() throws Exception
+   {
+      VFSClassLoaderPolicy policy = getClassLoaderPolicy();;
+      policy.setShutdownPolicy(ShutdownPolicy.UNREGISTER);
+      testShutdown(policy, true);
+   }
+
+   public void testShutdownGC() throws Exception
+   {
+      VFSClassLoaderPolicy policy = getClassLoaderPolicy();;
+      policy.setShutdownPolicy(ShutdownPolicy.GARBAGE_COLLECTION);
+      testShutdown(policy, false);
+   }
+
+   protected VFSClassLoaderPolicy getClassLoaderPolicy() throws Exception
+   {
+      URL signedJarURL = getResource("/classloader/signedjar");
+      VirtualFile signedJarRoot = VFS.getRoot(signedJarURL);
+      VirtualFile signedJar = signedJarRoot.getChild("wstx.jar");
+      VFSClassLoaderPolicy policy = VFSClassLoaderPolicy.createVFSClassLoaderPolicy(signedJar);
+      return policy;
+   }
+   
+   protected void testShutdown(VFSClassLoaderPolicy policy, boolean shutdownAtUnregister) throws Exception
+   {
+      ClassLoaderSystem system = new DefaultClassLoaderSystem();
+      ClassLoader classLoader = system.registerClassLoaderPolicy(policy);
+      
+      Class<?> clazz = classLoader.loadClass("org.codehaus.stax2.validation.XMLValidator");
+      assertEquals(classLoader, clazz.getClassLoader());
+      
+      MockClassLoaderPolicy mock = new MockClassLoaderPolicy();
+      mock.setDelegates(Collections.singletonList(new DelegateLoader(policy)));
+      ClassLoader mockCl = system.registerClassLoaderPolicy(mock);
+      
+      clazz = mockCl.loadClass("org.codehaus.stax2.validation.XMLValidator");
+      assertEquals(classLoader, clazz.getClassLoader());
+      
+      system.unregisterClassLoader(classLoader);
+      try
+      {
+         clazz = mockCl.loadClass("org.codehaus.stax2.validation.XMLValidator");
+         if (shutdownAtUnregister)
+            fail("Should not be here: " + ClassLoaderUtils.classToString(clazz));
+      }
+      catch (ClassNotFoundException e)
+      {
+         assertTrue("Didn't expect: " + e, shutdownAtUnregister);
+      }
+   }
+
+   public static Test suite()
+   {
+      return new TestSuite(ShutdownUnitTestCase.class);
+   }
+
+   public ShutdownUnitTestCase(String name) throws Throwable
+   {
+      super(name);
+   }
+}

Added: projects/jboss-cl/trunk/classloading-vfs/src/test/resources/org/jboss/test/classloading/vfs/metadata/xml/test/ModuleShutdown.xml
===================================================================
--- projects/jboss-cl/trunk/classloading-vfs/src/test/resources/org/jboss/test/classloading/vfs/metadata/xml/test/ModuleShutdown.xml	                        (rev 0)
+++ projects/jboss-cl/trunk/classloading-vfs/src/test/resources/org/jboss/test/classloading/vfs/metadata/xml/test/ModuleShutdown.xml	2010-01-21 13:37:05 UTC (rev 99748)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<classloader xmlns="urn:jboss:classloader:1.0"
+              name="test"
+              shutdown="GARBAGE_COLLECTION">
+</classloader>




More information about the jboss-cvs-commits mailing list