[jboss-cvs] JBossAS SVN: r62605 - in projects/microcontainer/trunk: classloader and 33 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Apr 27 06:28:07 EDT 2007


Author: adrian at jboss.org
Date: 2007-04-27 06:28:07 -0400 (Fri, 27 Apr 2007)
New Revision: 62605

Added:
   projects/microcontainer/trunk/classloader/
   projects/microcontainer/trunk/classloader/.classpath
   projects/microcontainer/trunk/classloader/.project
   projects/microcontainer/trunk/classloader/.settings/
   projects/microcontainer/trunk/classloader/.settings/org.eclipse.jdt.core.prefs
   projects/microcontainer/trunk/classloader/pom.xml
   projects/microcontainer/trunk/classloader/src/
   projects/microcontainer/trunk/classloader/src/etc/
   projects/microcontainer/trunk/classloader/src/etc/default.mf
   projects/microcontainer/trunk/classloader/src/main/
   projects/microcontainer/trunk/classloader/src/main/org/
   projects/microcontainer/trunk/classloader/src/main/org/jboss/
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/ClassLoaderUtils.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/EverythingClassFilter.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/JavaOnlyClassFilter.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/NothingClassFilter.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/PackageClassFilter.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/PatternClassFilter.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/loader/
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/loader/ClassLoaderToLoaderAdapter.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/system/
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/system/ClassLoaderSystemBuilder.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/system/DefaultClassLoaderSystem.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/
   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/DelegateLoader.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/Loader.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/PackageInformation.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ParentPolicy.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/
   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/BaseClassLoaderPolicy.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderSystem.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseDelegateLoader.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoaderInformation.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoaderManager.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoadingTask.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/filter/
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/filter/ClassFilter.java
   projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/filter/FilteredDelegateLoader.java
   projects/microcontainer/trunk/classloader/src/tests/
   projects/microcontainer/trunk/classloader/src/tests/org/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/AbstractClassLoaderTest.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/ClassLoaderAllTestSuite.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/TestThread.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/bootstrap/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/bootstrap/BootstrapTestSuite.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/bootstrap/test/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/bootstrap/test/ModifiedBootstrapUnitTestCase.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/DelegateTestSuite.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/TestA1.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/TestAbstractFactory.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/TestSleep.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/b/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/b/TestB1.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/b/TestFactoryImplementation.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/test/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/test/DelegateUnitTestCase.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/OldTestSuite.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass0.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass1.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass2.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass3.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass4.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass5.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass6.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass7.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass8.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass9.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Base.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Class0.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Class1.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Class2.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Derived.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/LoginInfo.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Support.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UserOfBase.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UserOfLoginInfo.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UserOfUsrMgr.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UsrMgr.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/CircularLoadUnitTestCase.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/CircularityErrorUnitTestCase.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/ConcurrentLoaderUnitTestCase.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/LoaderUnitTestCase.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/support/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/support/MockClassLoaderPolicy.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/ClassLoadingSystemTestSuite.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/support/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/support/MockClassLoaderDomain.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/support/MockClassLoaderSystem.java
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/test/
   projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/test/ClassLoadingSystemUnitTestCase.java
Log:
Basic functionality of new classloader

Added: projects/microcontainer/trunk/classloader/.classpath
===================================================================
--- projects/microcontainer/trunk/classloader/.classpath	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/.classpath	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,22 @@
+<classpath>
+  <classpathentry kind="src" path="src/main"/>
+  <classpathentry kind="src" path="src/tests"/>
+  <classpathentry kind="output" path="target/eclipse-classes"/>
+  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+  <classpathentry kind="var" path="M2_REPO/jboss/jboss-logging-log4j/2.0.2.GA/jboss-logging-log4j-2.0.2.GA.jar" sourcepath="M2_REPO/jboss/jboss-logging-log4j/2.0.2.GA/jboss-logging-log4j-2.0.2.GA-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/jboss/jboss-common-logging-spi/2.0.4.GA/jboss-common-logging-spi-2.0.4.GA.jar" sourcepath="M2_REPO/jboss/jboss-common-logging-spi/2.0.4.GA/jboss-common-logging-spi-2.0.4.GA-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/apache-slide/webdavlib/2.0/webdavlib-2.0.jar"/>
+  <classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.14/log4j-1.2.14.jar" sourcepath="M2_REPO/log4j/log4j/1.2.14/log4j-1.2.14-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/jboss/jboss-test/1.0.3.GA/jboss-test-1.0.3.GA.jar" sourcepath="M2_REPO/jboss/jboss-test/1.0.3.GA/jboss-test-1.0.3.GA-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar" sourcepath="M2_REPO/junit/junit/3.8.1/junit-3.8.1-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/jboss/profiler/jvmti/jboss-profiler-jvmti/1.0.0.CR5/jboss-profiler-jvmti-1.0.0.CR5.jar"/>
+  <classpathentry kind="var" path="M2_REPO/jboss/jboss-logging-spi/2.0.2.GA/jboss-logging-spi-2.0.2.GA.jar" sourcepath="M2_REPO/jboss/jboss-logging-spi/2.0.2.GA/jboss-logging-spi-2.0.2.GA-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/apache-xerces/xml-apis/2.7.1/xml-apis-2.7.1.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/apache/ant/ant-junit/1.7.0/ant-junit-1.7.0.jar"/>
+  <classpathentry kind="var" path="M2_REPO/oswego-concurrent/concurrent/1.3.4/concurrent-1.3.4.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/apache/ant/ant/1.7.0/ant-1.7.0.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/apache/ant/ant-launcher/1.7.0/ant-launcher-1.7.0.jar"/>
+  <classpathentry kind="var" path="M2_REPO/jboss/jboss-common-core/2.0.4.GA/jboss-common-core-2.0.4.GA.jar" sourcepath="M2_REPO/jboss/jboss-common-core/2.0.4.GA/jboss-common-core-2.0.4.GA-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/apache-log4j/log4j/1.2.8/log4j-1.2.8.jar"/>
+  <classpathentry kind="var" path="M2_REPO/apache-httpclient/commons-httpclient/2.0.2/commons-httpclient-2.0.2.jar"/>
+</classpath>

Added: projects/microcontainer/trunk/classloader/.project
===================================================================
--- projects/microcontainer/trunk/classloader/.project	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/.project	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,13 @@
+<projectDescription>
+  <name>jboss-classloader</name>
+  <comment>JBoss Microcontainer ClassLoader</comment>
+  <projects/>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+  </natures>
+</projectDescription>

Added: projects/microcontainer/trunk/classloader/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- projects/microcontainer/trunk/classloader/.settings/org.eclipse.jdt.core.prefs	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/.settings/org.eclipse.jdt.core.prefs	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,5 @@
+#Wed Mar 28 18:15:56 CEST 2007
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5

Added: projects/microcontainer/trunk/classloader/pom.xml
===================================================================
--- projects/microcontainer/trunk/classloader/pom.xml	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/pom.xml	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,35 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>jboss</groupId>
+    <artifactId>jboss-microcontainer</artifactId>
+    <version>2.0.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>jboss-classloader</artifactId>
+  <packaging>jar</packaging>
+  <name>JBoss ClassLoader</name>
+  <url>http://www.jboss.com/products/jbossmc</url>
+  <description>JBoss ClassLoader</description>
+  <dependencies>
+    <!-- Global dependencies -->
+    <dependency>
+	    <groupId>jboss</groupId>
+	    <artifactId>jboss-common-core</artifactId>
+	    <version>2.0.4.GA</version>
+	  </dependency>
+	  <!-- Test dependencies -->
+    <dependency>
+      <groupId>jboss</groupId>
+      <artifactId>jboss-test</artifactId>
+      <version>1.0.3.GA</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+	    <groupId>junit</groupId>
+	    <artifactId>junit</artifactId>
+	    <version>3.8.1</version>
+	    <scope>test</scope>
+    </dependency>
+  </dependencies>  
+</project>

Added: projects/microcontainer/trunk/classloader/src/etc/default.mf
===================================================================
--- projects/microcontainer/trunk/classloader/src/etc/default.mf	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/etc/default.mf	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Created-By: @java.vm.version@ (@java.vm.vendor@)
+Specification-Title: @specification.title@
+Specification-Version: @specification.version@
+Specification-Vendor: @specification.vendor@
+Implementation-Title: @implementation.title@
+Implementation-URL: @implementation.url@
+Implementation-Version: @implementation.version@
+Implementation-Vendor: @implementation.vendor@
+Implementation-Vendor-Id: @implementation.vendor.id@

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/ClassLoaderUtils.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/ClassLoaderUtils.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/ClassLoaderUtils.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,275 @@
+/*
+ * 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.classloader.plugins;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+
+import org.jboss.classloader.spi.base.BaseClassLoader;
+import org.jboss.classloader.spi.base.BaseClassLoaderDomain;
+import org.jboss.util.UnreachableStatementException;
+
+/**
+ * ClassLoaderUtils.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassLoaderUtils
+{
+   /** The hack to the security manager */
+   private static final Hack hack = new Hack();
+   
+   /**
+    * Check the class name makes sense
+    * 
+    * REVIEW other checks besides null and empty?
+    * @param className the class name
+    * @throws ClassNotFoundException for a malformed class name
+    */
+   public static final void checkClassName(final String className) throws ClassNotFoundException
+   {
+      if (className == null)
+         throw new ClassNotFoundException("Null class name");
+      if (className.trim().length() == 0)
+         throw new ClassNotFoundException("Empty class name '" + className + "'");
+   }
+
+   /**
+    * Convert a class name into a path
+    * 
+    * @param className the class name
+    * @return the path
+    */
+   public static final String classNameToPath(final String className)
+   {
+      return className.replace('.', '/') + ".class";
+   }
+
+   /**
+    * Convert a class's package name into a path
+    * 
+    * @param className the class name
+    * @return the path
+    */
+   public static final String packageNameToPath(final String className)
+   {
+      String packageName = getClassPackageName(className);
+      return packageName.replace('.', '/');
+   }
+
+   /**
+    * Get the package name for a class
+    * 
+    * @param className the class name
+    * @return the package name or the empty string if there is no package
+    */
+   public static final String getClassPackageName(final String className)
+   {
+      int end = className.lastIndexOf('.');
+      if (end == -1)
+         return "";
+      return className.substring(0, end);
+   }
+
+   /**
+    * Get the package name for a class
+    * 
+    * @param className the class name
+    * @return the package name or the empty string if there is no package
+    */
+   public static final String getResourcePackageName(final String className)
+   {
+      int i = className.lastIndexOf('/');
+      if (i == -1)
+         return "";
+      return className.substring(0, i).replace('/', '.');
+   }
+
+   /**
+    * Get the resource name in dot notation
+    * 
+    * @param name the resource name
+    * @return the resource name with / replaced by .
+    */
+   public static final String getResourceNameInDotNotation(final String name)
+   {
+      return name.replace('/', '.');
+   }
+   
+   /**
+    * Load bytecode from a stream
+    * 
+    * @param name the class name
+    * @param is the input stream
+    * @return the byte code
+    */
+   public static final byte[] loadByteCode(String name, final InputStream is)
+   {
+      try
+      {
+         ByteArrayOutputStream baos = new ByteArrayOutputStream();
+         byte[] tmp = new byte[1024];
+         int read = 0;
+         while ( (read = is.read(tmp)) >= 0 )
+            baos.write(tmp, 0, read);
+         return baos.toByteArray();
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException("Unable to load class byte code " + name, e);
+      }
+      finally
+      {
+         try
+         {
+            is.close();
+         }
+         catch (IOException e)
+         {
+            // pointless
+         }
+      }
+   }
+   
+   /**
+    * Used to check whether the classloading request is from the jdk<p>
+    * 
+    * This is a hack because of broken behaviour by the JDKs where they assume
+    * they can load their own classes from any classloader.
+    * 
+    * @return true when it is a JDK request
+    */
+   public static boolean isRequestFromJDK()
+   {
+      Class[] context = hack.getClassContext();
+      for (Class clazz : context)
+      {
+         // Review others?
+         if (Hack.class.isAssignableFrom(clazz) == false &&
+             ClassLoaderUtils.class.isAssignableFrom(clazz) == false &&
+             BaseClassLoaderDomain.class.isAssignableFrom(clazz) == false &&
+             BaseClassLoader.class.isAssignableFrom(clazz) == false &&
+             ClassLoader.class.isAssignableFrom(clazz) == false &&
+             Class.class.isAssignableFrom(clazz) == false)
+         {
+            ClassLoader cl = clazz.getClassLoader();
+            // Review: I don't think this true for all JDKs? i.e. JDK classes have no classloader.
+            return (cl == null);
+         }
+      }
+      throw new UnreachableStatementException();
+   }
+   
+   /**
+    * Formats the class as a string
+    * 
+    * @param clazz the class
+    * @return the string
+    */
+   public static final String classToString(final Class<?> clazz)
+   {
+      if (clazz == null)
+         return "null";
+
+      StringBuilder builder = new StringBuilder();
+      classToString(clazz, builder);
+      return builder.toString();
+   }
+   
+   /**
+    * Formats a class into a string builder
+    * 
+    * @param clazz the class
+    * @param builder the builder
+    */
+   public static final void classToString(final Class<?> clazz, StringBuilder builder)
+   {
+      if (clazz == null)
+      {
+         builder.append("null");
+         return;
+      }
+
+      builder.append(clazz);
+      builder.append('{');
+      ClassLoader cl = clazz.getClassLoader();
+      builder.append("cl=").append(cl);
+      builder.append(" codeSource=");
+      builder.append(getCodeSource(clazz));
+      builder.append("}");
+   }
+   
+   /**
+    * Get the protected domain for a class
+    * 
+    * @param clazz the class
+    * @return the protected domain or null if it doesn't have one
+    */
+   private static final ProtectionDomain getProtectionDomain(final Class<?> clazz)
+   {
+      SecurityManager sm = System.getSecurityManager();
+      if (sm == null)
+         return clazz.getProtectionDomain();
+      
+      return AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>()
+      {
+         public ProtectionDomain run()
+         {
+            return clazz.getProtectionDomain();
+         }
+      });
+   }
+   
+   /**
+    * Get the code source for a class
+    * 
+    * @param clazz the class
+    * @return the code source or null if it doesn't have one
+    */
+   private static final CodeSource getCodeSource(final Class<?> clazz)
+   {
+      ProtectionDomain protectionDomain = getProtectionDomain(clazz);
+      if (protectionDomain == null)
+         return null;
+      return protectionDomain.getCodeSource();
+   }
+   
+   /**
+    * Extend the security manager so we can get access to the stacktrace
+    * 
+    * TODO move this hack somewhere else?
+    */
+   private static class Hack extends SecurityManager
+   {
+      @Override
+      public Class[] getClassContext()
+      {
+         return super.getClassContext();
+      }
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/EverythingClassFilter.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/EverythingClassFilter.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/EverythingClassFilter.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,55 @@
+/*
+ * 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.classloader.plugins.filter;
+
+import org.jboss.classloader.spi.filter.ClassFilter;
+
+/**
+ * A class filter that matches everything
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class EverythingClassFilter implements ClassFilter
+{
+   /** The singleton instance */
+   public static final EverythingClassFilter INSTANCE = new EverythingClassFilter();
+   
+   /**
+    * Create a new EverythingClassFilter.
+    */
+   private EverythingClassFilter()
+   {
+      // Singleton
+   }
+   
+   public boolean matches(String className)
+   {
+      return true;
+   }
+   
+   @Override
+   public String toString()
+   {
+      return "<EVERYTHING>";
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/JavaOnlyClassFilter.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/JavaOnlyClassFilter.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/JavaOnlyClassFilter.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,47 @@
+/*
+ * 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.classloader.plugins.filter;
+
+/**
+ * A class filter that only delegates standard java classes
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class JavaOnlyClassFilter extends PatternClassFilter
+{
+   /** The singleton instance */ 
+   public static final JavaOnlyClassFilter INSTANCE = new JavaOnlyClassFilter();
+   
+   /**
+    * Create a new JavaOnlyClassFilter.
+    */
+   private JavaOnlyClassFilter()
+   {
+      super(new String[] { "java\\..*", "javax\\..*" } );
+   }
+
+   public String toString()
+   {
+      return "JAVA_ONLY";
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/NothingClassFilter.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/NothingClassFilter.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/NothingClassFilter.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,55 @@
+/*
+ * 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.classloader.plugins.filter;
+
+import org.jboss.classloader.spi.filter.ClassFilter;
+
+/**
+ * A class filter that matches nothing
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class NothingClassFilter implements ClassFilter
+{
+   /** The singleton instance */
+   public static final NothingClassFilter INSTANCE = new NothingClassFilter();
+   
+   /**
+    * Create a new NothingClassFilter.
+    */
+   private NothingClassFilter()
+   {
+      // Singleton
+   }
+   
+   public boolean matches(String className)
+   {
+      return false;
+   }
+   
+   @Override
+   public String toString()
+   {
+      return "<NOTHING>";
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/PackageClassFilter.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/PackageClassFilter.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/PackageClassFilter.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,81 @@
+/*
+ * 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.classloader.plugins.filter;
+
+import java.util.Arrays;
+
+/**
+ * A class filter using regular expressions
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class PackageClassFilter extends PatternClassFilter
+{
+   /** The patterns as regular expressions */
+   private String[] packageNames;
+   
+   /**
+    * Convert package names to patterns
+    * 
+    * @param packageNames the package names
+    * @return the patterns
+    */
+   private static String[] convertPackageNamesToPatterns(String[] packageNames)
+   {
+      if (packageNames == null)
+         throw new IllegalArgumentException("Null package names");
+      
+      String[] patterns = new String[packageNames.length];
+      for (int i = 0; i < packageNames.length; ++i)
+      {
+         if (packageNames[i] == null)
+            throw new IllegalArgumentException("Null package name in " + Arrays.asList(packageNames));
+
+         if (packageNames[i].length() == 0)
+            // Base package - it is a match if there is no . in the class name
+            patterns[i] = "[^.]*";
+         else
+            // Escape the dots in the package and match anything that has a single dot followed by non-dots
+            patterns[i] = packageNames[i].replace(".", "\\.") + "\\.[^.]*";
+      }
+      return patterns;
+   }
+   
+   /**
+    * Create a new PackageClassFilter.
+    * 
+    * @param packageNames the packageNames
+    * @throws IllegalArgumentException for null packageNames
+    */
+   public PackageClassFilter(String[] packageNames)
+   {
+      super(convertPackageNamesToPatterns(packageNames));
+      this.packageNames = packageNames;
+   }
+
+   @Override
+   public String toString()
+   {
+      return Arrays.asList(packageNames).toString();
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/PatternClassFilter.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/PatternClassFilter.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/filter/PatternClassFilter.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,90 @@
+/*
+ * 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.classloader.plugins.filter;
+
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.jboss.classloader.spi.filter.ClassFilter;
+
+/**
+ * A class filter using regular expressions
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class PatternClassFilter implements ClassFilter
+{
+   /** The patterns as regular expressions */
+   private Pattern[] patterns;
+   
+   /**
+    * Create a new PatternClassFilter.
+    * 
+    * @param pattern the pattern
+    */
+   public PatternClassFilter(String pattern)
+   {
+      if (pattern == null)
+         throw new IllegalArgumentException("Null pattern");
+      patterns = new Pattern[1];
+      patterns[0] = Pattern.compile(pattern);
+   }
+   
+   /**
+    * Create a new PatternClassFilter.
+    * 
+    * @param patterns the patterns
+    * @throws IllegalArgumentException for a null pattern
+    */
+   public PatternClassFilter(String[] patterns)
+   {
+      if (patterns == null)
+         throw new IllegalArgumentException("Null patterns");
+      
+      this.patterns = new Pattern[patterns.length];
+      for (int i = 0; i < patterns.length; ++i)
+      {
+         if (patterns[i] == null)
+            throw new IllegalArgumentException("Null pattern in " + Arrays.asList(patterns));
+         this.patterns[i] = Pattern.compile(patterns[i]);
+      }
+   }
+
+   public boolean matches(String className)
+   {
+      for (int i = 0; i < patterns.length; ++i)
+      {
+         Matcher matcher = patterns[i].matcher(className);
+         if (matcher.matches())
+            return true;
+      }
+      return false;
+   }
+
+   @Override
+   public String toString()
+   {
+      return Arrays.asList(patterns).toString();
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/loader/ClassLoaderToLoaderAdapter.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/loader/ClassLoaderToLoaderAdapter.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/loader/ClassLoaderToLoaderAdapter.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,83 @@
+/*
+ * 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.classloader.plugins.loader;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Set;
+
+import org.jboss.classloader.spi.Loader;
+
+/**
+ * ClassLoaderToLoaderAdapter.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassLoaderToLoaderAdapter implements Loader
+{
+   /** The classloader */
+   private ClassLoader classLoader;
+
+   /**
+    * Create a new ClassLoaderToLoaderAdapter.
+    * 
+    * @param classLoader the classloader
+    */
+   public ClassLoaderToLoaderAdapter(ClassLoader classLoader)
+   {
+      if (classLoader == null)
+         throw new IllegalArgumentException("Null classLoader");
+      this.classLoader = classLoader;
+   }
+
+   public URL getResource(String name, String resourceName)
+   {
+      return classLoader.getResource(name);
+   }
+
+   public void getResources(String name, String resourceName, Set<URL> urls) throws IOException
+   {
+      Enumeration<URL> enumeration = classLoader.getResources(name);
+      while (enumeration.hasMoreElements())
+         urls.add(enumeration.nextElement());
+   }
+
+   public Class<?> loadClass(String className)
+   {
+      try
+      {
+         return classLoader.loadClass(className);
+      }
+      catch (ClassNotFoundException e)
+      {
+         return null;
+      }
+   }
+
+   @Override
+   public String toString()
+   {
+      return classLoader.toString();
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/system/ClassLoaderSystemBuilder.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/system/ClassLoaderSystemBuilder.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/system/ClassLoaderSystemBuilder.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,47 @@
+/*
+ * 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.classloader.plugins.system;
+
+import org.jboss.classloader.spi.ClassLoaderSystem;
+
+/**
+ * ClassLoaderSystemBuilder.
+ * 
+ * TODO parameterize this
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassLoaderSystemBuilder
+{
+   /** The singleton */
+   private static final ClassLoaderSystem singleton = new DefaultClassLoaderSystem();
+   
+   /**
+    * Get the classloader system singleton
+    * 
+    * @return the singleton
+    */
+   public static ClassLoaderSystem get()
+   {
+      return singleton;
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/system/DefaultClassLoaderSystem.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/system/DefaultClassLoaderSystem.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/plugins/system/DefaultClassLoaderSystem.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,40 @@
+/*
+ * 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.classloader.plugins.system;
+
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderSystem;
+
+/**
+ * DefaultClassLoaderSystem.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class DefaultClassLoaderSystem extends ClassLoaderSystem
+{
+   @Override
+   protected ClassLoaderDomain createDomain(String name)
+   {
+      return new ClassLoaderDomain(name);
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomain.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomain.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderDomain.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,356 @@
+/*
+ * 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.classloader.spi;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Set;
+
+import org.jboss.classloader.plugins.loader.ClassLoaderToLoaderAdapter;
+import org.jboss.classloader.spi.base.BaseClassLoaderDomain;
+import org.jboss.classloader.spi.filter.ClassFilter;
+import org.jboss.logging.Logger;
+
+/**
+ * ClassLoaderDomain.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassLoaderDomain extends BaseClassLoaderDomain implements Loader
+{
+   /** The log */
+   private static final Logger log = Logger.getLogger(ClassLoaderDomain.class);
+   
+   /** The name of the domain */
+   private String name;
+
+   /** The parent classloading rules */
+   private ParentPolicy parentPolicy = ParentPolicy.BEFORE; 
+   
+   /** The parent */
+   private Loader parent;
+   
+   /**
+    * Create a new ClassLoaderDomain with the {@link ParentPolicy#BEFORE} loading rules.
+    * 
+    * @param name the name of the domain
+    * @throws IllegalArgumentException for a null name
+    */
+   public ClassLoaderDomain(String name)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      this.name = name;
+      fixUpParent();
+   }
+   
+   /**
+    * Get the name.
+    * 
+    * @return the name.
+    */
+   public String getName()
+   {
+      return name;
+   }
+   
+   /**
+    * Get the parent policy
+    * 
+    * @return the parent policy.
+    */
+   public ParentPolicy getParentPolicy()
+   {
+      return parentPolicy;
+   }
+   
+   /**
+    * Set the parentPolicy.
+    * 
+    * @param parentPolicy the parentPolicy.
+    * @throws IllegalArgumentException for a null parent policy
+    */
+   public void setParentPolicy(ParentPolicy parentPolicy)
+   {
+      if (parentPolicy == null)
+         throw new IllegalArgumentException("Null parent policy");
+      this.parentPolicy = parentPolicy;
+   }
+
+   /**
+    * Get the parent
+    * 
+    * @return the parent.
+    */
+   public Loader getParent()
+   {
+      return parent;
+   }
+
+   /**
+    * Set the parent.
+    * 
+    * @param parent the parent.
+    */
+   public void setParent(Loader parent)
+   {
+      this.parent = parent;
+      fixUpParent();
+   }
+   
+   /**
+    * For subclasses to add information for toLongString()
+    * 
+    * @param builder the builder
+    */
+   protected void toLongString(StringBuilder builder)
+   {
+      builder.append("name=").append(getName());
+      builder.append(" parentPolicy=").append(getParentPolicy());
+      builder.append(" parent=");
+      Loader parent = getParent();
+      if (parent != null)
+         builder.append(parent);
+      else
+         builder.append(getParentClassLoader());
+   }
+
+   @Override
+   public String toString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append(getClass().getSimpleName());
+      builder.append("@").append(Integer.toHexString(System.identityHashCode(this)));
+      builder.append("{").append(name).append('}');
+      return builder.toString();
+   }
+   
+   @Override
+   protected Loader findBeforeLoader(String name, String resourceName)
+   {
+      boolean trace = log.isTraceEnabled();
+      ClassFilter filter = getParentPolicy().getBeforeFilter();
+      if (filter.matches(resourceName))
+      {
+         if (trace)
+            log.trace(this + " " + name + " matches parent beforeFilter=" + filter);
+         return findLoaderFromParent(name, resourceName);
+      }
+      if (trace)
+         log.trace(this + " " + name + " does NOT match parent beforeFilter=" + filter);
+      return null;
+   }
+
+   @Override
+   protected Loader findAfterLoader(String name, String resourceName)
+   {
+      boolean trace = log.isTraceEnabled();
+      ClassFilter filter = getParentPolicy().getAfterFilter();
+      if (filter.matches(resourceName))
+      {
+         if (trace)
+            log.trace(this + " " + name + " matches parent afterFilter=" + filter);
+         return findLoaderFromParent(name, resourceName);
+      }
+      if (trace)
+         log.trace(this + " " + name + " does NOT match parent afterFilter=" + filter);
+      return null;
+   }
+
+   /**
+    * Try to find a loader from the parent
+    * 
+    * @param name the name
+    * @param resourceName the name in dot notation
+    * @return the loader if found
+    */
+   protected Loader findLoaderFromParent(String name, String resourceName)
+   {
+      Loader parentLoader = getParent();
+
+      boolean trace = log.isTraceEnabled();
+      if (parentLoader == null)
+      {
+         if (trace)
+            log.trace(this + " not loading from non-existant parent");
+         return null;
+      }
+
+      if (trace)
+         log.trace(this + " load from parent " + name + " parent=" + parent);
+      
+      if (parentLoader.getResource(name, resourceName) != null)
+         return parentLoader;
+      
+      return null;
+   }
+   
+   @Override
+   protected URL beforeGetResource(String name, String resourceName)
+   {
+      boolean trace = log.isTraceEnabled();
+      ClassFilter filter = getParentPolicy().getBeforeFilter();
+      if (filter.matches(resourceName))
+      {
+         if (trace)
+            log.trace(this + " " + name + " matches parent beforeFilter=" + filter);
+         return getResourceFromParent(name, resourceName);
+      }
+      if (trace)
+         log.trace(this + " " + name + " does NOT match parent beforeFilter=" + filter);
+      return null;
+   }
+
+   @Override
+   protected URL afterGetResource(String name, String resourceName)
+   {
+      boolean trace = log.isTraceEnabled();
+      ClassFilter filter = getParentPolicy().getAfterFilter();
+      if (filter.matches(resourceName))
+      {
+         if (trace)
+            log.trace(this + " " + name + " matches parent afterFilter=" + filter);
+         return getResourceFromParent(name, resourceName);
+      }
+      if (trace)
+         log.trace(this + " " + name + " does NOT match parent afterFilter=" + filter);
+      return null;
+   }
+
+   /**
+    * Try to get a resource from the parent
+    * 
+    * @param name the name
+    * @param resourceName the name of the resource in dot notation
+    * @return the url if found
+    */
+   protected URL getResourceFromParent(String name, String resourceName)
+   {
+      Loader parentLoader = getParent();
+
+      boolean trace = log.isTraceEnabled();
+      if (parentLoader == null)
+      {
+         if (trace)
+            log.trace(this + " not getting resource from non-existant parent");
+         return null;
+      }
+
+      if (trace)
+         log.trace(this + " get resource from parent " + name + " parent=" + parentLoader);
+      
+      URL result = null;
+      if (parentLoader != null)
+         result = parentLoader.getResource(name, resourceName);
+
+      if (trace)
+      {
+         if (result != null)
+            log.trace(this + " got resource from parent " + name + " parent=" + parentLoader + " " + result);
+         else
+            log.trace(this + " resource not found in parent " + name + " parent=" + parentLoader);
+      }
+      
+      return result;
+   }
+   
+   @Override
+   protected void beforeGetResources(String name, String resourceName, Set<URL> urls) throws IOException
+   {
+      boolean trace = log.isTraceEnabled();
+      ClassFilter filter = getParentPolicy().getBeforeFilter();
+      if (filter.matches(resourceName))
+      {
+         if (trace)
+            log.trace(this + " " + name + " matches parent beforeFilter=" + filter);
+         getResourcesFromParent(name, resourceName, urls);
+      }
+      else if (trace)
+         log.trace(this + " " + name + " does NOT match parent beforeFilter=" + filter);
+   }
+
+   @Override
+   protected void afterGetResources(String name, String resourceName, Set<URL> urls) throws IOException
+   {
+      boolean trace = log.isTraceEnabled();
+      ClassFilter filter = getParentPolicy().getAfterFilter();
+      if (filter.matches(resourceName))
+      {
+         if (trace)
+            log.trace(this + " " + name + " matches parent afterFilter=" + filter);
+         getResourcesFromParent(name, resourceName, urls);
+      }
+      else if (trace)
+         log.trace(this + " " + name + " does NOT match parent afterFilter=" + filter);
+   }
+
+   /**
+    * Try to get resources from the parent
+    * 
+    * @param name the name
+    * @param urls the urls to add to
+    * @param resourceName the name of the resource in dot notation
+    * @throws IOException for any error
+    */
+   protected void getResourcesFromParent(String name, String resourceName, Set<URL> urls) throws IOException
+   {
+      Loader parentLoader = getParent();
+
+      boolean trace = log.isTraceEnabled();
+      if (parentLoader == null)
+      {
+         if (trace)
+            log.trace(this + " not getting resources from non-existant parent");
+         return;
+      }
+
+      if (trace)
+         log.trace(this + " get resources from parent " + name + " parent=" + parentLoader);
+      
+      if (parentLoader != null)
+         parentLoader.getResources(name, resourceName, urls);
+   }
+
+   /**
+    * Get the parent classloader
+    * 
+    * @return the parent classloader
+    */
+   protected ClassLoader getParentClassLoader()
+   {
+      return getClass().getClassLoader();
+   }
+
+   /**
+    * Fixup the parent to the our classloader as parent if we don't have an explicit one
+    */
+   private void fixUpParent()
+   {
+      if (parent == null)
+      {
+         ClassLoader classLoader = getParentClassLoader();
+         if (classLoader != null)
+            parent = new ClassLoaderToLoaderAdapter(classLoader);
+      }
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderPolicy.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderPolicy.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderPolicy.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,192 @@
+/*
+ * 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.classloader.spi;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.classloader.plugins.filter.PackageClassFilter;
+import org.jboss.classloader.spi.base.BaseClassLoaderPolicy;
+import org.jboss.classloader.spi.filter.FilteredDelegateLoader;
+import org.jboss.logging.Logger;
+
+/**
+ * ClassLoader policy.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class ClassLoaderPolicy extends BaseClassLoaderPolicy
+{
+   /** The log */
+   private static final Logger log = Logger.getLogger(ClassLoaderPolicy.class);
+
+   /**
+    * Get the delegate loader for exported stuff<p>
+    *
+    * By default this uses {@link #getPackageNames()} to create a {@link FilteredDelegateLoader}
+    * 
+    * NOTE: Protected access for security reasons
+    * 
+    * @return the delegate loader
+    */
+   protected DelegateLoader getExported()
+   {
+      String[] packageNames = getPackageNames();
+      if (packageNames == null)
+         return null;
+      return new FilteredDelegateLoader(this, new PackageClassFilter(packageNames));
+   }
+
+   /**
+    * Get the exported packages<p>
+    *
+    * Provides a hint for indexing<p>
+    * 
+    * No packages are exported by default<p>
+    * 
+    * The returned package names can be null to indicate
+    * nothing is exported, but if an array is returned
+    * it should not include a null package element.
+    * 
+    * @return the package names
+    */
+   public String[] getPackageNames()
+   {
+      return null;
+   }
+   
+   /**
+    * Get the delegate loaders for imported stuff<p>
+    * 
+    * There are no imports by default<p>
+    * 
+    * NOTE: Protected access for security reasons
+    * 
+    * @return the delegate loaders
+    */
+   protected List<? extends DelegateLoader> getDelegates()
+   {
+      return Collections.emptyList();
+   }
+
+   /**
+    * Whether to import all exports from other classloaders in the domain<p>
+    *
+    * False by default
+    * 
+    * @return true to import all
+    */
+   protected boolean isImportAll()
+   {
+      return false;
+   }
+
+   /**
+    * Get the resource
+    * 
+    * @param path the path
+    * @return the url or null if not found
+    */
+   public abstract URL getResource(String path);
+
+   /**
+    * Get the resource as a stream<p>
+    * 
+    * Uses {@link #getResource(String)} by default
+    * 
+    * @param path the path
+    * @return the stream or null if not found
+    */
+   public InputStream getResourceAsStream(String path)
+   {
+      URL url = getResource(path);
+      if (url != null)
+      {
+         try
+         {
+            return url.openStream();
+         }
+         catch (IOException e)
+         {
+            log.debug("Unable to open URL: " + url + " for path " + path + " from " + toLongString());
+         }
+      }
+      return null;
+   }
+
+   /**
+    * Get resources
+    * 
+    * @param name the resource name
+    * @param urls the list of urls to add to
+    * @throws IOException for any error
+    */
+   public abstract void getResources(String name ,Set<URL> urls) throws IOException;
+   
+   /**
+    * Get the protection domain<p>
+    * 
+    * By default there is no protection domain<p>
+    * 
+    * NOTE: Protected access for security reasons
+    * 
+    * @param className the class name
+    * @param path the path
+    * @return the protection domain
+    */
+   protected ProtectionDomain getProtectionDomain(String className, String path)
+   {
+      return null;
+   }
+   
+   /**
+    * Get the package information<p>
+    * 
+    * There is no package information by default
+    * 
+    * @param packageName the package information
+    * @return the information or null if there is none
+    */
+   public PackageInformation getPackageInformation(String packageName)
+   {
+      return null;
+   }
+
+   @Override
+   protected void toLongString(StringBuilder builder)
+   {
+      builder.append(" delegates=").append(getDelegates());
+      String[] packageNames = getPackageNames();
+      if (packageNames != null)
+         builder.append(" exported=").append(Arrays.asList(packageNames));
+      boolean importAll = isImportAll();
+      if (importAll)
+         builder.append(" <IMPORT-ALL>");
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderSystem.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderSystem.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ClassLoaderSystem.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,339 @@
+/*
+ * 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.classloader.spi;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.classloader.plugins.system.ClassLoaderSystemBuilder;
+import org.jboss.classloader.spi.base.BaseClassLoaderSystem;
+import org.jboss.logging.Logger;
+
+/**
+ * ClassLoaderSystem.
+ * 
+ * TODO Permissions
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class ClassLoaderSystem extends BaseClassLoaderSystem
+{
+   /** The log */
+   private static final Logger log = Logger.getLogger(ClassLoaderSystem.class);
+
+   /** The name of the default domain */
+   public static final String DEFAULT_DOMAIN_NAME = "<DEFAULT>";
+
+   /** The class loading system builder */
+   private static final ClassLoaderSystemBuilder builder = new ClassLoaderSystemBuilder();
+
+   /** The default domain */
+   private ClassLoaderDomain defaultDomain;
+   
+   /** The registered domains by name */
+   private Map<String, ClassLoaderDomain> registeredDomains = new HashMap<String, ClassLoaderDomain>();
+   
+   /**
+    * Get the classloading system instance
+    * 
+    * @return the instance
+    */
+   public static final ClassLoaderSystem getInstance()
+   {
+      return builder.get();
+   }
+
+   /**
+    * Get the default classloading domain
+    * 
+    * @return the default domain
+    */
+   public synchronized ClassLoaderDomain getDefaultDomain()
+   {
+      // Already constructed
+      if (defaultDomain != null)
+         return defaultDomain;
+      
+      // See if explicitly registered
+      defaultDomain = registeredDomains.get(DEFAULT_DOMAIN_NAME);
+      if (defaultDomain != null)
+         return defaultDomain;
+      
+      // Create it
+      defaultDomain = createDefaultDomain();
+      
+      // Register it
+      internalRegisterDomain(DEFAULT_DOMAIN_NAME, defaultDomain);
+      
+      return defaultDomain;
+   }
+   
+   /**
+    * Create the default domain<p>
+    * 
+    * By default this just invokes {@link #createDomain(String)} with {@link #DEFAULT_DOMAIN_NAME}
+    * 
+    * @return the default domain
+    */
+   protected ClassLoaderDomain createDefaultDomain()
+   {
+      return createDomain(DEFAULT_DOMAIN_NAME);
+   }
+   
+   /**
+    * Create a domain
+    * 
+    * @param name the name of the domain
+    * @return the domain
+    * @throws IllegalArgumentException for a null name
+    */
+   protected abstract ClassLoaderDomain createDomain(String name);
+   
+   /**
+    * Create and register a domain
+    * 
+    * @param name the name of the domain
+    * @return the domain
+    * @throws IllegalArgumentException for a null name
+    * @throws IllegalStateException if there already is a domain with that name
+    */
+   public ClassLoaderDomain createAndRegisterDomain(String name)
+   {
+      return createAndRegisterDomain(name, ParentPolicy.BEFORE, null);
+   }
+   
+   /**
+    * Create and register a domain with the given parent classloading policy
+    * 
+    * @param name the name of the domain
+    * @param parentPolicy the parent classloading policy
+    * @return the domain
+    * @throws IllegalArgumentException for a null name or policy
+    * @throws IllegalStateException if there already is a domain with that name
+    */
+   public ClassLoaderDomain createAndRegisterDomain(String name, ParentPolicy parentPolicy)
+   {
+      return createAndRegisterDomain(name, parentPolicy, null);
+   }
+   
+   /**
+    * Create and register a domain with the given parent classloading policy
+    * 
+    * @param name the name of the domain
+    * @param parentPolicy the parent classloading policy
+    * @param parent the parent
+    * @return the domain
+    * @throws IllegalArgumentException for a null argument
+    * @throws IllegalStateException if there already is a domain with that name
+    */
+   public ClassLoaderDomain createAndRegisterDomain(String name, ParentPolicy parentPolicy, Loader parent)
+   {
+      ClassLoaderDomain result = createDomain(name);
+      result.setParentPolicy(parentPolicy);
+      result.setParent(parent);
+      registerDomain(result);
+      return result;
+   }
+
+   /**
+    * Get a domain
+    * 
+    * @param name the domain name
+    * @return the domain
+    * @throws IllegalArgumentException for a null name
+    */
+   public synchronized ClassLoaderDomain getDomain(String name)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      ClassLoaderDomain result = registeredDomains.get(name);
+      
+      // See whether this is the default domain
+      if (result == null && DEFAULT_DOMAIN_NAME.equals(name))
+         result = getDefaultDomain();
+      
+      return result;
+   }
+
+   /**
+    * Is a domain name registered
+    * 
+    * @param name the domain name
+    * @return true when the domain is registered
+    * @throws IllegalArgumentException for a null name
+    */
+   public boolean isRegistered(String name)
+   {
+      return getDomain(name) != null;
+   }
+
+   /**
+    * Is a domain registered
+    * 
+    * @param domain the domain
+    * @return true when the domain is registered
+    * @throws IllegalArgumentException for a null domain
+    */
+   public boolean isDomainRegistered(ClassLoaderDomain domain)
+   {
+      if (domain == null)
+         throw new IllegalArgumentException("Null domain");
+      return getDomain(domain.getName()) == domain;
+   }
+
+   /**
+    * Register a domain
+    * 
+    * @param domain the domain
+    * @throws IllegalArgumentException for a null domain
+    * @throws IllegalStateException if a domain is already registered with this name
+    */
+   public synchronized void registerDomain(ClassLoaderDomain domain)
+   {
+      if (domain == null)
+         throw new IllegalArgumentException("Null domain");
+      
+      String name = domain.getName();
+      if (isRegistered(name))
+         throw new IllegalStateException("A domain is already registered with " + name);
+      
+      internalRegisterDomain(name, domain);
+   }
+
+   private void internalRegisterDomain(String name, ClassLoaderDomain domain)
+   {
+      
+      registeredDomains.put(name, domain);
+      
+      log.debug(this + " registered domain=" + domain.toLongString());
+   }
+   
+   /**
+    * Unregister a domain
+    * 
+    * @param domain the domain
+    * @throws IllegalArgumentException for a null domain
+    * @throws IllegalStateException if a domain is not registered
+    */
+   public synchronized void unregisterDomain(ClassLoaderDomain domain)
+   {
+      
+      if (isDomainRegistered(domain) == false)
+         throw new IllegalStateException("Domain is not registered " + domain);
+      
+      registeredDomains.remove(domain.getName());
+      
+      log.debug(this + " unregistered domain=" + domain.toLongString());
+   }
+   
+   /**
+    * Register a policy with the default domain<p>
+    * 
+    * Equivalent to {@link #registerClassLoaderPolicy(ClassLoaderDomain, ClassLoaderPolicy)} using
+    * {@link #getDefaultDomain()} as the ClassLoaderDomain
+    * 
+    * @param policy the policy
+    * @return the classloader
+    * @throws IllegalArgumentException if a parameter is null
+    * @throws IllegalStateException if the policy is already registered with a domain  
+    */
+   public ClassLoader registerClassLoaderPolicy(ClassLoaderPolicy policy)
+   {
+      return registerClassLoaderPolicy(getDefaultDomain(), policy);
+   }
+   
+   /**
+    * Unregister a policy with the default domain<p>
+    * 
+    * Equivalent to {@link #unregisterClassLoaderPolicy(ClassLoaderDomain, ClassLoaderPolicy)} using
+    * {@link #getDefaultDomain()} as the ClassLoaderDomain
+    * 
+    * @param policy the policy
+    * @throws IllegalArgumentException if a parameter is null
+    * @throws IllegalStateException if the policy is not registered with the default domain  
+    */
+   public void unregisterClassLoaderPolicy(ClassLoaderPolicy policy)
+   {
+      unregisterClassLoaderPolicy(getDefaultDomain(), policy);
+   }
+   
+   /**
+    * Unregister a classloader with the default domain<p>
+    * 
+    * Equivalent to {@link #unregisterClassLoader(ClassLoaderDomain, ClassLoader)} using
+    * {@link #getDefaultDomain()} as the ClassLoaderDomain
+    * 
+    * @param classLoader classLoader
+    * @throws IllegalArgumentException if a parameter is null
+    * @throws IllegalStateException if the policy is not registered with the default domain  
+    */
+   public void unregisterClassLoader(ClassLoader classLoader)
+   {
+      unregisterClassLoader(getDefaultDomain(), classLoader);
+   }
+   
+   /**
+    * Register a policy with a domain
+    * 
+    * @param domain the domain
+    * @param policy the policy
+    * @return the classloader
+    * @throws IllegalArgumentException if a parameter is null
+    * @throws IllegalStateException if the domain is not registered or if the policy is already registered with a domain  
+    */
+   public ClassLoader registerClassLoaderPolicy(ClassLoaderDomain domain, ClassLoaderPolicy policy)
+   {
+      if (isDomainRegistered(domain) == false)
+         throw new IllegalArgumentException("Domain is not registered: " + domain);
+      return super.registerClassLoaderPolicy(domain, policy);
+   }
+   
+   /**
+    * Unregister a policy with a domain
+    * 
+    * @param domain the domain
+    * @param policy the policy
+    * @throws IllegalArgumentException if a parameter is null
+    * @throws IllegalStateException if the domain is not registered or if the policy is not registered with the domain  
+    */
+   public void unregisterClassLoaderPolicy(ClassLoaderDomain domain, ClassLoaderPolicy policy)
+   {
+      if (isDomainRegistered(domain) == false)
+         throw new IllegalArgumentException("Domain is not registered: " + domain);
+      super.unregisterClassLoaderPolicy(domain, policy);
+   }
+   
+   /**
+    * Unregister a policy with a domain
+    * 
+    * @param domain the domain
+    * @param classLoader the class loader
+    * @throws IllegalArgumentException if a parameter is null
+    * @throws IllegalStateException if the policy is not registered with the domain  
+    */
+   public void unregisterClassLoader(ClassLoaderDomain domain, ClassLoader classLoader)
+   {
+      if (isDomainRegistered(domain) == false)
+         throw new IllegalArgumentException("Domain is not registered: " + domain);
+      super.unregisterClassLoader(domain, classLoader);
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/DelegateLoader.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/DelegateLoader.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/DelegateLoader.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,44 @@
+/*
+ * 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.classloader.spi;
+
+import org.jboss.classloader.spi.base.BaseDelegateLoader;
+
+/**
+ * DelegateLoader.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class DelegateLoader extends BaseDelegateLoader implements Loader
+{
+   /**
+    * Create a new DelegateLoader.
+    * 
+    * @param delegate the delegate
+    * @throws IllegalArgumentException for a null delegate
+    */
+   public DelegateLoader(ClassLoaderPolicy delegate)
+   {
+      super(delegate);
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/Loader.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/Loader.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/Loader.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,62 @@
+/*
+ * 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.classloader.spi;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Set;
+
+/**
+ * Loader.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface Loader
+{
+   /**
+    * Load a class
+    * 
+    * @param className the class name
+    * @return the class or null if not found
+    */
+   Class<?> loadClass(String className);
+
+   /**
+    * Get a resource
+    * 
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @return the url or null if not found
+    */
+   URL getResource(String name, String resourceName);
+
+   /**
+    * Get resources
+    * 
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @param urls the list of urls to add to
+    * @throws IOException for any error
+    */
+   void getResources(String name, String resourceName, Set<URL> urls) throws IOException;
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/PackageInformation.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/PackageInformation.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/PackageInformation.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,136 @@
+/*
+ * 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.classloader.spi;
+
+import java.net.URL;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.util.jar.Attributes.Name;
+
+/**
+ * PackageInformation.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class PackageInformation
+{
+   /** The package name */
+   public String packageName;
+
+   /** The specification title */
+   public String specTitle;
+   
+   /** The specification version */
+   public String specVersion; 
+   
+   /** The specification vendor */
+   public String specVendor;
+   
+   /** The implementation title */
+   public String implTitle;
+   
+   /** The implementation version */
+   public String implVersion;
+   
+   /** The implementation vendor */
+   public String implVendor;
+   
+   /** The seal base url */
+   public URL sealBase;
+   
+   /**
+    * Create a new PackageInformation.
+    * 
+    * @param packageName the package name
+    * @throws IllegalArgumentException for a null parameter
+    */
+   public PackageInformation(String packageName)
+   {
+      this(packageName, null, null);
+   }
+   
+   /**
+    * Create a new PackageInformation from a manifest
+    * 
+    * @param packageName the package name
+    * @param manifest the manifest
+    * @throws IllegalArgumentException for a null package name
+    */
+   public PackageInformation(String packageName, Manifest manifest)
+   {
+      this(packageName, manifest, null);
+   }
+   
+   /**
+    * Create a new PackageInformation from a manifest
+    * 
+    * @param packageName the package name
+    * @param manifest the manifest
+    * @param seal the url to seal
+    * @throws IllegalArgumentException for a null package name
+    */
+   public PackageInformation(String packageName, Manifest manifest, URL seal)
+   {
+      if (packageName == null)
+         throw new IllegalArgumentException("Null package name");
+
+      if (manifest != null)
+      {
+         String path = packageName.replace('.', '/').concat("/");
+         String sealed = null;
+         Attributes attributes = manifest.getAttributes(path);
+         if (attributes != null)
+         {
+            specTitle = attributes.getValue(Name.SPECIFICATION_TITLE);
+            specVersion = attributes.getValue(Name.SPECIFICATION_VERSION);
+            specVendor = attributes.getValue(Name.SPECIFICATION_VENDOR);
+            implTitle = attributes.getValue(Name.IMPLEMENTATION_TITLE);
+            implVersion = attributes.getValue(Name.IMPLEMENTATION_VERSION);
+            implVendor = attributes.getValue(Name.IMPLEMENTATION_VENDOR);
+            
+            sealed = attributes.getValue(Name.SEALED);
+         }
+         attributes = manifest.getMainAttributes();
+         if (attributes != null)
+         {
+            if (specTitle == null)
+            {
+               specTitle = attributes.getValue(Name.SPECIFICATION_TITLE);
+               specVersion = attributes.getValue(Name.SPECIFICATION_VERSION);
+               specVendor = attributes.getValue(Name.SPECIFICATION_VENDOR);
+            }
+            if (implTitle == null)
+            {
+               implTitle = attributes.getValue(Name.IMPLEMENTATION_TITLE);
+               implVersion = attributes.getValue(Name.IMPLEMENTATION_VERSION);
+               implVendor = attributes.getValue(Name.IMPLEMENTATION_VENDOR);
+            }
+            
+            if (sealed == null)
+               sealed = attributes.getValue(Name.SEALED);
+         }
+         if (seal != null && "true".equalsIgnoreCase(sealed))
+            sealBase = seal;
+      }
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ParentPolicy.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ParentPolicy.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/ParentPolicy.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,114 @@
+/*
+ * 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.classloader.spi;
+
+import org.jboss.classloader.spi.filter.ClassFilter;
+
+/**
+ * ParentPolicy
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ParentPolicy
+{
+   /** Standard Java Delegation */
+   public static final ParentPolicy BEFORE = new ParentPolicy(ClassFilter.EVERYTHING, ClassFilter.NOTHING, "BEFORE");
+
+   /** Servlet style */
+   public static final ParentPolicy AFTER = new ParentPolicy(ClassFilter.NOTHING, ClassFilter.EVERYTHING, "AFTER");
+
+   /** Standard Java Delegation for java classes */
+   public static final ParentPolicy BEFORE_BUT_JAVA_ONLY = new ParentPolicy(ClassFilter.JAVA_ONLY, ClassFilter.NOTHING, "BEFORE_BUT_JAVA_ONLY");
+
+   /** Java classes before, everything else after */
+   public static final ParentPolicy AFTER_BUT_JAVA_BEFORE = new ParentPolicy(ClassFilter.JAVA_ONLY, ClassFilter.EVERYTHING, "AFTER_BUT_JAVA_BEFORE");
+   
+   /** The before filter */
+   private ClassFilter beforeFilter;
+   
+   /** The after filter */
+   private ClassFilter afterFilter;
+
+   /** A description of the policy */
+   private String description;
+   
+   /**
+    * Create a new ParentPolicy.
+    * 
+    * @param beforeFilter the before filter
+    * @param afterFilter the after filter
+    * @throws IllegalArgumentException for a null parameter
+    */
+   public ParentPolicy(ClassFilter beforeFilter, ClassFilter afterFilter)
+   {
+      this(beforeFilter, afterFilter, null);
+   }
+
+   /**
+    * Create a new ParentPolicy.
+    * 
+    * @param beforeFilter the before filter
+    * @param afterFilter the after filter
+    * @param description of the policy
+    * @throws IllegalArgumentException for a null parameter
+    */
+   public ParentPolicy(ClassFilter beforeFilter, ClassFilter afterFilter, String description)
+   {
+      if (beforeFilter == null)
+         throw new IllegalArgumentException("Null beforeFilter");
+      if (afterFilter == null)
+         throw new IllegalArgumentException("Null afterFilter");
+      
+      this.beforeFilter = beforeFilter;
+      this.afterFilter = afterFilter;
+      this.description = description;
+      if (description == null)
+         description = "(before=" + beforeFilter + " after=" + afterFilter + ")";
+   }
+
+   /**
+    * Get the beforeFilter.
+    * 
+    * @return the beforeFilter.
+    */
+   public ClassFilter getBeforeFilter()
+   {
+      return beforeFilter;
+   }
+
+   /**
+    * Get the afterFilter.
+    * 
+    * @return the afterFilter.
+    */
+   public ClassFilter getAfterFilter()
+   {
+      return afterFilter;
+   }
+   
+   @Override
+   public String toString()
+   {
+      return description;
+   }
+}

Added: 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	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoader.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,575 @@
+/*
+ * 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.classloader.spi.base;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.security.SecureClassLoader;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.ClassLoaderPolicy;
+import org.jboss.classloader.spi.DelegateLoader;
+import org.jboss.classloader.spi.PackageInformation;
+import org.jboss.logging.Logger;
+import org.jboss.util.collection.Iterators;
+
+/**
+ * BaseClassLoader.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class BaseClassLoader extends SecureClassLoader
+{
+   /** The log */
+   private static final Logger log = Logger.getLogger(BaseClassLoader.class);
+
+   /** The lock object */
+   private ReentrantLock lock = new ReentrantLock(true);
+   
+   /** The policy for this classloader */
+   private ClassLoaderPolicy policy;
+   
+   /** Our Loader front end */
+   private DelegateLoader loader;
+   
+   /**
+    * Create a new ClassLoader with no parent.
+    * 
+    * @param policy the policy
+    * @throws IllegalArgumentException for a null policy 
+    * @throws IllegalStateException if the policy is already associated with a classloader 
+    */
+   public BaseClassLoader(ClassLoaderPolicy policy)
+   {
+      super(null);
+      if (policy == null)
+         throw new IllegalArgumentException("Null policy");
+      this.policy = policy;
+      
+      BaseClassLoaderPolicy basePolicy = policy;
+      basePolicy.setClassLoader(this);
+
+      loader = new DelegateLoader(policy);
+      
+      if (log.isTraceEnabled())
+         log.debug("Created " + this + " with policy " + policy);
+   }
+
+   /**
+    * Get the policy.
+    * 
+    * @return the policy.
+    */
+   ClassLoaderPolicy getPolicy()
+   {
+      return policy;
+   }
+
+   /**
+    * Get the loader.
+    * 
+    * @return the loader.
+    */
+   DelegateLoader getLoader()
+   {
+      return loader;
+   }
+
+   @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 = findLoadedClass(name);
+      if (result != null && trace)
+         log.trace(this + " already loaded class " + name + " " + ClassLoaderUtils.classToString(result));
+
+      // If this is an array, use Class.forName() to resolve it
+      if (name.charAt(0) == '[')
+      {
+         if (trace)
+            log.trace(this + " resolving array class " + name + " using Class.forName()");
+         result = Class.forName(name, true, this);
+         if (trace)
+            log.trace(this + " resolved array "  + ClassLoaderUtils.classToString(result));
+      }
+      
+      // Not already loaded use the domain
+      if (result == null)
+         result = loadClassFromDomain(name, trace);
+      
+      // Still not found
+      if (result == null)
+      {
+         if (trace)
+            log.trace(this + " class not found " + name);
+         throw new ClassNotFoundException(name + " from " + toLongString());
+      }
+      
+      // Link the class if requested
+      if (resolve)
+      {
+         if (trace)
+            log.trace(this + " resolveClass " + ClassLoaderUtils.classToString(result));
+         resolveClass(result);
+      }
+      
+      return result;
+   }
+
+   @Override
+   public URL getResource(String name)
+   {
+      BaseClassLoaderPolicy basePolicy = policy;
+      BaseClassLoaderDomain domain = basePolicy.getClassLoaderDomain();
+      boolean trace = log.isTraceEnabled();
+      if (trace)
+         log.trace(this + " getResource " + name + " domain=" + domain);
+
+      if (domain != null)
+         return domain.getResource(this, name, ClassLoaderUtils.getResourceNameInDotNotation(name));
+      return null;
+   }
+
+   @Override
+   @SuppressWarnings("unchecked")
+   protected Enumeration<URL> findResources(String name) throws IOException
+   {
+      BaseClassLoaderPolicy basePolicy = policy;
+      BaseClassLoaderDomain domain = basePolicy.getClassLoaderDomain();
+      boolean trace = log.isTraceEnabled();
+      if (trace)
+         log.trace(this + " findResources " + name + " domain=" + domain);
+
+      Set<URL> resourceURLs = new HashSet<URL>();
+      if (domain != null)
+         domain.getResources(this, name, ClassLoaderUtils.getResourceNameInDotNotation(name), resourceURLs);
+      return Iterators.toEnumeration(resourceURLs.iterator());
+   }
+
+   /**
+    * Try to load the class locally
+    * 
+    * @param name the class name
+    * @return the class
+    */
+   Class<?> loadClassLocally(String name)
+   {
+      return loadClassLocally(name, log.isTraceEnabled());
+   }
+
+   /**
+    * Try to load the class locally
+    * 
+    * @param name the class name
+    * @param trace whether trace is enabled
+    * @return the class if found
+    */
+   synchronized Class<?> loadClassLocally(String name, boolean trace)
+   {
+      if (trace)
+         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);
+      if (result != null)
+      {
+         if (trace)
+            log.trace(this + " already loaded " + ClassLoaderUtils.classToString(result));
+         return result;
+      }
+
+      // Look for the resource
+      String resourceName = ClassLoaderUtils.classNameToPath(name);
+      InputStream is = policy.getResourceAsStream(resourceName);
+      if (is == null)
+      {
+         if (trace)
+            log.trace(this + " resource not found locally " + resourceName + " for " + name);
+         return null;
+      }
+
+      // Load the bytecode
+      byte[] byteCode = ClassLoaderUtils.loadByteCode(name, is);
+      
+      // Let the policy do things before we define the class
+      BaseClassLoaderPolicy basePolicy = policy;
+      ProtectionDomain protectionDomain = basePolicy.getProtectionDomain(name, resourceName);
+      byteCode = policy.transform(name, byteCode, protectionDomain);
+      
+      // Create the package if necessary
+      definePackage(name);
+      
+      // Finally we can define the class
+      if (protectionDomain != null)
+         result = defineClass(name, byteCode, 0, byteCode.length, protectionDomain);
+      else
+         result = defineClass(name, byteCode, 0, byteCode.length);
+      if (trace)
+         log.trace(this + " loaded class locally " + ClassLoaderUtils.classToString(result));
+      return result;
+   }
+
+   /**
+    * Try to find the resource locally
+    * 
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @return the url if found
+    */
+   URL getResourceLocally(String name, String resourceName)
+   {
+      return getResourceLocally(name, resourceName, log.isTraceEnabled());
+   }
+
+   /**
+    * Try to find the resource locally
+    * 
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @param trace whether trace is enabled
+    * @return the URL if found
+    */
+   URL getResourceLocally(String name, String resourceName, boolean trace)
+   {
+      if (trace)
+         log.trace(this + " get resource locally " + name);
+
+      // Look for the resource
+      URL result = policy.getResource(name);
+      if (result == null)
+      {
+         if (trace)
+            log.trace(this + " resource not found locally " + name);
+         return null;
+      }
+      if (trace)
+         log.trace(this + " got resource locally " + name);
+      return result;
+   }
+
+   /**
+    * Try to find the resource locally
+    * 
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @param urls the urls to add to
+    * @throws IOException for any error
+    */
+   void getResourcesLocally(String name, String resourceName, Set<URL> urls) throws IOException
+   {
+      getResourcesLocally(name, resourceName, urls, log.isTraceEnabled());
+   }
+
+   /**
+    * Try to find the resources locally
+    * 
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @param urls the urls to add to
+    * @param trace whether trace is enabled
+    * @throws IOException for any error
+    */
+   void getResourcesLocally(String name, String resourceName, Set<URL> urls, boolean trace) throws IOException
+   {
+      if (trace)
+         log.trace(this + " get resources locally " + name);
+
+      // Look for the resources
+      policy.getResources(name, urls);
+   }
+   
+   /**
+    * Define the package for the class if not already done
+    *
+    * @param className the class name
+    */
+   protected void definePackage(String className)
+   {
+      String packageName = ClassLoaderUtils.getClassPackageName(className);
+      if (packageName.length() == 0)
+         return;
+      
+      // Already defined?
+      Package pkge = getPackage(packageName);
+      if (pkge != null)
+         return;
+      
+      // Ask the policy for the information
+      PackageInformation pi = policy.getPackageInformation(packageName);
+      try
+      {
+         if (pi != null)
+            definePackage(packageName, pi.specTitle, pi.specVersion, pi.specVendor, pi.implTitle, pi.implVersion, pi.implVendor, pi.sealBase);
+         else
+            definePackage(packageName, null, null, null, null, null, null, null);
+      }
+      catch (IllegalArgumentException alreadyDone)
+      {
+         // The package has already been defined
+      }
+   }
+
+   /**
+    * Try to load the class from the domain
+    * 
+    * @param name the class name
+    * @param trace whether trace is enabled
+    * @return the class if found in the parent
+    * @throws ClassNotFoundException for any error
+    */
+   protected Class<?> loadClassFromDomain(String name, boolean trace) throws ClassNotFoundException
+   {
+      // Because of the broken classloading in the Sun JDK we need to
+      // serialize access to the classloader.
+      
+      // Additionally, acquiring the lock on the policy for this classloader
+      // ensures that we don't race with somebody undeploying the classloader
+      // which could cause leaks
+      acquireLockFairly(trace);
+      try
+      {
+         // Here we have synchronized with the policy 
+         BaseClassLoaderPolicy basePolicy = policy;
+         BaseClassLoaderDomain domain = basePolicy.getClassLoaderDomain();
+         
+         if (trace)
+            log.trace(this + " load from domain " + name + " domain=" + domain);
+
+         // No domain, try to load the class locally
+         // this could happen during undeployment of the classloader
+         // where something needs a local class after it is has been unhooked from the system
+         if (domain == null)
+         {
+            Class<?> result = loadClassLocally(name, trace);
+            
+            // So this is almost certainly a classloader leak
+            if (result == null)
+               throw new IllegalStateException(this + " classLoader is not connected to a domain (probably undeployed?) for class " + name);
+            return result;
+         }
+
+         // Ask the domain to load the class in the context of our classloader/policy
+         Class<?> result = domain.loadClass(this, name);
+         if (result != null && trace)
+            log.trace(this + " got class from domain " + ClassLoaderUtils.classToString(result));
+         return result;
+      }
+      finally
+      {
+         unlock(trace);
+      }
+   }
+   
+   /**
+    * A long version of the classloader
+    * 
+    * @return the long string
+    */
+   public String toLongString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append(getClass().getSimpleName());
+      builder.append('@').append(Integer.toHexString(System.identityHashCode(this)));
+      builder.append('{').append(getPolicy().toLongString());
+      toLongString(builder);
+      builder.append('}');
+      return builder.toString();
+   }
+
+   /**
+    * For subclasses to add things to the long string
+    * 
+    * @param builder the builder
+    */
+   protected void toLongString(StringBuilder builder)
+   {
+   }
+   
+   @Override
+   public String toString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append(getClass().getSimpleName());
+      builder.append('@').append(Integer.toHexString(System.identityHashCode(this)));
+      return builder.toString();
+   }
+
+   /**
+    * Attempt to lock, but don't wait
+    * 
+    * @return true when the lock was obtained
+    */
+   boolean attemptLock()
+   {
+      return attemptLock(log.isTraceEnabled());
+   }
+
+   /**
+    * Lock
+    * 
+    * This method must be invoked with the monitor held
+    */
+   void lock()
+   {
+      acquireLockFairly(log.isTraceEnabled());
+   }
+
+   /**
+    * Unlock
+    */
+   void unlock()
+   {
+      unlock(log.isTraceEnabled());
+   }
+
+   /**
+    * Attempt to get the lock but don't wait
+    * 
+    * @param trace whether trace is enabled
+    * @return true when obtained the lock
+    */
+   private final boolean attemptLock(boolean trace)
+   {
+      Thread thread = Thread.currentThread();
+      if (trace)
+         log.trace(this + " attemptLock " + thread);
+
+      boolean interrupted = Thread.interrupted();
+
+      boolean result = false;
+      try
+      {
+         result = lock.tryLock(0, TimeUnit.MICROSECONDS);
+      }
+      catch (InterruptedException ignored)
+      {
+      }
+      finally
+      {
+         if (interrupted)
+            thread.interrupt();
+      }
+      if (trace)
+      {
+         if (result)
+            log.trace(this + " locked " + thread + " holding=" + lock.getHoldCount());
+         else
+            log.trace(this + " did NOT get the lock " + thread);
+      }
+
+      // We got the lock so we own it
+      if (result && lock.getHoldCount() == 1)
+         ClassLoaderManager.registerLoaderThread(this, thread);
+
+      return result;
+   }
+   
+   /**
+    * Acquire the lock on the classloader fairly<p>
+    *
+    * This must be invoked with the monitor held
+    */
+   private void acquireLockFairly(boolean trace)
+   {
+      Thread thread = Thread.currentThread();
+      if (trace)
+         log.trace(this + " aquireLockFairly " + thread);
+
+      boolean interrupted = thread.interrupted();
+
+      int waits = 0;
+      
+      try
+      {
+         while (true)
+         {
+            try
+            {
+               if (lock.tryLock(0, TimeUnit.MICROSECONDS) == false)
+               {
+                  // REVIEW: If we've been spinning for more than a minute then there is probably something wrong? 
+                  if (waits++ == 6)
+                     throw new IllegalStateException("Waiting too long to get the classloader lock: " + this);
+                  // Wait 10 seconds
+                  if (trace)
+                     log.trace(this + " waiting for lock " + thread);
+                  this.wait(10000);
+               }
+               else
+               {
+                  if (trace)
+                     log.trace(this + " aquiredLock " + thread + " holding=" + lock.getHoldCount());
+                  break;
+               }
+            }
+            catch (InterruptedException ignored)
+            {
+            }
+         }
+      }
+      finally
+      {
+         if (interrupted)
+            thread.interrupt();
+      }
+      
+      if (lock.getHoldCount() == 1)
+         ClassLoaderManager.registerLoaderThread(this, thread);
+   }
+
+   /**
+    * Unlock
+    * 
+    * This method must be invoked with the monitor held
+    */
+   private void unlock(boolean trace)
+   {
+      Thread thread = Thread.currentThread();
+      if (trace)
+         log.trace(this + " unlock " + thread + " holding=" + lock.getHoldCount());
+
+      lock.unlock();      
+      
+      if (lock.getHoldCount() == 0)
+         ClassLoaderManager.unregisterLoaderThread(this, thread);
+
+      synchronized (this)
+      {
+         notifyAll();
+      }
+   }
+}

Added: 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	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,631 @@
+/*
+ * 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.classloader.spi.base;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.ClassLoaderPolicy;
+import org.jboss.classloader.spi.DelegateLoader;
+import org.jboss.classloader.spi.Loader;
+import org.jboss.logging.Logger;
+
+/**
+ * BaseClassLoaderDomain.<p>
+ * 
+ * This class hides some of the implementation details and allows
+ * package access to the protected methods.
+ *
+ * TODO add handling of domain shutdown
+ * TODO add caching (needs to be per classloader when not AllExports policy)
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class BaseClassLoaderDomain implements Loader
+{
+   /** The log */
+   private static final Logger log = Logger.getLogger(BaseClassLoaderDomain.class);
+
+   /** 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>>();
+   
+   /** Keep track of the added order */
+   private int order = 0;
+   
+   /**
+    * Invoked before classloading is attempted to allow a preload attempt, e.g. from the parent
+    * 
+    * @param name the class resource name
+    * @param resourceName the resource name in dot notation
+    * @return the loader if found or null otherwise
+    */
+   protected abstract Loader findBeforeLoader(String name, String resourceName);
+   
+   /**
+    * Invoked after classloading is attempted to allow a postload attempt, e.g. from the parent
+    * 
+    * @param name the class resource name
+    * @param resourceName the resource name in dot notation
+    * @return the loader if found or null otherwise
+    */
+   protected abstract Loader findAfterLoader(String name, String resourceName);
+   
+   public Class<?> loadClass(String name)
+   {
+      try
+      {
+         return loadClass(null, name, true);
+      }
+      catch (ClassNotFoundException e)
+      {
+         return null;
+      }
+   }
+   
+   /**
+    * Load a class from the domain
+    * 
+    * @param classLoader the classloader
+    * @param name the class name
+    * @return the class
+    * @throws ClassNotFoundException for any error
+    */
+   Class<?> loadClass(BaseClassLoader classLoader, String name) throws ClassNotFoundException
+   {
+      return loadClass(classLoader, name, false);
+   }
+   
+   /**
+    * Load a class from the domain
+    * 
+    * @param classLoader the classloader
+    * @param name the class name
+    * @param allExports whether we should look at all exports
+    * @return the class
+    * @throws ClassNotFoundException for any error
+    */
+   Class<?> loadClass(BaseClassLoader classLoader, String name, boolean allExports) throws ClassNotFoundException
+   {
+      boolean trace = log.isTraceEnabled();
+      
+      String path = ClassLoaderUtils.classNameToPath(name);
+      
+      // Try the before attempt (e.g. from the parent)
+      Loader loader = findBeforeLoader(path, name);
+      
+      if (loader == null)
+      {
+         // Work out the rules
+         List<? extends DelegateLoader> delegates = null;
+         BaseClassLoaderPolicy policy = null;
+         if (classLoader != null)
+         {
+            policy = classLoader.getPolicy();
+            delegates = policy.getDelegates();
+            if (policy.isImportAll())
+               allExports = true;
+         }
+
+         // Next we try the old "big ball of mud" model      
+         if (allExports)
+         {
+            String packageName = ClassLoaderUtils.getClassPackageName(name);
+            List<ClassLoaderInformation> list = classLoadersByPackageName.get(packageName);
+            if (list != null && list.isEmpty() == false)
+            {
+               if (trace)
+                  log.trace(this + " trying to load " + name + " from all exports " + list);
+               for (ClassLoaderInformation info : list)
+               {
+                  BaseDelegateLoader exported = info.getExported();
+                  if (exported.getResource(path, name) != null)
+                  {
+                     loader = exported;
+                     break;
+                  }
+               }
+            }
+         }
+         
+         // Next we try the imports
+         if (loader == null && delegates != null && delegates.isEmpty() == false)
+         {
+            for (DelegateLoader delegate : delegates)
+            {
+               if (trace)
+                  log.trace(this + " trying to load " + name + " from import " + delegate + " for " + classLoader);
+               if (delegate.getResource(path, name) != null)
+               {
+                  loader = delegate;
+                  break;
+               }
+            }
+         }
+
+         // Next use any requesting classloader, this will look at everything not just what it exports
+         if (loader == null && classLoader != null)
+         {
+            if (trace)
+               log.trace(this + " trying to load " + name + " from requesting " + classLoader);
+            if (classLoader.getResourceLocally(path, name) != null)
+               loader = classLoader.getLoader();
+         }
+
+         // Try the after attempt (e.g. from the parent)
+         if (loader == null)
+            loader = findAfterLoader(path, name);
+
+         // Finally see whether this is the JDK assuming it can load its classes from any classloader
+         if (loader == null && ClassLoaderUtils.isRequestFromJDK())
+         {
+            ClassLoader hack = getClass().getClassLoader();
+            if (trace)
+               log.trace(this + " trying to load " + name + " using hack " + hack);
+            Class<?> result = getClass().getClassLoader().loadClass(name);
+            {
+               if (trace)
+                  log.trace(this + " loaded from hack " + hack + " " + ClassLoaderUtils.classToString(result));
+               return result;
+            }
+         }
+      }
+
+      if (loader != null)
+      {
+         Thread thread = Thread.currentThread();
+         ClassLoadingTask task = new ClassLoadingTask(name, classLoader, thread);
+         ClassLoaderManager.scheduleTask(task, loader, false);
+         return ClassLoaderManager.process(thread, task);
+      }
+      
+      // Didn't find it
+      return null;
+   }
+   
+   /**
+    * Invoked before getResource is attempted to allow a preload attempt, e.g. from the parent
+    * 
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @return the url if found or null otherwise
+    */
+   protected abstract URL beforeGetResource(String name, String resourceName);
+   
+   /**
+    * Invoked after getResource is attempted to allow a postload attempt, e.g. from the parent
+    * 
+    * @param name the class name
+    * @param resourceName the name of the resource in dot notation
+    * @return the url if found or null otherwise
+    */
+   protected abstract URL afterGetResource(String name, String resourceName);
+   
+   public URL getResource(String name, String resourceName)
+   {
+      return getResource(null, name, resourceName, true);
+   }
+   
+   /**
+    * Get a resource from the domain
+    * 
+    * @param classLoader the classloader
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @return the url
+    */
+   URL getResource(BaseClassLoader classLoader, String name, String resourceName)
+   {
+      return getResource(classLoader, name, resourceName, false);
+   }
+   
+   /**
+    * Load a resource from the domain
+    * 
+    * @param classLoader the classloader
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @param allExports whether we should look at all exports
+    * @return the url
+    */
+   URL getResource(BaseClassLoader classLoader, String name, String resourceName, boolean allExports)
+   {
+      boolean trace = log.isTraceEnabled();
+
+      // Try the before attempt
+      URL result = beforeGetResource(name, resourceName);
+      if (result != null)
+         return result;
+
+      // Work out the rules
+      List<? extends DelegateLoader> delegates = null;
+      BaseClassLoaderPolicy policy = null;
+      if (classLoader != null)
+      {
+         policy = classLoader.getPolicy();
+         delegates = policy.getDelegates();
+         if (policy.isImportAll())
+            allExports = true;
+      }
+
+      // Next we try the old "big ball of mud" model      
+      if (allExports)
+      {
+         String packageName = ClassLoaderUtils.getResourcePackageName(name);
+         List<ClassLoaderInformation> list = classLoadersByPackageName.get(packageName);
+         if (list != null && list.isEmpty() == false)
+         {
+            if (trace)
+               log.trace(this + " trying to get resource " + name + " from all exports " + list);
+            for (ClassLoaderInformation info : list)
+            {
+               BaseDelegateLoader loader = info.getExported();
+               result = loader.getResource(name, resourceName);
+               if (result != null)
+                  return result;
+            }
+         }
+      }
+      
+      // Next we try the imports
+      if (delegates != null && delegates.isEmpty() == false)
+      {
+         for (DelegateLoader delegate : delegates)
+         {
+            if (trace)
+               log.trace(this + " trying to get resource " + name + " from import " + delegate + " for " + classLoader);
+            result = delegate.getResource(name, resourceName);
+            if (result != null)
+               return result;
+         }
+      }
+
+      // Finally use any requesting classloader
+      if (classLoader != null)
+      {
+         if (trace)
+            log.trace(this + " trying to get resource " + name + " from requesting " + classLoader);
+         result = classLoader.getResourceLocally(name, resourceName);
+         if (result != null)
+         {
+            if (trace)
+               log.trace(this + " got resource from requesting " + classLoader + " " + result);
+            return result;
+         }
+      }
+
+      // Try the after attempt
+      result = afterGetResource(name, resourceName);
+      if (result != null)
+         return result;
+      
+      // Didn't find it
+      return null;
+   }
+   
+   /**
+    * Invoked before getResources is attempted to allow a preload attempt, e.g. from the parent
+    * 
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @param urls the urls to add to
+    * @throws IOException for any error
+    */
+   protected abstract void beforeGetResources(String name, String resourceName, Set<URL> urls) throws IOException;
+   
+   /**
+    * Invoked after getResources is attempted to allow a postload attempt, e.g. from the parent
+    * 
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @param urls the urls to add to
+    * @throws IOException for any error
+    */
+   protected abstract void afterGetResources(String name, String resourceName, Set<URL> urls) throws IOException;
+   
+   public void getResources(String name, String resourceName, Set<URL> urls) throws IOException
+   {
+      getResources(null, name, resourceName, urls, true);
+   }
+   
+   /**
+    * Get a resource from the domain
+    * 
+    * @param classLoader the classloader
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @param urls the urls to add to
+    * @throws IOException for any error
+    */
+   void getResources(BaseClassLoader classLoader, String name, String resourceName, Set<URL> urls) throws IOException
+   {
+      getResources(classLoader, name, resourceName, urls, false);
+   }
+   
+   /**
+    * Load a resource from the domain
+    * 
+    * @param classLoader the classloader
+    * @param name the resource name
+    * @param resourceName the name of the resource in dot notation
+    * @param allExports whether we should look at all exports
+    * @param urls the urls to add to
+    * @throws IOException for any error
+    */
+   void getResources(BaseClassLoader classLoader, String name, String resourceName, Set<URL> urls, boolean allExports) throws IOException
+   {
+      boolean trace = log.isTraceEnabled();
+
+      // Try the before attempt
+      beforeGetResources(name, resourceName, urls);
+
+      // Work out the rules
+      List<? extends DelegateLoader> delegates = null;
+      BaseClassLoaderPolicy policy = null;
+      if (classLoader != null)
+      {
+         policy = classLoader.getPolicy();
+         delegates = policy.getDelegates();
+         if (policy.isImportAll())
+            allExports = true;
+      }
+
+      // Next we try the old "big ball of mud" model      
+      if (allExports)
+      {
+         String packageName = ClassLoaderUtils.getResourcePackageName(name);
+         List<ClassLoaderInformation> list = classLoadersByPackageName.get(packageName);
+         if (list != null && list.isEmpty() == false)
+         {
+            if (trace)
+               log.trace(this + " trying to get resources " + name + " from all exports " + list);
+            for (ClassLoaderInformation info : list)
+            {
+               BaseDelegateLoader loader = info.getExported();
+               loader.getResources(name, resourceName, urls);
+            }
+         }
+      }
+      
+      // Next we try the imports
+      if (delegates != null && delegates.isEmpty() == false)
+      {
+         for (DelegateLoader delegate : delegates)
+         {
+            if (trace)
+               log.trace(this + " trying to get resources " + name + " from import " + delegate + " for " + classLoader);
+            delegate.getResources(name, resourceName, urls);
+         }
+      }
+
+      // Finally use any requesting classloader
+      if (classLoader != null)
+      {
+         if (trace)
+            log.trace(this + " trying to get resources " + name + " from requesting " + classLoader);
+         classLoader.getResourcesLocally(name, resourceName, urls);
+      }
+
+      // Try the after attempt
+      afterGetResources(name, resourceName, urls);
+   }
+
+   /**
+    * A long version of toString()
+    * 
+    * @return the long string
+    */
+   public String toLongString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append(getClass().getSimpleName());
+      builder.append("@").append(Integer.toHexString(System.identityHashCode(this)));
+      builder.append("{");
+      toLongString(builder);
+      builder.append('}');
+      return builder.toString();
+   }
+   
+   /**
+    * For subclasses to add information for toLongString()
+    * 
+    * @param builder the builder
+    */
+   protected void toLongString(StringBuilder builder)
+   {
+   }
+   
+   /**
+    * Invoked before adding a classloader policy 
+    * 
+    * @param classLoader the classloader
+    * @param policy the classloader policy
+    */
+   protected void beforeRegisterClassLoader(ClassLoader classLoader, ClassLoaderPolicy policy)
+   {
+      // nothing
+   }
+   /**
+    * Invoked after adding a classloader policy 
+    * 
+    * @param classLoader the classloader
+    * @param policy the classloader policy
+    */
+   protected void afterRegisterClassLoader(ClassLoader classLoader, ClassLoaderPolicy policy)
+   {
+      // nothing
+   }
+   
+   /**
+    * Invoked before adding a classloader policy 
+    * 
+    * @param classLoader the classloader
+    * @param policy the classloader policy
+    */
+   protected void beforeUnregisterClassLoader(ClassLoader classLoader, ClassLoaderPolicy policy)
+   {
+      // nothing
+   }
+   /**
+    * Invoked after adding a classloader policy 
+    * 
+    * @param classLoader the classloader
+    * @param policy the classloader policy
+    */
+   protected void afterUnregisterClassLoader(ClassLoader classLoader, ClassLoaderPolicy policy)
+   {
+      // nothing
+   }
+   
+   /**
+    * Remove a classloader 
+    * 
+    * @param classLoader the classloader
+    */
+   protected void removeClassLoader(BaseClassLoader classLoader)
+   {
+      // nothing
+   }
+   
+   /**
+    * Register a classloader 
+    * 
+    * @param classLoader the classloader
+    */
+   void registerClassLoader(BaseClassLoader classLoader)
+   {
+      log.debug(this + " registerClassLoader " + classLoader.toLongString());
+
+      try
+      {
+         beforeRegisterClassLoader(classLoader, classLoader.getPolicy());
+      }
+      catch (Throwable t)
+      {
+         log.warn("Error in beforeRegisterClassLoader: " + this + " classLoader=" + classLoader.toLongString(), t);
+      }
+      
+      BaseClassLoaderPolicy policy = classLoader.getPolicy();
+      policy.setClassLoaderDomain(this);
+
+      synchronized (classLoaders)
+      {
+         // Create the information
+         ClassLoaderInformation info = new ClassLoaderInformation(classLoader, policy, order++);
+         classLoaders.add(info);
+         infos.put(classLoader, info);
+
+         // Index the packages
+         // TODO Test base package and add support for dynamic packages to the policy
+         String[] packageNames = policy.getPackageNames();
+         if (packageNames != null && info.getExported() != null)
+         {
+            for (String packageName : packageNames)
+            {
+               List<ClassLoaderInformation> list = classLoadersByPackageName.get(packageName);
+               if (list == null)
+               {
+                  list = new CopyOnWriteArrayList<ClassLoaderInformation>();
+                  classLoadersByPackageName.put(packageName, list);
+               }
+               list.add(info);
+               log.trace("Registered " + policy + " as providing package=" + packageName);
+            }
+         }
+      }
+
+      try
+      {
+         afterRegisterClassLoader(classLoader, classLoader.getPolicy());
+      }
+      catch (Throwable t)
+      {
+         log.warn("Error in afterRegisterClassLoader: " + this + " classLoader=" + classLoader.toLongString(), t);
+      }
+   }
+   
+   /**
+    * Remove a classloader 
+    * 
+    * @param classLoader the classloader
+    */
+   synchronized void unregisterClassLoader(BaseClassLoader classLoader)
+   {
+      log.debug(this + " unregisterClassLoader " + classLoader.toLongString());
+
+      try
+      {
+         beforeUnregisterClassLoader(classLoader, classLoader.getPolicy());
+      }
+      catch (Throwable t)
+      {
+         log.warn("Error in beforeUnegisterClassLoader: " + this + " classLoader=" + classLoader.toLongString(), t);
+      }
+
+      BaseClassLoaderPolicy policy = classLoader.getPolicy();
+      policy.unsetClassLoaderDomain(this);
+
+      synchronized (classLoaders)
+      {
+         // Remove the classloader
+         ClassLoaderInformation info = infos.remove(classLoader);
+         classLoaders.remove(info);
+         
+         // Remove the package index
+         String[] packageNames = policy.getPackageNames();
+         if (packageNames != null && info.getExported() != null)
+         {
+            for (String packageName : packageNames)
+            {
+               List<ClassLoaderInformation> list = classLoadersByPackageName.get(packageName);
+               if (list != null)
+               {
+                  list.remove(info);
+                  log.trace("Unregistered " + policy + " as providing package=" + packageName);
+                  if (list.isEmpty())
+                     classLoadersByPackageName.remove(packageName);
+               }
+            }
+         }
+      }
+
+      try
+      {
+         afterUnregisterClassLoader(classLoader, classLoader.getPolicy());
+      }
+      catch (Throwable t)
+      {
+         log.warn("Error in afterUnegisterClassLoader: " + this + " classLoader=" + classLoader.toLongString(), t);
+      }
+   }
+}

Added: 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	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,203 @@
+/*
+ * 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.classloader.spi.base;
+
+import java.security.ProtectionDomain;
+import java.util.List;
+
+import org.jboss.classloader.spi.DelegateLoader;
+
+/**
+ * Base ClassLoader policy.<p>
+ * 
+ * This class hides some of the implementation details and allows
+ * package access to the protected methods.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class BaseClassLoaderPolicy
+{
+   /** The classloader for this policy */
+   private volatile BaseClassLoader classLoader;
+
+   /** The domain for this policy */
+   private volatile BaseClassLoaderDomain domain;
+
+   /**
+    * Get the delegate loader for exported stuff<p>
+    *
+    * NOTE: Protected access for security reasons
+    * 
+    * @return the delegate loader
+    */
+   protected abstract DelegateLoader getExported();
+
+   /**
+    * Get the exported packages<p>
+    *
+    * Provides a hint for indexing
+    * 
+    * @return the package names
+    */
+   public abstract String[] getPackageNames();
+
+   /**
+    * Get the delegate loaders for imported stuff<p>
+    * 
+    * NOTE: Protected access for security reasons
+    * 
+    * @return the delegate loaders
+    */
+   protected abstract List<? extends DelegateLoader> getDelegates();
+
+   /**
+    * Whether to import all exports from other classloaders in the domain
+    * 
+    * @return true to import all
+    */
+   protected abstract boolean isImportAll();
+
+   /**
+    * Get the protection domain<p>
+    * 
+    * NOTE: Defined as protected here for security reasons
+    * 
+    * @param className the class name
+    * @param path the path
+    * @return the protection domain
+    */
+   protected abstract ProtectionDomain getProtectionDomain(String className, String path);
+   
+   /**
+    * Transform the byte code
+    * 
+    * @param className the class name
+    * @param byteCode the byte code
+    * @param protectionDomain the protection domain
+    * @return the transformed byte code
+    */
+   protected byte[] transform(String className, byte[] byteCode, ProtectionDomain protectionDomain)
+   {
+      // TODO should delegate to the domain by default
+      return byteCode;
+   }
+
+   /**
+    * A long version of toString()
+    * 
+    * @return the long string
+    */
+   public String toLongString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append(getClass().getSimpleName());
+      builder.append("@").append(Integer.toHexString(System.identityHashCode(this)));
+      builder.append("{domain=");
+      if (domain == null)
+         builder.append("null");
+      else
+         builder.append(domain.toLongString());
+      toLongString(builder);
+      builder.append('}');
+      return builder.toString();
+   }
+   
+   /**
+    * For subclasses to add information for toLongString()
+    * 
+    * @param builder the builder
+    */
+   protected void toLongString(StringBuilder builder)
+   {
+   }
+
+   @Override
+   public String toString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append(getClass().getSimpleName());
+      builder.append("@").append(Integer.toHexString(System.identityHashCode(this)));
+      return builder.toString();
+   }
+   
+   /**
+    * Get the classloader domain
+    * 
+    * @return the domain
+    */
+   BaseClassLoaderDomain getClassLoaderDomain()
+   {
+      return domain;
+   }
+   
+   /**
+    * Set the classloader domain
+    * 
+    * @param domain the domain
+    * @throws IllegalStateException if the policy already has a domain
+    */
+   void setClassLoaderDomain(BaseClassLoaderDomain domain)
+   {
+      if (this.domain != null)
+         throw new IllegalStateException("Policy already has a domain " + this);
+      this.domain = domain;
+   }
+
+   
+   /**
+    * Unset the classloader domain
+    * 
+    * @param domain the domain
+    * @throws IllegalStateException if the policy is not part of that domain
+    */
+   void unsetClassLoaderDomain(BaseClassLoaderDomain domain)
+   {
+      if (this.domain != domain)
+         throw new IllegalStateException("Policy is not a part of the domain " + this + " domain=" + domain);
+      this.domain = null;
+   }
+   /**
+    * Get the classloader
+    * 
+    * @return the classloader
+    */
+   BaseClassLoader getClassLoader()
+   {
+      return classLoader;
+   }
+   
+   /**
+    * Set the classloader<p>
+    * 
+    * NOTE: Package private for security reasons
+    * 
+    * @param classLoader the classloader
+    * @throws IllegalStateException if the classloader is already set
+    */
+   void setClassLoader(BaseClassLoader classLoader)
+   {
+      if (this.classLoader != null)
+         throw new IllegalStateException("Policy already has a classloader previous=" + classLoader);
+      this.classLoader = classLoader;
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderSystem.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderSystem.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseClassLoaderSystem.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,144 @@
+/*
+ * 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.classloader.spi.base;
+
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderPolicy;
+
+/**
+ * Base ClassLoaderSystem.
+ * 
+ * TODO Permissions
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class BaseClassLoaderSystem
+{
+   /**
+    * A long version of toString()
+    * 
+    * @return the long string
+    */
+   public String toLongString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append(getClass().getSimpleName());
+      builder.append("@").append(Integer.toHexString(System.identityHashCode(this)));
+      builder.append("{");
+      toLongString(builder);
+      builder.append('}');
+      return builder.toString();
+   }
+   
+   /**
+    * For subclasses to add information for toLongString()
+    * 
+    * @param builder the builder
+    */
+   protected void toLongString(StringBuilder builder)
+   {
+   }
+
+   @Override
+   public String toString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append(getClass().getSimpleName());
+      builder.append("@").append(Integer.toHexString(System.identityHashCode(this)));
+      return builder.toString();
+   }
+
+   /**
+    * Register a policy with a domain
+    * 
+    * @param domain the domain
+    * @param policy the policy
+    * @return the classloader
+    * @throws IllegalArgumentException if a parameter is null
+    * @throws IllegalStateException if the policy is already registered with a domain  
+    */
+   protected ClassLoader registerClassLoaderPolicy(BaseClassLoaderDomain domain, ClassLoaderPolicy policy)
+   {
+      if (domain == null)
+         throw new IllegalArgumentException("Null domain");
+
+      BaseClassLoader classLoader = createClassLoader(policy);
+      domain.registerClassLoader(classLoader);
+      return classLoader;
+   }
+   
+   /**
+    * Unregister a policy with a domain
+    * 
+    * @param domain the domain
+    * @param policy the policy
+    * @throws IllegalArgumentException if a parameter is null
+    * @throws IllegalStateException if the policy is not registered with the domain  
+    */
+   protected void unregisterClassLoaderPolicy(BaseClassLoaderDomain domain, ClassLoaderPolicy policy)
+   {
+      if (domain == null)
+         throw new IllegalArgumentException("Null domain");
+      if (policy == null)
+         throw new IllegalArgumentException("Null policy");
+      
+      BaseClassLoaderPolicy basePolicy = policy;
+      BaseClassLoader classLoader = basePolicy.getClassLoader();
+      if (classLoader == null)
+         throw new IllegalStateException("Policy has no associated classloader, it is therefore not registered with a domain. " + policy.toLongString());
+      domain.unregisterClassLoader(classLoader);
+   }
+   
+   /**
+    * Unregister a policy with a domain
+    * 
+    * @param domain the domain
+    * @param classLoader the class loader
+    * @throws IllegalArgumentException if a parameter is null
+    * @throws IllegalStateException if the policy is not registered with the domain  
+    */
+   protected void unregisterClassLoader(ClassLoaderDomain domain, ClassLoader classLoader)
+   {
+      if (domain == null)
+         throw new IllegalArgumentException("Null domain");
+      if (classLoader == null)
+         throw new IllegalArgumentException("Null classLoader");
+      
+      if (classLoader instanceof BaseClassLoader == false)
+         throw new IllegalStateException("ClassLoader is not the correct type and therefore not registered: " + classLoader);
+      
+      BaseClassLoader baseClassLoader = (BaseClassLoader) classLoader;
+      unregisterClassLoaderPolicy(domain, baseClassLoader.getPolicy());
+   }
+
+   /**
+    * Create a classloader for the given policy
+    * 
+    * @param policy the policy
+    * @return the classloader
+    * @throws IllegalArgumentException for a null policy
+    */
+   protected BaseClassLoader createClassLoader(ClassLoaderPolicy policy)
+   {
+      return new BaseClassLoader(policy);
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseDelegateLoader.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseDelegateLoader.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/BaseDelegateLoader.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,121 @@
+/*
+ * 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.classloader.spi.base;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Set;
+
+import org.jboss.classloader.spi.Loader;
+
+/**
+ * Base DelegateLoader.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class BaseDelegateLoader implements Loader
+{
+   /** The delegate loader policy */
+   private BaseClassLoaderPolicy delegate;
+
+   /**
+    * Create a new BaseDelegateLoader.
+    * 
+    * @param delegate the delegate
+    * @throws IllegalArgumentException for a null delegate
+    */
+   public BaseDelegateLoader(BaseClassLoaderPolicy delegate)
+   {
+      if (delegate == null)
+         throw new IllegalArgumentException("Null delegate");
+      this.delegate = delegate;
+   }
+   
+   BaseClassLoaderPolicy getPolicy()
+   {
+      return delegate;
+   }
+   
+   public Class<?> loadClass(String className)
+   {
+      BaseClassLoader classLoader = delegate.getClassLoader();
+      // REVIEW: Should probably add some kind of warning here
+      if (classLoader == null)
+         return null;
+      return classLoader.loadClassLocally(className);
+   }
+   
+   public URL getResource(String name, String resourceName)
+   {
+      BaseClassLoader classLoader = delegate.getClassLoader();
+      // REVIEW: Should probably add some kind of warning here
+      if (classLoader == null)
+         return null;
+      return classLoader.getResourceLocally(name, resourceName);
+   }
+
+   public void getResources(String name, String resourceName, Set<URL> urls) throws IOException
+   {
+      BaseClassLoader classLoader = delegate.getClassLoader();
+      // REVIEW: Should probably add some kind of warning here
+      if (classLoader == null)
+         return;
+      classLoader.getResourcesLocally(name, resourceName, urls);
+   }
+
+   /**
+    * A long version of toString()
+    * 
+    * @return the long string
+    */
+   public String toLongString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append(getClass().getSimpleName());
+      builder.append("@").append(Integer.toHexString(System.identityHashCode(this)));
+      builder.append("{delegate=").append(delegate.toLongString());
+      toLongString(builder);
+      builder.append('}');
+      return builder.toString();
+   }
+   
+   /**
+    * For subclasses to add information for toLongString()
+    * 
+    * @param builder the builder
+    */
+   protected void toLongString(StringBuilder builder)
+   {
+   }
+
+   @Override
+   public String toString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append(getClass().getSimpleName());
+      builder.append("@").append(Integer.toHexString(System.identityHashCode(this)));
+      builder.append("{delegate=").append(delegate);
+      builder.append('}');
+      return builder.toString();
+   }
+}

Added: 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	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoaderInformation.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,109 @@
+/*
+ * 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.classloader.spi.base;
+
+/**
+ * ClassLoaderInformation.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassLoaderInformation
+{
+   /** The classloader */
+   private BaseClassLoader classLoader;
+   
+   /** The policy */
+   private BaseClassLoaderPolicy policy;
+
+   /** The order */
+   private int order;
+   
+   /** The exports of the classloader */
+   private BaseDelegateLoader exported;
+   
+   /**
+    * Create a new ClassLoaderInformation.
+    * 
+    * @param classLoader the classloader
+    * @param policy the policy
+    * @param order the added order
+    * @throws IllegalArgumentException for a null parameter
+    */
+   public ClassLoaderInformation(BaseClassLoader classLoader, BaseClassLoaderPolicy policy, int order)
+   {
+      if (classLoader == null)
+         throw new IllegalArgumentException("Null classloader");
+      if (policy == null)
+         throw new IllegalArgumentException("Null policy");
+      this.classLoader = classLoader;
+      this.policy = policy;
+      this.order = order;
+      this.exported = policy.getExported();
+   }
+
+   /**
+    * Get the classLoader.
+    * 
+    * @return the classLoader.
+    */
+   public BaseClassLoader getClassLoader()
+   {
+      return classLoader;
+   }
+
+   /**
+    * Get the policy.
+    * 
+    * @return the policy.
+    */
+   public BaseClassLoaderPolicy getPolicy()
+   {
+      return policy;
+   }
+
+   /**
+    * Get the order.
+    * 
+    * @return the order.
+    */
+   public int getOrder()
+   {
+      return order;
+   }
+
+   /**
+    * Get the exported.
+    * 
+    * @return the exported.
+    */
+   public BaseDelegateLoader getExported()
+   {
+      return exported;
+   }
+   
+   @Override
+   public String toString()
+   {
+      return policy.toString();
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoaderManager.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoaderManager.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoaderManager.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,408 @@
+/*
+ * 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.classloader.spi.base;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.jboss.classloader.spi.Loader;
+import org.jboss.classloader.spi.base.ClassLoadingTask.ThreadTask;
+import org.jboss.logging.Logger;
+
+/**
+ * ClassLoaderManager.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassLoaderManager
+{
+   /** The log */
+   private static Logger log = Logger.getLogger(ClassLoaderManager.class);
+
+   /** The threads owning the classloader lock */
+   private static Map<BaseClassLoader, Thread> loadClassThreads = new HashMap<BaseClassLoader, Thread>();
+   
+   /** The classloading tasks by thread */
+   private static Map<Thread, List<ThreadTask>> loadTasksByThread = Collections.synchronizedMap(new WeakHashMap<Thread, List<ThreadTask>>());
+
+   /** 
+    * Register a thread as owning the classloader
+    * 
+    * @param classloader the classloader
+    * @param thread the thread
+    * @throws IllegalArgumentException for a null parameter
+    */
+   static void registerLoaderThread(BaseClassLoader classloader, Thread thread)
+   {
+      boolean trace = log.isTraceEnabled();
+      
+      synchronized (loadClassThreads)
+      {
+         Object previousThread = loadClassThreads.put(classloader, thread);
+         if (trace)
+            log.trace("registerLoaderThread, classloader=" + classloader + " thread=" + thread + " previousThread=" + previousThread);
+
+         synchronized (loadTasksByThread)
+         {
+            List<ThreadTask> taskList = loadTasksByThread.get(thread);
+            if (taskList == null)
+            {
+               taskList = Collections.synchronizedList(new LinkedList<ThreadTask>());
+               loadTasksByThread.put(thread, taskList);
+               if (trace)
+                  log.trace("Created new task list for " + thread);
+            }
+         }
+         loadClassThreads.notifyAll();
+      }
+   }
+
+   /** 
+    * Unregister ourselves as owning the classloader lock
+    * 
+    * @param classLoader the classloader
+    * @param thread the thread owning the classloader
+    */
+   public static void unregisterLoaderThread(BaseClassLoader classLoader, Thread thread)
+   {
+      boolean trace = log.isTraceEnabled();
+      if (trace)
+         log.trace("unregisterLoaderThread, classloader=" + classLoader + " thread=" + thread);
+
+      // Unregister as the owning thread and notify any waiting threads
+      synchronized (loadClassThreads)
+      {
+         loadClassThreads.remove(classLoader);
+         loadClassThreads.notifyAll();
+      }
+
+      // Any ThreadTasks associated with this thread must be reassigned
+      List<ThreadTask> taskList = loadTasksByThread.get(thread);
+      if (taskList != null)
+      {
+         synchronized (taskList)
+         {
+            while (taskList.isEmpty() == false)
+            {
+               ThreadTask threadTask = taskList.remove(0);
+               ClassLoadingTask loadTask = threadTask.getLoadTask();
+               Thread requestingThread = loadTask.getRequestingThread();
+               if( trace )
+                  log.trace("Reassigning task: " + threadTask+" to " + requestingThread);
+               threadTask.setThread(null);
+               // Insert the task into the front of requestingThread task list
+               List<ThreadTask> toTaskList = loadTasksByThread.get(requestingThread);
+               synchronized (toTaskList)
+               {
+                  toTaskList.add(0, threadTask);
+                  loadTask.nextEvent();
+                  toTaskList.notify();
+               }
+            }
+         }
+      }
+   }
+
+   /**
+    * Process the classloading task
+    * 
+    * @param thread the thread
+    * @param task the task
+    * @return the loaded class
+    * @throws InterruptedException if it is interrupted
+    */
+   static Class<?> process(Thread thread, ClassLoadingTask task) throws ClassNotFoundException
+   {
+      while (task.getThreadTaskCount() != 0)
+      {
+         try
+         {
+            nextTask(thread, task);
+         }
+         catch(InterruptedException e)
+         {
+            task.setLoadError(e);
+            break;
+         }
+      }
+
+      Class<?> loadedClass = task.getLoadedClass();
+      if (loadedClass == null)
+      {
+         Throwable loadException = task.getLoadException();
+         if (loadException instanceof ClassNotFoundException)
+            throw (ClassNotFoundException) loadException;
+         else if (loadException instanceof NoClassDefFoundError)
+            throw (NoClassDefFoundError) loadException;
+         else if (loadException != null)
+         {
+            log.warn("Unexpected error during load of:" + task.getClassName(), loadException);
+            String msg = "Unexpected error during load of: "+ task.getClassName() + ", msg=" + loadException.getMessage();
+            throw new ClassNotFoundException(msg, loadException);
+         }
+         // Assert that loadedClass is not null
+         else
+            throw new IllegalStateException("ClassLoadingTask.loadedTask is null, name: " + task.getClassName());
+      }
+      return loadedClass;
+   }
+
+   /**
+    * Process the next task
+    * 
+    * @param thread the thread
+    * @param task the task
+    * @throws InterruptedException if it is interrupted
+    */
+   private static void nextTask(Thread thread, ClassLoadingTask task) throws InterruptedException
+   {
+      boolean trace = log.isTraceEnabled();
+      if (trace)
+         log.trace("Next task thread=" + thread + " task=" + task);
+      
+      List<ThreadTask> taskList = loadTasksByThread.get(thread);
+      synchronized (taskList)
+      {
+         // There may not be any ThreadTasks
+         while (taskList.isEmpty() && task.getThreadTaskCount() != 0 )
+         {
+            /* There are no more tasks for the calling thread to execute, so the
+            calling thread must wait until the task.threadTaskCount reaches 0
+             */
+            if (trace)
+               log.trace("Begin nextTask(WAIT_ON_EVENT), task="+task);
+            try
+            {
+               task.waitOnEvent();
+               taskList.wait();
+            }
+            catch(InterruptedException e)
+            {
+               if( trace )
+                  log.trace("nextTask(WAIT_ON_EVENT), interrupted, task="+task, e);
+               // Abort this task t
+               throw e;
+            }
+            if (trace)
+               log.trace("nextTask(WAIT_ON_EVENT), notified, task="+task);
+         }
+
+         if (trace)
+            log.trace("Continue nextTask(" + taskList.size()+"), task="+task);
+
+         // See if the task is complete
+         if (task.getThreadTaskCount() == 0)
+         {
+            task.finish();
+            log.trace("End nextTask(FINISHED), task="+task);
+            return;
+         }
+      }
+
+      ThreadTask threadTask = taskList.remove(0);
+      ClassLoadingTask loadTask = threadTask.getLoadTask();
+      if (trace)
+         log.trace("Begin nextTask(" + taskList.size() + "), loadTask=" + loadTask);
+
+      try
+      {
+         Thread taskThread = threadTask.getThread();
+         if (taskThread == null)
+         {
+            /* This is a task that has been reassigned back to the original
+            requesting thread ClassLoadingTask, so a new ThreadTask must
+            be scheduled.
+            */
+            if (trace)
+               log.trace("Rescheduling threadTask=" + threadTask);
+            scheduleTask(loadTask, threadTask.getLoader(), true);
+         }
+         else
+         {
+            if (trace)
+               log.trace("Running threadTask=" + threadTask);
+            threadTask.run();
+         }
+      }
+      catch (Throwable e)
+      {
+         if (trace)
+            log.trace("Run failed with exception", e);
+         boolean retry = e instanceof ClassCircularityError || e.getClass().equals(LinkageError.class);
+         if (retry)
+         {
+            /* Reschedule this task after all existing tasks to allow the
+            current load tasks which are conflicting to complete.
+            */
+            try
+            {
+               // Reschedule and update the loadTask.threadTaskCount
+               scheduleTask(loadTask, threadTask.getLoader(), true);
+            }
+            catch (Throwable ex)
+            {
+               loadTask.setLoadError(ex);
+               log.warn("Failed to reschedule task after CCE", ex);
+            }
+            if (trace)
+               log.trace("Post CCE state, loadTask=" + loadTask);
+         }
+         else
+         {
+            loadTask.setLoadError(e);
+         }
+      }
+      finally
+      {
+         // Release any lock on the classloader
+         if (threadTask.isReleaseInNextTask())
+            threadTask.getClassLoader().unlock();
+      }
+
+      // If the ThreadTasks are complete mark the ClassLoadingTask finished
+      if (loadTask.getThreadTaskCount() == 0)
+      {
+         List<ThreadTask> loadTaskThreadTasks = loadTasksByThread.get(loadTask.getRequestingThread());
+         synchronized (loadTaskThreadTasks)
+         {
+            if( trace )
+               log.trace("Notifying task of thread completion, loadTask:"+loadTask);
+            task.finish();
+            loadTaskThreadTasks.notify();
+         }
+      }
+      if (trace)
+         log.trace("End nextTask(" + taskList.size()+ "), loadTask=" + loadTask);
+   }
+
+   /** 
+    * Invoked to create a ThreadTask to assign a thread to the task of
+    * loading the class of ClassLoadingTask.
+    *
+    * @param task the classloading task
+    * @param loader the loader
+    * @param reschedule a boolean indicating if this task is being rescheduled with another classloader
+    */
+   static void scheduleTask(ClassLoadingTask task, Loader loader, boolean reschedule)
+   {
+      boolean trace = log.isTraceEnabled();
+      if (trace)
+         log.trace("ScheduleTask task=" + task + " loader=" + loader + " reschedule=" + reschedule);
+      
+      Thread thread = null;
+      boolean releaseInNextTask = false;
+      ThreadTask subtask = null;
+      List<ThreadTask> taskList = null;
+
+      BaseClassLoader classLoader = null;
+      if (loader instanceof BaseDelegateLoader)
+      {
+         BaseDelegateLoader delegateLoader = (BaseDelegateLoader) loader;
+         BaseClassLoaderPolicy policy = delegateLoader.getPolicy();
+         classLoader = policy.getClassLoader();
+      }
+      
+      synchronized (loadClassThreads)
+      {
+         // Find the thread that owns the classloader
+         if (classLoader == null)
+         {
+            thread = task.getRequestingThread();
+            synchronized (loadTasksByThread)
+            {
+               List<ThreadTask> list = loadTasksByThread.get(thread);
+               if (list == null)
+               {
+                  list = Collections.synchronizedList(new LinkedList<ThreadTask>());
+                  loadTasksByThread.put(thread, list);
+                  if (trace)
+                     log.trace("Created new task list for " + thread);
+               }
+            }
+         }
+         else
+         {
+            thread = loadClassThreads.get(classLoader);
+         }
+         
+         if (thread == null)
+         {
+            Thread currentThread = Thread.currentThread();
+            boolean interrupted = currentThread.interrupted();
+            int waits = 0;
+            
+            try
+            {
+               // No thread, try to get the lock ourselves
+               while (thread == null)
+               {
+                  try
+                  {
+                     boolean gotLock = classLoader.attemptLock();
+                     if (gotLock == false)
+                     {
+                        // REVIEW: If we've been spinning for more than a minute then there is probably something wrong? 
+                        if (waits++ == 6)
+                           throw new IllegalStateException("Waiting too long to get the registration lock for classLoader " + classLoader);
+                        // Wait 10 seconds
+                        if (trace)
+                           log.trace(classLoader + " waiting for lock");
+                        loadClassThreads.wait(10000);
+                     }
+                     else
+                     {
+                        releaseInNextTask = true;
+                     }
+                  }
+                  catch (InterruptedException ignored)
+                  {
+                  }
+                  thread = loadClassThreads.get(classLoader);
+               }
+            }
+            finally
+            {
+               if (interrupted)
+                  currentThread.interrupt();
+            }
+         }
+
+         // Now that we have the owner thread, create and assign the task
+         subtask = task.newThreadTask(loader, thread, reschedule, releaseInNextTask);
+         // Add the task to the owning thread
+         taskList = loadTasksByThread.get(thread);
+         synchronized (taskList)
+         {
+            taskList.add(subtask);
+            taskList.notify();
+            if (trace)
+               log.trace("scheduleTask(" + taskList.size() + "), created subtask: " + subtask);
+         }
+      }
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoadingTask.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoadingTask.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/base/ClassLoadingTask.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,479 @@
+/*
+ * 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.classloader.spi.base;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+
+import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.Loader;
+import org.jboss.logging.Logger;
+
+/**
+ * ClassLoadingTask.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+class ClassLoadingTask
+{
+   /** The log */
+   protected static Logger log = Logger.getLogger(ClassLoadingTask.class);
+
+   /**
+    * TaskState.
+    */
+   enum TaskState
+   {
+      /** Found the classloader */
+      FOUND_CLASS_LOADER,
+      
+      /** Next event */
+      NEXT_EVENT,
+      
+      /** Waiting on event */
+      WAIT_EVENT,
+      
+      /** Finished */
+      FINISHED,
+   }
+
+   /** The class name */
+   private String className;
+   
+   /** The reques thread */ 
+   private Thread requestingThread;
+   
+   /** The requesting classloader */
+   private ClassLoader classLoader;
+   
+   /** The loaded class */
+   private Class<?> loadedClass;
+   
+   /** The error during the load */
+   private Throwable loadException;
+   
+   /** The number of ThreadTasks remaining */
+   private int threadTaskCount;
+
+   /** The state of the requestingThread */
+   private TaskState state;
+   
+   /** The Logger trace level flag */
+   private boolean trace = log.isTraceEnabled();
+
+   /** The number of class circularity errors */
+   private int numCCE;
+
+   /**
+    * Create a new ClassLoadingTask.
+    * 
+    * @param className the class name
+    * @param classLoader the requesting the classloader
+    * @param requestingThread the requesting thread
+    */
+   ClassLoadingTask(String className, ClassLoader classLoader, Thread requestingThread)
+   {
+      this.className = className;
+      this.requestingThread = requestingThread;
+      this.classLoader = classLoader;
+   }
+
+   /**
+    * Get the className.
+    * 
+    * @return the className.
+    */
+   String getClassName()
+   {
+      return className;
+   }
+
+   /**
+    * Get the loadedClass.
+    * 
+    * @return the loadedClass.
+    */
+   Class<?> getLoadedClass()
+   {
+      return loadedClass;
+   }
+
+   /**
+    * Get the loadException.
+    * 
+    * @return the loadException.
+    */
+   Throwable getLoadException()
+   {
+      return loadException;
+   }
+
+   /**
+    * Get the numCCE.
+    * 
+    * @return the numCCE.
+    */
+   int getNumCCE()
+   {
+      return numCCE;
+   }
+
+   /**
+    * Get the requestingThread.
+    * 
+    * @return the requestingThread.
+    */
+   Thread getRequestingThread()
+   {
+      return requestingThread;
+   }
+
+   /**
+    * Get the state.
+    * 
+    * @return the state.
+    */
+   synchronized TaskState getState()
+   {
+      return state;
+   }
+
+   /**
+    * Set the task into the finished state
+    * 
+    * @param loadedClass the loaded class
+    */
+   synchronized void finish(Class<?> loadedClass)
+   {
+      this.loadedClass = loadedClass;
+      state = TaskState.FINISHED;
+   }
+
+   /**
+    * Set the task into the found classloader state
+    */
+   synchronized void foundClassLoader()
+   {
+      state = TaskState.FOUND_CLASS_LOADER;
+   }
+
+   /**
+    * Set the task into the finished state
+    */
+   synchronized void finish()
+   {
+      state = TaskState.FINISHED;
+   }
+
+   /**
+    * Set the task into the wait on event state
+    */
+   synchronized void waitOnEvent()
+   {
+      state = TaskState.WAIT_EVENT;
+   }
+
+   /**
+    * Set the task into the next event state
+    */
+   synchronized void nextEvent()
+   {
+      state = TaskState.NEXT_EVENT;
+   }
+   
+   /**
+    * Get the threadTaskCount.
+    * 
+    * @return the threadTaskCount.
+    */
+   int getThreadTaskCount()
+   {
+      return threadTaskCount;
+   }
+
+   @Override
+   public String toString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append(getClass().getSimpleName());
+      builder.append('@').append(Integer.toHexString(System.identityHashCode(this)));
+      builder.append('{');
+      builder.append("className=").append(className);
+      builder.append(" requestingThread=").append(requestingThread);
+      builder.append(" requestingClassLoader: ").append(classLoader);
+      if (loadedClass != null)
+      {
+         builder.append(" loadedClass=");
+         ClassLoaderUtils.classToString(loadedClass, builder);
+      }
+      if (loadException != null)
+         builder.append(" loadException: ").append(loadException);
+      builder.append(" threadTaskCount: ").append(threadTaskCount);
+      builder.append(" state: ").append(state);
+      if (numCCE > 0)
+         builder.append(", #CCE: ").append(numCCE);
+      builder.append('}');
+      if( trace && loadException != null )
+      {
+         StringWriter sw = new StringWriter();
+         PrintWriter pw = new PrintWriter(sw);
+         loadException.printStackTrace(pw);
+         builder.append("loadException details:\n");
+         builder.append(sw.toString());
+      }
+      return builder.toString();
+   }
+
+   /**
+    * Creaqte a new thread task
+    * 
+    * @param loader the loader
+    * @param thread the thread
+    * @param reschedule whether this is a reschedule
+    * @param releaseInNextTask whether to release in the next task
+    * @return the thread task
+    */
+   synchronized ThreadTask newThreadTask(Loader loader, Thread thread, boolean reschedule, boolean releaseInNextTask)
+   {
+      // Only update the threadTaskCount if this is not a reschedule
+      if (reschedule == false)
+         ++threadTaskCount;
+      return new ThreadTask(loader, thread, releaseInNextTask);
+   }
+   
+   /**
+    * Set the load exception
+    * 
+    * @param t the throwable
+    */
+   synchronized void setLoadError(Throwable t)
+   {
+       --threadTaskCount;
+        if (trace)
+            log.trace("setLoadedError, error="+t);
+       loadException = t;
+   }
+   
+
+   /** 
+    * This is called from run on success or failure to mark the end
+    * of the load attempt. This must decrement the threadTaskCount or
+    * the ClassLoadingTask will never complete.
+    * 
+    * @param theClass the loaded class
+    */
+   private synchronized void setLoadedClass(Class<?> theClass)
+   {
+      --threadTaskCount;
+      if (trace)
+         log.trace("setLoadedClass, theClass=" + theClass);
+
+      // Warn about duplicate classes
+      if (this.loadedClass != null && theClass != null)
+      {
+         StringBuilder builder = new StringBuilder();
+         builder.append("Duplicate class found: ").append(className).append('\n');
+         ProtectionDomain pd = getProtectionDomain(loadedClass);
+         CodeSource cs = pd != null ? pd.getCodeSource() : null;
+         builder.append("Current CS: ").append(cs).append('\n');
+         pd = getProtectionDomain(theClass);
+         cs = pd != null ? pd.getCodeSource() : null;
+         builder.append("Duplicate CS: ").append(cs);
+         log.warn(builder.toString());
+      }
+
+      // Accept the first class
+      if (theClass != null && loadedClass == null)
+         this.loadedClass = theClass;
+   }
+
+   /** 
+    * Thread Task
+    */
+   class ThreadTask
+   {
+      /** The loader */
+      private Loader loader;
+      
+      /** The thread that owns the ucl monitor */
+      private Thread thread;
+      
+      /** Whether to release in the next task */
+      private boolean releaseInNextTask;
+
+      /**
+       * Create a new ThreadTask.
+       * 
+       * @param loader the loader
+       * @param thread the thread
+       * @param releaseInNextTask whether to release in the next task
+       */
+      ThreadTask(Loader loader, Thread thread, boolean releaseInNextTask)
+      {
+         this.loader = loader;
+         this.thread = thread;
+         this.releaseInNextTask = releaseInNextTask;
+      }
+
+      /**
+       * Get the className.
+       * 
+       * @return the className.
+       */
+      String getClassName()
+      {
+         return className;
+      }
+
+      /**
+       * Get the loadedClass.
+       * 
+       * @return the loadedClass.
+       */
+      Class<?> getLoadedClass()
+      {
+         return loadedClass;
+      }
+
+      @Override
+      public String toString()
+      {
+         StringBuilder builder = new StringBuilder();
+         builder.append("{thread=").append(thread);
+         builder.append(" loader=").append(loader);
+         builder.append(" requestingThread=").append(requestingThread);
+         builder.append(" releaseInNextTask=").append(releaseInNextTask);
+         builder.append("}");
+         return builder.toString();
+      }
+      
+      /**
+       * Get the classloading task
+       * 
+       * @return the classloading task
+       */
+      ClassLoadingTask getLoadTask()
+      {
+         return ClassLoadingTask.this;
+      }
+
+      /**
+       * Get the loader.
+       * 
+       * @return the loader.
+       */
+      Loader getLoader()
+      {
+         return loader;
+      }
+
+      /**
+       * Get the classloader for this task
+       * 
+       * @return the classloader
+       */
+      BaseClassLoader getClassLoader()
+      {
+         if (loader instanceof BaseDelegateLoader)
+         {
+            BaseDelegateLoader delegateLoader = (BaseDelegateLoader) loader;
+            return delegateLoader.getPolicy().getClassLoader();
+         }
+         return null;
+      }
+      
+      /**
+       * Get the thread.
+       * 
+       * @return the thread.
+       */
+      synchronized Thread getThread()
+      {
+         return thread;
+      }
+
+      /**
+       * Set the thread.
+       * 
+       * @param thread the thread.
+       */
+      synchronized void setThread(Thread thread)
+      {
+         this.thread = thread;
+      }
+
+      /**
+       * Get the releaseInNextTask.
+       * 
+       * @return the releaseInNextTask.
+       */
+      boolean isReleaseInNextTask()
+      {
+         return releaseInNextTask;
+      }
+
+      /**
+       * Run the class load
+       * 
+       * @throws ClassNotFoundException
+       */
+      void run() throws ClassNotFoundException
+      {
+         if (loadedClass == null)
+         {
+            Class<?> theClass = loader.loadClass(className);
+            setLoadedClass(theClass);
+         }
+         else if (trace)
+         {
+            log.trace("Already found class(" + loadedClass + "), skipping load class");
+         }
+      }
+   }
+   
+   /**
+    * Get the protected domain for a class
+    * 
+    * @param clazz the class
+    * @return the protected domain or null if it doesn't have one
+    */
+   private static final ProtectionDomain getProtectionDomain(final Class<?> clazz)
+   {
+      SecurityManager sm = System.getSecurityManager();
+      if (sm == null)
+         return clazz.getProtectionDomain();
+      
+      return AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>()
+      {
+         public ProtectionDomain run()
+         {
+            return clazz.getProtectionDomain();
+         }
+      });
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/filter/ClassFilter.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/filter/ClassFilter.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/filter/ClassFilter.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,52 @@
+/*
+ * 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.classloader.spi.filter;
+
+import org.jboss.classloader.plugins.filter.EverythingClassFilter;
+import org.jboss.classloader.plugins.filter.JavaOnlyClassFilter;
+import org.jboss.classloader.plugins.filter.NothingClassFilter;
+
+/**
+ * ClassFilter.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface ClassFilter
+{
+   /** Match evertything */
+   ClassFilter EVERYTHING = EverythingClassFilter.INSTANCE;
+
+   /** Match nothing */
+   ClassFilter NOTHING = NothingClassFilter.INSTANCE;
+
+   /** Java Only */
+   ClassFilter JAVA_ONLY = JavaOnlyClassFilter.INSTANCE;
+   
+   /** 
+    * Whether the class name matches the filter
+    * 
+    * @param className the class name
+    * @return true when it matches the filter
+    */
+   boolean matches(String className);
+}

Added: projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/filter/FilteredDelegateLoader.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/filter/FilteredDelegateLoader.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/main/org/jboss/classloader/spi/filter/FilteredDelegateLoader.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,129 @@
+/*
+ * 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.classloader.spi.filter;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Set;
+
+import org.jboss.classloader.spi.ClassLoaderPolicy;
+import org.jboss.classloader.spi.DelegateLoader;
+import org.jboss.logging.Logger;
+
+/**
+ * FilteredDelegateLoader.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class FilteredDelegateLoader extends DelegateLoader
+{
+   /** The log */
+   private static final Logger log = Logger.getLogger(FilteredDelegateLoader.class);
+   
+   /** The filter */
+   private ClassFilter filter;
+
+   /**
+    * Create a new FilteredDelegateLoader that does not filter
+    * 
+    * @param delegate the delegate classloading policy
+    * @throws IllegalArgumentException for a null parameter
+    */
+   public FilteredDelegateLoader(ClassLoaderPolicy delegate)
+   {
+      this(delegate, ClassFilter.EVERYTHING);
+   }
+
+   /**
+    * Create a new FilteredDelegateLoader.
+    * 
+    * @param delegate the delegate classloading policy
+    * @param filter the filter
+    * @throws IllegalArgumentException for a null parameter
+    */
+   public FilteredDelegateLoader(ClassLoaderPolicy delegate, ClassFilter filter)
+   {
+      super(delegate);
+      if (filter == null)
+         throw new IllegalArgumentException("Null filter");
+      this.filter = filter;
+   }
+
+   /**
+    * Get the filter.
+    * 
+    * @return the filter.
+    */
+   public ClassFilter getFilter()
+   {
+      return filter;
+   }
+
+   @Override
+   public Class<?> loadClass(String className)
+   {
+      boolean trace = log.isTraceEnabled();
+      if (filter.matches(className))
+      {
+         if (trace)
+            log.trace(this + " " + className + " matches filter=" + filter);
+         return super.loadClass(className);
+      }
+      if (trace)
+         log.trace(this + " " + className + " does NOT match filter=" + filter);
+      return null;
+   }
+
+   public URL getResource(String name, String resourceName)
+   {
+      boolean trace = log.isTraceEnabled();
+      if (filter.matches(resourceName))
+      {
+         if (trace)
+            log.trace(this + " " + name + " matches filter=" + filter);
+         return super.getResource(name, resourceName);
+      }
+      if (trace)
+         log.trace(this + " " + name + " NOT match filter=" + filter);
+      return null;
+   }
+
+   public void getResources(String name, String resourceName, Set<URL> urls) throws IOException
+   {
+      boolean trace = log.isTraceEnabled();
+      if (filter.matches(resourceName))
+      {
+         if (trace)
+            log.trace(this + " " + name + " matches filter=" + filter);
+         super.getResources(name, resourceName, urls);
+      }
+      if (trace)
+         log.trace(this + " " + name + " matches does NOT match filter=" + filter);
+   }
+
+   @Override
+   protected void toLongString(StringBuilder builder)
+   {
+      builder.append(" filter=").append(getFilter());
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/AbstractClassLoaderTest.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/AbstractClassLoaderTest.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/AbstractClassLoaderTest.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,270 @@
+/*
+ * 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;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestSuite;
+
+import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.plugins.system.DefaultClassLoaderSystem;
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderPolicy;
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.spi.ParentPolicy;
+import org.jboss.test.BaseTestCase;
+import org.jboss.test.classloader.support.MockClassLoaderPolicy;
+
+/**
+ * AbstractClassLoaderTest.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class AbstractClassLoaderTest extends BaseTestCase
+{
+   /**
+    * Create a new testsuite for the class
+    * 
+    * TODO move to BaseTestCase
+    * @param clazz the class
+    * @return the suite
+    */
+   public static TestSuite suite(Class<?> clazz)
+   {
+      return new TestSuite(clazz);
+   }
+
+   /**
+    * Raise an assertion failed error for an error
+    * 
+    * TODO move to AbstractTestCase
+    * @param reason the reason
+    * @param cause the cause
+    */
+   protected void failure(String reason, Throwable cause)
+   {
+      log.error(reason, cause);
+      if (cause instanceof AssertionFailedError)
+         throw (AssertionFailedError) cause;
+      Error error = new AssertionFailedError(reason);
+      error.initCause(cause);
+      throw error;
+   }
+   
+   public AbstractClassLoaderTest(String name)
+   {
+      super(name);
+   }
+   
+   protected ClassLoaderSystem createClassLoaderSystem()
+   {
+      // We always create a new one to avoid things in the default domain leaking across tests
+      return new DefaultClassLoaderSystem();
+   }
+   
+   protected ClassLoaderSystem createClassLoaderSystemWithModifiedBootstrap()
+   {
+      ClassLoaderSystem result = createClassLoaderSystem();
+      result.getDefaultDomain().setParentPolicy(ParentPolicy.BEFORE_BUT_JAVA_ONLY);
+      return result;
+   }
+   
+   protected ClassLoader createClassLoaderSystemWithModifiedBootstrapAndMockClassLoader()
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      return createMockClassLoader(system);
+   }
+   
+   protected ClassLoader registerPolicyWithDefaultDomain(ClassLoaderPolicy policy, ClassLoaderSystem system)
+   {
+      return system.registerClassLoaderPolicy(policy);
+   }
+   
+   protected ClassLoader createMockClassLoader(ClassLoaderSystem system)
+   {
+      return createMockClassLoader(system, "mock");
+   }
+   
+   protected ClassLoader createMockClassLoader(ClassLoaderSystem system, String name)
+   {
+      MockClassLoaderPolicy policy = new MockClassLoaderPolicy(name);
+      return system.registerClassLoaderPolicy(policy);
+   }
+   
+   protected ClassLoader createMockClassLoader(ClassLoaderSystem system, ClassLoaderDomain domain)
+   {
+      return createMockClassLoader(system, domain, "mock");
+   }
+   
+   protected ClassLoader createMockClassLoader(ClassLoaderSystem system, ClassLoaderDomain domain, String name)
+   {
+      MockClassLoaderPolicy policy = new MockClassLoaderPolicy(name);
+      return system.registerClassLoaderPolicy(domain, policy);
+   }
+   
+   protected void assertClassEquality(Class<?> expected, Class<?> actual)
+   {
+      assertTrue("Should be the same " + ClassLoaderUtils.classToString(expected) +" and " + ClassLoaderUtils.classToString(actual), expected == actual);
+   }
+   
+   protected void assertNoClassEquality(Class<?> expected, Class<?> actual)
+   {
+      assertTrue("Should NOT be the same " + ClassLoaderUtils.classToString(expected) +" and " + ClassLoaderUtils.classToString(actual), expected != actual);
+   }
+   
+   protected void assertClassLoader(Class<?> clazz, ClassLoader expected)
+   {
+      log.debug("Should be the expected classloader expected=" + expected + " actual=" + clazz.getClassLoader());
+      assertEquals("Should be the expected classloader", expected, clazz.getClassLoader());
+   }
+   
+   protected Class<?> assertLoadClass(Class<?> reference, ClassLoader start)
+   {
+      return assertLoadClass(reference, start, start, false);
+   }
+   
+   protected Class<?> assertLoadClass(Class<?> reference, ClassLoader start, boolean isReference)
+   {
+      return assertLoadClass(reference, start, start, isReference);
+   }
+   
+   protected Class<?> assertLoadClass(Class<?> reference, ClassLoader start, ClassLoader expected)
+   {
+      return assertLoadClass(reference, start, expected, false);
+   }
+   
+   protected Class<?> assertLoadClass(Class<?> reference, ClassLoader start, ClassLoader expected, boolean isReference)
+   {
+      Class<?> result = assertLoadClass(reference.getName(), start, expected);
+      if (isReference)
+         assertClassEquality(reference, result);
+      else
+         assertNoClassEquality(reference, result);
+      return result;
+   }
+   
+   protected Class<?> assertLoadClass(String name, ClassLoader start)
+   {
+      return assertLoadClass(name, start, start);
+   }
+   
+   protected Class<?> assertLoadClass(String name, ClassLoader start, ClassLoader expected)
+   {
+      Class<?> result = null;
+      try
+      {
+         result = start.loadClass(name);
+         log.debug("Got class: " + ClassLoaderUtils.classToString(result) + " for " + name + " from " + start);
+      }
+      catch (ClassNotFoundException e)
+      {
+         failure("Did not expect CNFE for " + name + " from " + start, e);
+      }
+      assertClassLoader(result, expected);
+      return result;
+   }
+   
+   protected void assertLoadClassFail(Class<?> reference, ClassLoader start)
+   {
+      assertLoadClassFail(reference.getName(), start);
+   }
+      
+   protected void assertLoadClassFail(String name, ClassLoader start)
+   {
+      try
+      {
+         start.loadClass(name);
+      }
+      catch (Exception expected)
+      {
+         checkThrowable(ClassNotFoundException.class, expected);
+      }
+   }
+   
+   protected Class<?> assertClassForName(Class<?> reference, ClassLoader start)
+   {
+      return assertClassForName(reference, start, start, false);
+   }
+   
+   protected Class<?> assertClassForName(Class<?> reference, ClassLoader start, boolean isReference)
+   {
+      return assertClassForName(reference, start, start, isReference);
+   }
+   
+   protected Class<?> assertClassForName(Class<?> reference, ClassLoader start, ClassLoader expected)
+   {
+      return assertClassForName(reference, start, expected, false);
+   }
+   
+   protected Class<?> assertClassForName(Class<?> reference, ClassLoader start, ClassLoader expected, boolean isReference)
+   {
+      Class<?> result = assertClassForName(reference.getName(), start, expected);
+      if (isReference)
+         assertClassEquality(reference, result);
+      else
+         assertNoClassEquality(reference, result);
+      return result;
+   }
+   
+   protected Class<?> assertClassForName(String name, ClassLoader start)
+   {
+      return assertLoadClass(name, start, start);
+   }
+   
+   protected Class<?> assertClassForName(String name, ClassLoader start, ClassLoader expected)
+   {
+      Class<?> result = null;
+      try
+      {
+         result = Class.forName(name, true, start);
+         log.debug("Got class: " + ClassLoaderUtils.classToString(result) + " for " + name + " from " + start);
+      }
+      catch (ClassNotFoundException e)
+      {
+         failure("Did not expect CNFE for " + name + " from " + start, e);
+      }
+      assertClassLoader(result, expected);
+      return result;
+   }
+   
+   protected void assertClassForNameFail(Class<?> reference, ClassLoader start)
+   {
+      assertClassForNameFail(reference.getName(), start);
+   }
+      
+   protected void assertClassForNameFail(String name, ClassLoader start)
+   {
+      try
+      {
+         Class.forName(name, true, start);
+      }
+      catch (Exception expected)
+      {
+         checkThrowable(ClassNotFoundException.class, expected);
+      }
+   }
+   
+   protected void configureLogging()
+   {
+      //enableTrace("org.jboss.classloader");
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/ClassLoaderAllTestSuite.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/ClassLoaderAllTestSuite.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/ClassLoaderAllTestSuite.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,67 @@
+/*
+ * 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;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import org.jboss.test.classloader.bootstrap.BootstrapTestSuite;
+import org.jboss.test.classloader.delegate.test.DelegateUnitTestCase;
+import org.jboss.test.classloader.old.OldTestSuite;
+import org.jboss.test.classloader.system.ClassLoadingSystemTestSuite;
+
+/**
+ * ClassLoader All Test Suite.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 37459 $
+ */
+public class ClassLoaderAllTestSuite 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("ClassLoader All Tests");
+
+      suite.addTest(ClassLoadingSystemTestSuite.suite());
+      suite.addTest(BootstrapTestSuite.suite());
+      suite.addTest(DelegateUnitTestCase.suite());
+      suite.addTest(OldTestSuite.suite());
+      
+      return suite;
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/TestThread.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/TestThread.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/TestThread.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+import java.lang.Thread.UncaughtExceptionHandler;
+
+import junit.framework.AssertionFailedError;
+
+import org.jboss.logging.Logger;
+
+/**
+ * TestThread.
+ * 
+ * TODO move to the test project
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestThread extends Thread implements UncaughtExceptionHandler
+{
+   private Logger log = Logger.getLogger(TestThread.class);
+   
+   private Throwable t;
+
+   public TestThread()
+   {
+      setUncaughtExceptionHandler(this);
+   }
+
+   public TestThread(String name)
+   {
+      super(name);
+      setUncaughtExceptionHandler(this);
+   }
+
+   public void uncaughtException(Thread t, Throwable e)
+   {
+      log.error("Error in thread " + t, e);
+      this.t = e;
+   }
+   
+   public void doJoin() throws InterruptedException
+   {
+      super.join();
+      if (t != null)
+      {
+         if (t instanceof AssertionFailedError)
+            throw (AssertionFailedError) t;
+         AssertionFailedError e = new AssertionFailedError("Error in thread" + t);
+         e.initCause(t);
+         throw e;
+      }
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/bootstrap/BootstrapTestSuite.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/bootstrap/BootstrapTestSuite.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/bootstrap/BootstrapTestSuite.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -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.bootstrap;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import org.jboss.test.classloader.bootstrap.test.ModifiedBootstrapUnitTestCase;
+
+/**
+ * Bootstrap Test Suite.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 37459 $
+ */
+public class BootstrapTestSuite 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("Bootstrap Tests");
+
+      suite.addTest(ModifiedBootstrapUnitTestCase.suite());
+      
+      return suite;
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/bootstrap/test/ModifiedBootstrapUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/bootstrap/test/ModifiedBootstrapUnitTestCase.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/bootstrap/test/ModifiedBootstrapUnitTestCase.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,82 @@
+/*
+ * 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.bootstrap.test;
+
+import java.util.List;
+
+import javax.naming.Context;
+
+import junit.framework.TestSuite;
+
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.test.classloader.AbstractClassLoaderTest;
+
+/**
+ * ModifiedBootstrapUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ModifiedBootstrapUnitTestCase extends AbstractClassLoaderTest
+{
+   public static TestSuite suite()
+   {
+      return suite(ModifiedBootstrapUnitTestCase.class);
+   }
+
+   public ModifiedBootstrapUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   public void testJavaLangObject() throws Exception
+   {
+      testBootstrapClass(Object.class);
+   }
+   
+   public void testJavaUtilList() throws Exception
+   {
+      testBootstrapClass(List.class);
+   }
+   
+   public void testJavaxNamingContext() throws Exception
+   {
+      testBootstrapClass(Context.class);
+   }
+   
+   public void testClassLoaderDomain() throws Exception
+   {
+      testNotBootstrapClass(ClassLoaderDomain.class);
+   }
+   
+   protected void testBootstrapClass(Class<?> clazz) throws Exception
+   {
+      ClassLoader classLoader = createClassLoaderSystemWithModifiedBootstrapAndMockClassLoader();
+      assertLoadClass(clazz, classLoader, clazz.getClassLoader(), true);
+   }
+   
+   protected void testNotBootstrapClass(Class<?> clazz) throws Exception
+   {
+      ClassLoader classLoader = createClassLoaderSystemWithModifiedBootstrapAndMockClassLoader();
+      assertLoadClassFail(clazz, classLoader);
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/DelegateTestSuite.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/DelegateTestSuite.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/DelegateTestSuite.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -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.delegate;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import org.jboss.test.classloader.delegate.test.DelegateUnitTestCase;
+
+/**
+ * Delegate Test Suite.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 37459 $
+ */
+public class DelegateTestSuite 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("Delegate Tests");
+
+      suite.addTest(DelegateUnitTestCase.suite());
+      
+      return suite;
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/TestA1.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/TestA1.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/TestA1.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,33 @@
+/*
+ * 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.delegate.support.a;
+
+/**
+ * TestA1.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestA1
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/TestAbstractFactory.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/TestAbstractFactory.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/TestAbstractFactory.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,62 @@
+/*
+ * 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.delegate.support.a;
+
+import org.jboss.test.classloader.delegate.support.b.TestFactoryImplementation;
+
+/**
+ * TestAbstractFactory.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestAbstractFactory
+{
+   private static TestAbstractFactory instance;
+   
+   static
+   {
+      long sleep = TestSleep.sleep;
+      if (sleep != 0)
+      {
+         try
+         {
+            Thread.sleep(sleep);
+         }
+         catch (InterruptedException e)
+         {
+            throw new Error("Interrupted");
+         }
+      }
+      init();
+   }
+
+   public static void init()
+   {
+      instance = new TestFactoryImplementation();
+   }
+   
+   public static TestAbstractFactory getInstance()
+   {
+      return instance;
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/TestSleep.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/TestSleep.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/a/TestSleep.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,33 @@
+/*
+ * 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.delegate.support.a;
+
+/**
+ * TestSleep.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestSleep
+{
+   public static long sleep = 0;
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/b/TestB1.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/b/TestB1.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/b/TestB1.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,33 @@
+/*
+ * 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.delegate.support.b;
+
+/**
+ * TestB1.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestB1
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/b/TestFactoryImplementation.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/b/TestFactoryImplementation.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/support/b/TestFactoryImplementation.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,34 @@
+/*
+ * 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.delegate.support.b;
+
+import org.jboss.test.classloader.delegate.support.a.TestAbstractFactory;
+
+/**
+ * TestFactoryImplementation.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TestFactoryImplementation extends TestAbstractFactory
+{
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/test/DelegateUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/test/DelegateUnitTestCase.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/test/DelegateUnitTestCase.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,227 @@
+/*
+ * 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.delegate.test;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+import junit.framework.TestSuite;
+
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.spi.DelegateLoader;
+import org.jboss.classloader.spi.filter.FilteredDelegateLoader;
+import org.jboss.test.classloader.AbstractClassLoaderTest;
+import org.jboss.test.classloader.TestThread;
+import org.jboss.test.classloader.delegate.support.a.TestA1;
+import org.jboss.test.classloader.delegate.support.a.TestAbstractFactory;
+import org.jboss.test.classloader.delegate.support.a.TestSleep;
+import org.jboss.test.classloader.delegate.support.b.TestB1;
+import org.jboss.test.classloader.delegate.support.b.TestFactoryImplementation;
+import org.jboss.test.classloader.support.MockClassLoaderPolicy;
+
+/**
+ * ModifiedBootstrapUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class DelegateUnitTestCase extends AbstractClassLoaderTest
+{
+   public static TestSuite suite()
+   {
+      return suite(DelegateUnitTestCase.class);
+   }
+
+   public DelegateUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   public void testNoDelegateAToB() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy pb = new MockClassLoaderPolicy("B");
+      pb.setPaths(TestB1.class);
+      ClassLoader b = system.registerClassLoaderPolicy(pb);
+
+      MockClassLoaderPolicy pa = new MockClassLoaderPolicy("A");
+      pa.setPaths(TestA1.class);
+      ClassLoader a = system.registerClassLoaderPolicy(pa);
+      
+      assertLoadClass(TestB1.class, b, false);
+      assertLoadClassFail(TestB1.class, a);
+   }
+   
+   public void testDelegateAToB() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy pb = new MockClassLoaderPolicy("B");
+      pb.setPaths(TestB1.class);
+      ClassLoader b = system.registerClassLoaderPolicy(pb);
+
+      MockClassLoaderPolicy pa = new MockClassLoaderPolicy("A");
+      pa.setPaths(TestA1.class);
+      pa.setDelegates(Collections.singletonList(new FilteredDelegateLoader(pb)));
+      ClassLoader a = system.registerClassLoaderPolicy(pa);
+      
+      Class<?> fromB = assertLoadClass(TestB1.class, b, false);
+      Class<?> fromA = assertLoadClass(TestB1.class, a, b, false);
+      
+      assertClassEquality(fromB, fromA);
+   }
+   
+   public void testAbstractFactoryObviousWay() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      
+      MockClassLoaderPolicy pb = new MockClassLoaderPolicy("B");
+      pb.setPaths(TestB1.class);
+
+      MockClassLoaderPolicy pa = new MockClassLoaderPolicy("A");
+      pa.setPaths(TestA1.class);
+
+      List<DelegateLoader> delegates = new ArrayList<DelegateLoader>();
+      delegates.add(new FilteredDelegateLoader(pa));
+      delegates.add(new FilteredDelegateLoader(pb));
+      pa.setDelegates(delegates);
+      pb.setDelegates(delegates);
+
+      ClassLoader a = system.registerClassLoaderPolicy(pa);
+      ClassLoader b = system.registerClassLoaderPolicy(pb);
+      
+      Class<?> testAbstractFactoryClass = assertLoadClass(TestAbstractFactory.class, a);
+      Method method = testAbstractFactoryClass.getMethod("getInstance", null);
+      Object instance = method.invoke(null, null);
+      Class<?> testFactoryImplementationClass = assertLoadClass(TestFactoryImplementation.class, b);
+      assertClassEquality(testFactoryImplementationClass, instance.getClass());
+   }
+   
+   public void testAbstractFactoryWrongWay() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      
+      MockClassLoaderPolicy pb = new MockClassLoaderPolicy("B");
+      pb.setPaths(TestB1.class);
+
+      MockClassLoaderPolicy pa = new MockClassLoaderPolicy("A");
+      pa.setPaths(TestA1.class);
+
+      List<DelegateLoader> delegates = new ArrayList<DelegateLoader>();
+      delegates.add(new FilteredDelegateLoader(pa));
+      delegates.add(new FilteredDelegateLoader(pb));
+      pa.setDelegates(delegates);
+      pb.setDelegates(delegates);
+
+      ClassLoader a = system.registerClassLoaderPolicy(pa);
+      ClassLoader b = system.registerClassLoaderPolicy(pb);
+      
+      Class<?> testAbstractFactoryClass = assertLoadClass(TestAbstractFactory.class, b, a);
+      Method method = testAbstractFactoryClass.getMethod("getInstance", null);
+      Object instance = method.invoke(null, null);
+      Class<?> testFactoryImplementationClass = assertLoadClass(TestFactoryImplementation.class, a, b);
+      assertClassEquality(testFactoryImplementationClass, instance.getClass());
+   }
+   
+   public void testAbstractFactoryConcurrent() throws Exception
+   {
+      for (int i = 0; i < 10; ++i)
+      {
+         log.debug("Attempt: " + i);
+         ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+         
+         MockClassLoaderPolicy pb = new MockClassLoaderPolicy("B");
+         pb.setPaths(TestB1.class);
+
+         MockClassLoaderPolicy pa = new MockClassLoaderPolicy("A");
+         pa.setPaths(TestA1.class);
+
+         List<DelegateLoader> delegates = new ArrayList<DelegateLoader>();
+         delegates.add(new FilteredDelegateLoader(pa));
+         delegates.add(new FilteredDelegateLoader(pb));
+         pa.setDelegates(delegates);
+         pb.setDelegates(delegates);
+
+         final ClassLoader a = system.registerClassLoaderPolicy(pa);
+         final ClassLoader b = system.registerClassLoaderPolicy(pb);
+         
+         Class<?> testSleep = assertLoadClass(TestSleep.class, a);
+         Field field = testSleep.getField("sleep");
+         field.set(null, new Long(1));
+         
+         final CountDownLatch startALatch = new CountDownLatch(1);
+         final CountDownLatch startBLatch = new CountDownLatch(1);
+         
+         TestThread threadA = new TestThread("A")
+         {
+            public void run()
+            {
+               try
+               {
+                  startBLatch.await();
+               }
+               catch (InterruptedException ignored)
+               {
+               }
+               startALatch.countDown();
+               Class<?> testAbstractFactoryClass = assertLoadClass(TestAbstractFactory.class, a);
+               try
+               {
+                  Method method = testAbstractFactoryClass.getMethod("getInstance", null);
+                  method.invoke(null, null);
+               }
+               catch (Exception e)
+               {
+                  throw new Error("Error", e);
+               }
+            }
+         };
+         
+         TestThread threadB = new TestThread("B")
+         {
+            public void run()
+            {
+               startBLatch.countDown();
+               try
+               {
+                  startALatch.await();
+               }
+               catch (InterruptedException ignored)
+               {
+               }
+               assertLoadClass(TestFactoryImplementation.class, b);
+            }
+         };
+         
+         threadA.start();
+         threadB.start();
+         
+         threadA.doJoin();
+         threadB.doJoin();
+      }
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/OldTestSuite.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/OldTestSuite.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/OldTestSuite.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,67 @@
+/*
+ * 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.old;
+
+import org.jboss.test.classloader.old.test.CircularLoadUnitTestCase;
+import org.jboss.test.classloader.old.test.CircularityErrorUnitTestCase;
+import org.jboss.test.classloader.old.test.ConcurrentLoaderUnitTestCase;
+import org.jboss.test.classloader.old.test.LoaderUnitTestCase;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+/**
+ * Old Test Suite.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 37459 $
+ */
+public class OldTestSuite 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("OldTests");
+
+      suite.addTest(CircularityErrorUnitTestCase.suite());
+      suite.addTest(CircularLoadUnitTestCase.suite());
+      suite.addTest(ConcurrentLoaderUnitTestCase.suite());
+      suite.addTest(LoaderUnitTestCase.suite());
+      
+      return suite;
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass0.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass0.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass0.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,34 @@
+/*
+ * 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.old.support;
+
+/**
+ * AnyClass.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author  <a href="mailto:sacha.labourey at cogito-info.ch">Sacha Labourey</a>.
+ * @version $Revision: 1.1 $
+ */
+public class AnyClass0
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass1.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass1.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass1.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,34 @@
+/*
+ * 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.old.support;
+
+/**
+ * AnyClass.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author  <a href="mailto:sacha.labourey at cogito-info.ch">Sacha Labourey</a>.
+ * @version $Revision: 1.1 $
+ */
+public class AnyClass1
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass2.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass2.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass2.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,34 @@
+/*
+ * 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.old.support;
+
+/**
+ * AnyClass.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author  <a href="mailto:sacha.labourey at cogito-info.ch">Sacha Labourey</a>.
+ * @version $Revision: 1.1 $
+ */
+public class AnyClass2
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass3.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass3.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass3.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,34 @@
+/*
+ * 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.old.support;
+
+/**
+ * AnyClass.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author  <a href="mailto:sacha.labourey at cogito-info.ch">Sacha Labourey</a>.
+ * @version $Revision: 1.1 $
+ */
+public class AnyClass3
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass4.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass4.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass4.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,34 @@
+/*
+ * 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.old.support;
+
+/**
+ * AnyClass.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author  <a href="mailto:sacha.labourey at cogito-info.ch">Sacha Labourey</a>.
+ * @version $Revision: 1.1 $
+ */
+public class AnyClass4
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass5.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass5.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass5.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,34 @@
+/*
+ * 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.old.support;
+
+/**
+ * AnyClass.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author  <a href="mailto:sacha.labourey at cogito-info.ch">Sacha Labourey</a>.
+ * @version $Revision: 1.1 $
+ */
+public class AnyClass5
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass6.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass6.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass6.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,34 @@
+/*
+ * 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.old.support;
+
+/**
+ * AnyClass.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author  <a href="mailto:sacha.labourey at cogito-info.ch">Sacha Labourey</a>.
+ * @version $Revision: 1.1 $
+ */
+public class AnyClass6
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass7.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass7.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass7.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,34 @@
+/*
+ * 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.old.support;
+
+/**
+ * AnyClass.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author  <a href="mailto:sacha.labourey at cogito-info.ch">Sacha Labourey</a>.
+ * @version $Revision: 1.1 $
+ */
+public class AnyClass7
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass8.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass8.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass8.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,34 @@
+/*
+ * 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.old.support;
+
+/**
+ * AnyClass.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author  <a href="mailto:sacha.labourey at cogito-info.ch">Sacha Labourey</a>.
+ * @version $Revision: 1.1 $
+ */
+public class AnyClass8
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass9.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass9.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/AnyClass9.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,34 @@
+/*
+ * 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.old.support;
+
+/**
+ * AnyClass.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author  <a href="mailto:sacha.labourey at cogito-info.ch">Sacha Labourey</a>.
+ * @version $Revision: 1.1 $
+ */
+public class AnyClass9
+{
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Base.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Base.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Base.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,41 @@
+/*
+ * 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.old.support;
+
+/**
+ * Base.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class Base
+{
+   public static void run() throws Exception
+   {
+      System.out.println("Base.CS: "+Base.class.getProtectionDomain().getCodeSource());
+      Class2 o2 = new Class2();
+      System.out.println("o2.CS: "+o2.getClass().getProtectionDomain().getCodeSource());
+      Class0 o0 = o2.get0();
+      System.out.println("o0.CS: "+o0.getClass().getProtectionDomain().getCodeSource());
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Class0.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Class0.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Class0.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,37 @@
+/*
+ * 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.old.support;
+
+/**
+ * Class0.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class Class0
+{
+   /** Creates a new instance of Class0 */
+   public Class0()
+   {
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Class1.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Class1.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Class1.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,36 @@
+/*
+ * 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.old.support;
+
+/**
+ * Class1.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class Class1
+{
+   public Class1()
+   {
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Class2.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Class2.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Class2.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,42 @@
+/*
+ * 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.old.support;
+
+/**
+ * Class2.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class Class2
+{
+   /** Creates a new instance of Class0 */
+   public Class2()
+   {
+   }
+   
+   public Class0 get0()
+   {
+      return new Class0();
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Derived.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Derived.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Derived.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,33 @@
+/*
+ * 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.old.support;
+
+/**
+ * Derived.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class Derived extends Base
+{
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/LoginInfo.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/LoginInfo.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/LoginInfo.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,41 @@
+/*
+ * 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.old.support;
+
+/**
+ * LoginInfo.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class LoginInfo
+{
+   protected String username = "jduke";
+   protected char[] password = "theduke".toCharArray();
+
+   public LoginInfo(String username, char[] password)
+   {
+      this.username = username;
+      this.password = password;
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Support.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Support.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/Support.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,39 @@
+/*
+ * 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.old.support;
+
+/**
+ * Support.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class Support
+{
+   private Base base = new Base();
+
+   public Base getBase()
+   {
+      return base;
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UserOfBase.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UserOfBase.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UserOfBase.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,44 @@
+/*
+ * 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.old.support;
+
+/**
+ * UserOfBase.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class UserOfBase
+{
+   public void testBase(Support s)
+   {
+      // System.out.println("testBase.Base.class.CS: "
+      //  + Base.class.getProtectionDomain().getCodeSource());
+      // Base^L0 = Base^L1
+      Base b = s.getBase();
+      System.out.println("testBase.Base.CS: "
+         + b.getClass().getProtectionDomain().getCodeSource());
+      System.out.println("testBase.Support.CS: "
+         + s.getClass().getProtectionDomain().getCodeSource());
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UserOfLoginInfo.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UserOfLoginInfo.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UserOfLoginInfo.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,39 @@
+/*
+ * 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.old.support;
+
+/**
+ * UserOfLoginInfo.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class UserOfLoginInfo
+{
+   LoginInfo info;
+
+   public UserOfLoginInfo(String username, String password)
+   {
+      info = new LoginInfo(username, password.toCharArray());
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UserOfUsrMgr.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UserOfUsrMgr.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UserOfUsrMgr.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,44 @@
+/*
+ * 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.old.support;
+
+/**
+ * UserOfUsrMgr.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class UserOfUsrMgr
+{
+   LoginInfo info;
+
+   public UserOfUsrMgr(String username, String password)
+   {
+      info = new LoginInfo(username, password.toCharArray());
+   }
+
+   public void changePassword(char[] password)
+   {
+      UsrMgr.changeUserPassword(info, password);
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UsrMgr.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UsrMgr.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/support/UsrMgr.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,37 @@
+/*
+ * 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.old.support;
+
+/**
+ * UsrMgr.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class UsrMgr
+{
+   public static void changeUserPassword(LoginInfo info, char[] password)
+   {
+      info.password = password;
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/CircularLoadUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/CircularLoadUnitTestCase.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/CircularLoadUnitTestCase.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,329 @@
+/*
+ * 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.old.test;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import junit.framework.TestSuite;
+
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.test.classloader.AbstractClassLoaderTest;
+import org.jboss.test.classloader.old.support.Base;
+import org.jboss.test.classloader.old.support.Class0;
+import org.jboss.test.classloader.old.support.Class1;
+import org.jboss.test.classloader.old.support.Class2;
+import org.jboss.test.classloader.old.support.Derived;
+import org.jboss.test.classloader.old.support.LoginInfo;
+import org.jboss.test.classloader.old.support.Support;
+import org.jboss.test.classloader.old.support.UserOfBase;
+import org.jboss.test.classloader.old.support.UserOfLoginInfo;
+import org.jboss.test.classloader.old.support.UserOfUsrMgr;
+import org.jboss.test.classloader.old.support.UsrMgr;
+import org.jboss.test.classloader.support.MockClassLoaderPolicy;
+
+/**
+ * ClassLoadingSystemUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author Simone.Bordet at hp.com
+ * @author Scott.Stark at jboss.org
+ * @version $Revision: 1.1 $
+ */
+public class CircularLoadUnitTestCase extends AbstractClassLoaderTest
+{
+   public static TestSuite suite()
+   {
+      return suite(CircularLoadUnitTestCase.class);
+   }
+
+   public CircularLoadUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+   public void testLinkageError() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy le0 = new MockClassLoaderPolicy("le0");
+      le0.setPathsAndPackageNames(Base.class);
+      le0.setImportAll(true);
+      le0.setIncluded(Base.class, UserOfBase.class);
+      ClassLoader cl0 = system.registerClassLoaderPolicy(le0);
+
+      MockClassLoaderPolicy le1 = new MockClassLoaderPolicy("le1");
+      le1.setPathsAndPackageNames(Base.class);
+      le1.setImportAll(true);
+      le1.setIncluded(Base.class, Support.class);
+      ClassLoader cl1 = system.registerClassLoaderPolicy(le1);
+
+      MockClassLoaderPolicy all = new MockClassLoaderPolicy("all");
+      all.setPackageNames(Base.class);
+      all.setImportAll(true);
+      ClassLoader cl2 = system.registerClassLoaderPolicy(all);
+      
+      try
+      {
+         // Load Base
+         assertLoadClass(Base.class, cl2, cl0);
+
+         // Load and create an instance of the UserOfBase class
+         Class<?> userOfBaseClass = assertLoadClass(UserOfBase.class, cl0);
+         Constructor ctor0 = userOfBaseClass.getConstructor(null);
+         Object userOfBase = ctor0.newInstance(null);
+
+         // Load and create an instance of the Support class
+         Class<?> supportClass = assertLoadClass(Support.class, cl1);
+         Constructor ctor1 = supportClass.getConstructor(null);
+         Object support = ctor1.newInstance(null);
+
+         // Now invoke UserOfBase.testBase(Support)
+         Class[] sig = { supportClass };
+         Method testBase = userOfBaseClass.getMethod("testBase", sig);
+         log.info(testBase.toString());
+         Object[] args = { support };
+         testBase.invoke(userOfBase, args);
+      }
+      catch(Throwable t)
+      {
+         failure("Failed", t);
+      }
+   }
+   public void testPackageProtected() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy mock = new MockClassLoaderPolicy();
+      mock.setPathsAndPackageNames(Base.class);
+      mock.setIncluded(LoginInfo.class, UsrMgr.class, UserOfUsrMgr.class, UserOfLoginInfo.class);
+      ClassLoader cl = system.registerClassLoaderPolicy(mock);
+
+      log.info("Begin testPackageProtected");
+
+      try
+      {
+         // Load and create an instance of the UserOfLoginInfo class
+         Class<?> c0 = assertLoadClass(UserOfLoginInfo.class, cl);
+         Class[] ctorsig0 = {String.class, String.class};
+         Constructor ctor0 = c0.getConstructor(ctorsig0);
+         Object[] args0 = {"jduke", "theduke"};
+         ctor0.newInstance(args0);
+
+         // Load and create an instance of the UserOfUsrMgr class
+         Class<?> c1 = assertLoadClass(UserOfUsrMgr.class, cl);
+         Class[] ctorsig1 = {String.class, String.class};
+         Constructor ctor1 = c1.getConstructor(ctorsig1);
+         Object[] args1 = {"jduke", "theduke"};
+         Object o1 = ctor1.newInstance(args1);
+         log.info("UserOfUsrMgr.CS: "+o1.getClass().getProtectionDomain().getCodeSource());
+
+         // Now invoke UserOfUsrMgr.changePassword(char[] password)
+         char[] password = "theduke2".toCharArray();
+         Class[] sig = {password.getClass()};
+         Method changePassword = c1.getMethod("changePassword", sig);
+         log.info(changePassword.toString());
+         Object[] args = {password};
+         changePassword.invoke(o1, args);
+      }
+      catch(Exception e)
+      {
+         failure("Failed", e);
+      }
+   }
+
+   public void testDuplicateClass() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy any0 = new MockClassLoaderPolicy("any0");
+      any0.setPathsAndPackageNames(Support.class);
+      any0.setImportAll(true);
+      any0.setIncluded(Base.class, Class0.class, Class2.class);
+      ClassLoader cl0 = system.registerClassLoaderPolicy(any0);
+      
+      MockClassLoaderPolicy any1 = new MockClassLoaderPolicy("any1");
+      any1.setPathsAndPackageNames(Support.class);
+      any1.setImportAll(true);
+      any1.setIncluded(Class0.class, Class2.class);
+      ClassLoader cl1 = system.registerClassLoaderPolicy(any1);
+
+      assertLoadClass(Class0.class, cl0);
+      assertLoadClass(Class2.class, cl1, cl0);
+      Class<?> base = assertLoadClass(Base.class, cl0);
+      Method run = base.getMethod("run", null);
+      run.invoke(null, null);
+   }
+   
+   public void testUCLOwner() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy j0 = new MockClassLoaderPolicy("j0");
+      j0.setPathsAndPackageNames(Support.class);
+      j0.setImportAll(true);
+      j0.setIncluded(Class0.class);
+      ClassLoader cl0 = system.registerClassLoaderPolicy(j0);
+
+      MockClassLoaderPolicy j1 = new MockClassLoaderPolicy("j1");
+      j1.setPathsAndPackageNames(Support.class);
+      j1.setImportAll(true);
+      j1.setIncluded(Class2.class);
+      ClassLoader cl1 = system.registerClassLoaderPolicy(j1);
+
+      // Request a class that does not exist
+      LoadThread t0 = new LoadThread(Support.class, cl0, "testUCLOwner.T0", true);
+      t0.start();
+      // Join the thread
+      t0.join(5000);
+      assertNull("T0 failed as no class should have been found, loadedClass="+t0.loadedClass, t0.loadedClass);
+      assertNotNull("T0 failed as no class should have been found, loadedClass="+t0.loadedClass, t0.loadError);
+      checkThrowable(ClassNotFoundException.class, t0.loadError);
+
+      LoadThread t1 = new LoadThread(Class2.class, cl1, "testUCLOwner.T1");
+      t1.start();
+      // Join the thread
+      t1.join(5000);
+      if (t1.loadError != null)
+         failure("T1 failed to load Class2" , t1.loadError);
+      assertNotNull("T1 failed to load Class2", t1.loadedClass);
+   }
+   
+   public void testMissingSuperClass() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy j0 = new MockClassLoaderPolicy("j0");
+      j0.setPathsAndPackageNames(Support.class);
+      j0.setImportAll(true);
+      j0.setIncluded(Class0.class);
+      ClassLoader cl0 = system.registerClassLoaderPolicy(j0);
+
+      MockClassLoaderPolicy j3 = new MockClassLoaderPolicy("j3");
+      j3.setPathsAndPackageNames(Support.class);
+      j3.setImportAll(true);
+      j3.setIncluded(Derived.class);
+      system.registerClassLoaderPolicy(j3);
+
+      LoadThread t0 = new LoadThread(Derived.class, cl0, "testMissingSuperClass.T0");
+      t0.start();
+      // Join the thread
+      t0.join(5000);
+      assertNull("T0 failed as no class should have been found, loadedClass="+t0.loadedClass, t0.loadedClass);
+      checkThrowable(NoClassDefFoundError.class, t0.loadError);
+   }
+   
+   public void testLoading() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy j0 = new MockClassLoaderPolicy("j0");
+      j0.setPathsAndPackageNames(Support.class);
+      j0.setImportAll(true);
+      j0.setIncluded(Class0.class);
+      ClassLoader cl0 = system.registerClassLoaderPolicy(j0);
+
+      MockClassLoaderPolicy j1 = new MockClassLoaderPolicy("j1");
+      j1.setPathsAndPackageNames(Support.class);
+      j1.setImportAll(true);
+      j1.setIncluded(Class1.class);
+      ClassLoader cl1 = system.registerClassLoaderPolicy(j1);
+
+      MockClassLoaderPolicy j2 = new MockClassLoaderPolicy("j2");
+      j2.setPathsAndPackageNames(Support.class);
+      j2.setImportAll(true);
+      j2.setIncluded(Class2.class);
+      ClassLoader cl2 = system.registerClassLoaderPolicy(j2);
+
+      LoadThread t0 = new LoadThread(Class2.class, cl0, cl2, "testLoading.T0");
+      LoadThread t1 = new LoadThread(Class0.class, cl1, cl0, "testLoading.T1");
+      LoadThread t2 = new LoadThread(Class1.class, cl2, cl1, "testLoading.T2");
+      t0.start();
+      t1.start();
+      t2.start();
+
+      // Join the threads
+      t0.join();
+      if (t0.loadError != null)
+         failure("T0 failed", t0.loadError);
+      assertNotNull("T0 failed", t0.loadedClass);
+
+      t1.join(5000);
+      if (t1.loadError != null)
+         failure("T1 failed", t1.loadError);
+      assertNotNull("T1 failed", t1.loadedClass);
+
+      t2.join(5000);
+      if (t2.loadError != null)
+         failure("T2 failed", t2.loadError);
+      assertNotNull("T2 failed", t2.loadedClass);
+   }
+
+   class LoadThread extends Thread
+   {
+      String classname;
+      ClassLoader loader;
+      ClassLoader expected;
+      Class loadedClass;
+      Throwable loadError;
+      boolean fails;
+
+      LoadThread(Class<?> reference, ClassLoader loader, String name)
+      {
+         this(reference, loader, loader, name, false);
+      }
+
+      LoadThread(Class<?> reference, ClassLoader loader, String name, boolean fails)
+      {
+         this(reference, loader, loader, name, fails);
+      }
+
+      LoadThread(Class<?> reference, ClassLoader loader, ClassLoader expected, String name)
+      {
+         this(reference, loader, expected, name, false);
+      }
+
+      LoadThread(Class<?> reference, ClassLoader loader, ClassLoader expected, String name, boolean fails)
+      {
+         super(name);
+         this.classname = reference.getName();
+         this.loader = loader;
+         this.expected = expected;
+         this.fails = fails;
+      }
+
+      public void run()
+      {
+         try
+         {
+            if (fails)
+               loader.loadClass(classname);
+            else
+               loadedClass = assertLoadClass(classname, loader, expected);
+         }
+         catch(Throwable t)
+         {
+            loadError = t;
+         }
+      }
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/CircularityErrorUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/CircularityErrorUnitTestCase.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/CircularityErrorUnitTestCase.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,150 @@
+/*
+ * 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.old.test;
+
+import java.net.URL;
+import java.util.concurrent.CountDownLatch;
+
+import junit.framework.TestSuite;
+
+import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.test.classloader.AbstractClassLoaderTest;
+import org.jboss.test.classloader.old.support.Derived;
+import org.jboss.test.classloader.old.support.Support;
+import org.jboss.test.classloader.support.MockClassLoaderPolicy;
+
+/**
+ * CircularityErrorUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author Simone.Bordet at hp.com
+ * @author Scott.Stark at jboss.org
+ * @version $Revision: 1.1 $
+ */
+public class CircularityErrorUnitTestCase extends AbstractClassLoaderTest
+{
+   private CountDownLatch waiting = new CountDownLatch(1);
+   private Throwable sawError;
+
+   public static TestSuite suite()
+   {
+      return suite(CircularityErrorUnitTestCase.class);
+   }
+
+   public CircularityErrorUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   public void testClassCircularityError() throws Exception
+   {
+      // The scenario is this one:
+      // Thread1 asks classloader1 to load class Derived
+      // Thread2 triggers a loadClassInternal for classloader1 to load class Base
+      // Thread2 is put in sleep by the ULR since we are loading Derived
+      // Thread1 triggers a loadClassInternal for classloader1 to load class Base
+      // Thread1 throws ClassCircularityError
+
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      final ClassLoader cl = system.registerClassLoaderPolicy(new TestClassLoaderPolicy());
+
+      Class cls = assertLoadClass(Support.class, cl);
+
+      Thread thread1 = new Thread(new Runnable()
+      {
+         public void run()
+         {
+            // Be sure thread2 is waiting
+            try 
+            {
+               Thread.sleep(1000);
+            }
+            catch (InterruptedException x) 
+            {
+            }
+            
+
+            try
+            {
+               log.debug("Thread " + Thread.currentThread() + " loading...");
+               assertLoadClass(Derived.class, cl);
+               log.debug("Thread " + Thread.currentThread() + " loading done !");
+            }
+            catch (Throwable t)
+            {
+               sawError = t;
+            }
+         }
+      }, "CircularityErrorThread");
+      thread1.start();
+
+      log.debug("Thread " + Thread.currentThread() + " waiting...");
+      waiting.await();
+      log.debug("Thread " + Thread.currentThread() + " woken up !");
+
+      // Ask this thread to trigger a loadClassInternal directly; the thread will be put to sleep
+      // but the JVM has already registered the fact that
+      // it wants to load the class, in this case class Base
+      cls.newInstance();
+      thread1.join();
+
+      // The ClassCircularityError thrown should allow the call above to complete
+      if (sawError != null)
+         failure("Unexpected error", sawError);
+   }
+
+   public class TestClassLoaderPolicy extends MockClassLoaderPolicy
+   {
+      public TestClassLoaderPolicy()
+      {
+         setPaths(Support.class);
+      }
+
+      @Override
+      public URL getResource(String name)
+      {
+         log.debug(Thread.currentThread() + " is now asked to load class: " + name);
+
+         if (name.equals(ClassLoaderUtils.classNameToPath(Derived.class.getName())))
+         {
+            waiting.countDown();
+
+            // Wait to trigger ClassCircularityError
+            // Do not release the lock on the classloader
+            try
+            {
+               log.debug("Loading " + name + ", waiting...");
+               Thread.sleep(2000);
+               log.debug("Loading " + name + " end wait");
+            }
+            catch (InterruptedException x)
+            {
+               log.debug("Sleep was interrupted", x);
+            }
+         }
+
+         return super.getResource(name);
+      }
+   }
+
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/ConcurrentLoaderUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/ConcurrentLoaderUnitTestCase.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/ConcurrentLoaderUnitTestCase.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,192 @@
+/*
+ * 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.old.test;
+
+import java.util.HashSet;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.Vector;
+
+import junit.framework.TestSuite;
+
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.test.classloader.AbstractClassLoaderTest;
+import org.jboss.test.classloader.old.support.Support;
+import org.jboss.test.classloader.support.MockClassLoaderPolicy;
+
+/**
+ * ConcurrentLoaderUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author Scott.Stark at jboss.org
+ * @version $Revision: 1.1 $
+ */
+public class ConcurrentLoaderUnitTestCase extends AbstractClassLoaderTest
+{
+   public Object lock = new Object ();
+
+   public final static int MAX_CLASSES = 10;
+   public final static int NUMBER_OF_LOADING = 10;
+   public final static int NUMBER_OF_THREADS = 20;
+   private HashSet<Class> classes = new HashSet<Class>();
+   private Vector<Loader> loaders = new Vector<Loader>();
+   private Timer newInstanceTimer;
+   private int doneCount;
+   private ClassLoader cl;
+
+   public static TestSuite suite()
+   {
+      return suite(ConcurrentLoaderUnitTestCase.class);
+   }
+
+   public ConcurrentLoaderUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   public void testConcurrentLoad() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+      
+      MockClassLoaderPolicy policy = new MockClassLoaderPolicy();
+      policy.setPaths(Support.class);
+      cl = system.registerClassLoaderPolicy(policy);
+      
+      log.debug("Creating " + NUMBER_OF_THREADS + " threads...");
+      newInstanceTimer = new Timer(true);
+      newInstanceTimer.scheduleAtFixedRate(new NewInstanceTask(), 0, 100);
+      doneCount = 0;
+      for (int t = 0; t < NUMBER_OF_THREADS; t ++)
+      {
+         Loader loader = new Loader (t);
+         loader.start();
+         loaders.add(loader);
+      }
+      log.debug("All threads created");
+      Thread.sleep(2000);
+
+      synchronized(lock)
+      {
+         lock.notifyAll ();
+      }
+      
+      log.debug("Unlocked all Loader threads");
+      
+      synchronized(lock)
+      {
+         while( doneCount < NUMBER_OF_THREADS )
+         {
+            lock.wait();
+         }
+         log.debug("Loader doneCount=" + doneCount);
+      }
+      log.debug("All Loaders are done");
+      newInstanceTimer.cancel();
+      
+      for (Loader loader : loaders)
+      {
+         if (loader.error != null)
+            failure("Error in loader: ", loader.error);
+      }
+   }
+
+   class NewInstanceTask extends TimerTask
+   {
+      public void run()
+      {
+         int size = classes.size();
+         Class[] theClasses = new Class[size];
+         classes.toArray(theClasses);
+         log.debug("NewInstanceTask, creating " + size + " instances");
+         for (int c = 0; c < theClasses.length; ++c)
+         {
+            try
+            {
+               Class clazz = theClasses[c];
+               Object obj = clazz.newInstance();
+               log.debug("Created instance=" + obj);
+            }
+            catch(Throwable t)
+            {
+               log.error("Error instantiating class " + theClasses[c], t);
+            }
+         }
+      }
+   }
+
+   class Loader extends Thread
+   {
+      int classid = 0;
+      Throwable error;
+
+      public Loader (int classid)
+      {
+         super("ConcurrentLoader - Thread #" + classid);
+         this.classid = classid;
+      }
+
+      public void run ()
+      {
+         int modId = classid % MAX_CLASSES;
+         String className = Support.class.getPackage().getName() + ".AnyClass" + modId;
+
+         synchronized(lock)
+         {
+            try
+            {
+               log.debug("Thread ready: " + classid);
+               lock.wait ();
+            }
+            catch (Exception e)
+            {
+               log.error("Error during wait", e);
+            }
+         }
+         log.debug("loading class... " + className);
+         for (int i = 0; i < NUMBER_OF_LOADING; ++i)
+         {
+            log.debug("loading class with id " + classid + " for the " + i + "th time");
+            try
+            {
+               log.debug("before load...");
+               long sleep = (long) (1000 * Math.random());
+               Thread.sleep(sleep);
+               Class clazz = cl.loadClass (className);
+               classes.add(clazz);
+               Object obj = clazz.newInstance();
+               log.debug("Class " + className + " loaded, obj=" + obj);
+            }
+            catch (Throwable e)
+            {
+               log.debug("Failed to load class and create instance", e);
+               error = e;
+            }
+         }
+         log.debug("...Done loading classes. " + classid);
+         synchronized( lock )
+         {
+            doneCount++;
+            lock.notify();
+         }
+      }
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/LoaderUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/LoaderUnitTestCase.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/old/test/LoaderUnitTestCase.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,83 @@
+/*
+ * 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.old.test;
+
+import junit.framework.TestSuite;
+
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.test.classloader.AbstractClassLoaderTest;
+import org.jboss.test.classloader.old.support.Support;
+import org.jboss.test.classloader.support.MockClassLoaderPolicy;
+
+/**
+ * LoaderUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author Scott.Stark at jboss.org
+ * @version $Revision: 1.1 $
+ */
+public class LoaderUnitTestCase extends AbstractClassLoaderTest
+{
+   public static TestSuite suite()
+   {
+      return suite(LoaderUnitTestCase.class);
+   }
+
+   public LoaderUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+   public void testInterruptThread() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy policy = new MockClassLoaderPolicy();
+      policy.setPaths(Support.class);
+      final ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      // Set our interrupted flag
+      log.debug("Setting interrupt flag");
+      Thread.currentThread().interrupt();
+      try
+      {
+         assertLoadClass(Support.class, cl);
+      }
+      finally
+      {
+         assertTrue("Interrupted state not restored", Thread.currentThread().interrupted());
+      }
+   }
+   
+   public void testLoadingArrayClass() throws Exception
+   {
+      ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+      MockClassLoaderPolicy policy = new MockClassLoaderPolicy();
+      policy.setPaths(Support.class);
+      ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+      assertLoadClass("[Ljava.lang.String;", cl, null);
+      assertLoadClass("[L" + Support.class.getName() + ";", cl);
+      assertLoadClass("[[L" + Support.class.getName() + ";", cl);
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/support/MockClassLoaderPolicy.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/support/MockClassLoaderPolicy.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/support/MockClassLoaderPolicy.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,239 @@
+/*
+ * 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.support;
+
+import java.io.IOException;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.ClassLoaderPolicy;
+import org.jboss.classloader.spi.DelegateLoader;
+
+/**
+ * MockClassLoaderPolicy.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class MockClassLoaderPolicy extends ClassLoaderPolicy
+{
+   private String name;
+   
+   private List<? extends DelegateLoader> delegates;
+   
+   private String[] paths;
+   
+   private String[] included;
+   
+   private String[] excluded;
+
+   private String[] packageNames;
+   
+   private boolean importAll;
+   
+   public MockClassLoaderPolicy()
+   {
+      this(null);
+   }
+
+   public MockClassLoaderPolicy(String name)
+   {
+      if (name == null)
+         name = "mock";
+      this.name = name;
+   }
+   
+   @Override
+   public List<? extends DelegateLoader> getDelegates()
+   {
+      return delegates;
+   }
+   
+   public void setDelegates(List<? extends DelegateLoader> delegates)
+   {
+      this.delegates = delegates;
+   }
+
+   public String[] getPaths()
+   {
+      return paths;
+   }
+   
+   public void setPath(String path)
+   {
+      setPaths(new String[] { path });
+   }
+   
+   public void setPaths(String[] paths)
+   {
+      this.paths = paths;
+   }
+   
+   public void setPaths(Class... classes)
+   {
+      if (classes == null)
+         paths = null;
+      paths = new String[classes.length];
+      for (int i = 0; i < classes.length; ++i)
+         paths[i] = ClassLoaderUtils.packageNameToPath(classes[i].getName());
+   }
+
+   @Override
+   public String[] getPackageNames()
+   {
+      return packageNames;
+   }
+   
+   public void setPackageNames(String[] packageNames)
+   {
+      this.packageNames = packageNames;
+   }
+   
+   public void setPackageNames(Class... classes)
+   {
+      if (classes == null)
+         packageNames = null;
+      packageNames = new String[classes.length];
+      for (int i = 0; i < classes.length; ++i)
+         packageNames[i] = ClassLoaderUtils.getClassPackageName(classes[i].getName());
+   }
+   
+   public void setIncluded(Class... classes)
+   {
+      if (classes == null)
+         included = null;
+      included = new String[classes.length];
+      for (int i = 0; i < classes.length; ++i)
+         included[i] = ClassLoaderUtils.classNameToPath(classes[i].getName());
+   }
+   
+   public void setExcluded(Class... classes)
+   {
+      if (classes == null)
+         excluded = null;
+      excluded = new String[classes.length];
+      for (int i = 0; i < classes.length; ++i)
+         excluded[i] = ClassLoaderUtils.classNameToPath(classes[i].getName());
+   }
+
+   public void setPathsAndPackageNames(Class... classes)
+   {
+      setPaths(classes);
+      setPackageNames(classes);
+   }
+   
+   /**
+    * Get the importAll.
+    * 
+    * @return the importAll.
+    */
+   public boolean isImportAll()
+   {
+      return importAll;
+   }
+
+   /**
+    * Set the importAll.
+    * 
+    * @param importAll the importAll.
+    */
+   public void setImportAll(boolean importAll)
+   {
+      this.importAll = importAll;
+   }
+
+   @Override
+   public URL getResource(String path)
+   {
+      if (paths == null)
+         return null;
+
+      if (excluded != null)
+      {
+         for (String excludedPath : excluded)
+         {
+            if (excludedPath.equals(path))
+               return null;
+         }
+      }
+
+      if (included != null)
+      {
+         boolean include = false;
+         for (String includedPath : included)
+         {
+            if (includedPath.equals(path))
+            {
+               include = true;
+               break;
+            }
+         }
+         if (include == false)
+            return null;
+      }
+      
+      for (int i = 0; i < paths.length; ++i)
+      {
+         if (path.startsWith(paths[i]))
+            return getClass().getClassLoader().getResource(path);
+      }
+      return null;
+   }
+
+   @Override
+   public void getResources(String name, Set<URL> urls) throws IOException
+   {
+      // TODO getResources
+      throw new org.jboss.util.NotImplementedException("getResources");
+      
+   }
+
+   @Override
+   protected ProtectionDomain getProtectionDomain(String className, String path)
+   {
+      return getClass().getProtectionDomain();
+   }
+
+   @Override 
+   public void toLongString(StringBuilder builder)
+   {
+      builder.append(" name=").append(name);
+      if (paths != null)
+         builder.append(" paths=").append(Arrays.asList(paths));
+      if (included != null)
+         builder.append(" included=").append(Arrays.asList(included));
+      if (excluded != null)
+         builder.append(" excluded=").append(Arrays.asList(excluded));
+      super.toLongString(builder);
+   }
+   
+   
+   @Override
+   public String toString()
+   {
+      return name;
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/ClassLoadingSystemTestSuite.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/ClassLoadingSystemTestSuite.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/ClassLoadingSystemTestSuite.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -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.system;
+
+import org.jboss.test.classloader.system.test.ClassLoadingSystemUnitTestCase;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+/**
+ * ClassLoadingSystem Test Suite.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 37459 $
+ */
+public class ClassLoadingSystemTestSuite 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("ClassLoading System Tests");
+
+      suite.addTest(ClassLoadingSystemUnitTestCase.suite());
+      
+      return suite;
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/support/MockClassLoaderDomain.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/support/MockClassLoaderDomain.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/support/MockClassLoaderDomain.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,55 @@
+/*
+ * 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.system.support;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderPolicy;
+
+/**
+ * MockClassLoaderDomain.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class MockClassLoaderDomain extends ClassLoaderDomain
+{
+   public List<ClassLoader> added = new CopyOnWriteArrayList<ClassLoader>();
+   public List<ClassLoader> removed = new CopyOnWriteArrayList<ClassLoader>();
+   
+   public MockClassLoaderDomain()
+   {
+      super("mock");
+   }
+   
+   protected void afterRegisterClassLoader(ClassLoader classLoader, ClassLoaderPolicy policy)
+   {
+      added.add(classLoader);
+   }
+
+   protected void afterUnregisterClassLoader(ClassLoader classLoader, ClassLoaderPolicy policy)
+   {
+      removed.add(classLoader);
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/support/MockClassLoaderSystem.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/support/MockClassLoaderSystem.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/support/MockClassLoaderSystem.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,45 @@
+/*
+ * 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.system.support;
+
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderSystem;
+
+/**
+ * MockClassLoaderSystem.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class MockClassLoaderSystem extends ClassLoaderSystem
+{
+   @Override
+   protected ClassLoaderDomain createDomain(String name)
+   {
+      return new MockClassLoaderDomain();
+   }
+
+   public MockClassLoaderDomain createAndRegisterDomain(String name)
+   {
+      return (MockClassLoaderDomain) super.createAndRegisterDomain(name);
+   }
+}

Added: projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/test/ClassLoadingSystemUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/test/ClassLoadingSystemUnitTestCase.java	                        (rev 0)
+++ projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/system/test/ClassLoadingSystemUnitTestCase.java	2007-04-27 10:28:07 UTC (rev 62605)
@@ -0,0 +1,107 @@
+/*
+ * 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.system.test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestSuite;
+
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.test.classloader.AbstractClassLoaderTest;
+import org.jboss.test.classloader.system.support.MockClassLoaderDomain;
+import org.jboss.test.classloader.system.support.MockClassLoaderSystem;
+
+/**
+ * ClassLoadingSystemUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassLoadingSystemUnitTestCase extends AbstractClassLoaderTest
+{
+   public static TestSuite suite()
+   {
+      return suite(ClassLoadingSystemUnitTestCase.class);
+   }
+
+   public ClassLoadingSystemUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   public void testGetInstance() throws Exception
+   {
+      ClassLoaderSystem instance = ClassLoaderSystem.getInstance();
+      assertNotNull(instance);
+   }
+   
+   public void testDefaultDomain() throws Exception
+   {
+      ClassLoaderDomain domain = createClassLoaderSystem().getDefaultDomain();
+      assertNotNull(domain);
+      assertEquals(ClassLoaderSystem.DEFAULT_DOMAIN_NAME, domain.getName());
+   }
+   
+   public void testRegisterExplicitDomain() throws Exception
+   {
+      MockClassLoaderSystem system = createMockClassLoaderSystem();
+      MockClassLoaderDomain domain = system.createAndRegisterDomain("mock");
+      ClassLoader cl1 = createMockClassLoader(system, domain);
+      
+      List<ClassLoader> expected = new ArrayList<ClassLoader>();
+      expected.add(cl1);
+      
+      assertEquals(expected, domain.added);
+      assertEmpty(domain.removed);
+
+      ClassLoader cl2 = createMockClassLoader(system, domain);
+      expected.add(cl2);
+      
+      assertEquals(expected, domain.added);
+      assertEmpty(domain.removed);
+   }
+   
+   public void testUnregisterExplicitDomain() throws Exception
+   {
+      MockClassLoaderSystem system = createMockClassLoaderSystem();
+      MockClassLoaderDomain domain = system.createAndRegisterDomain("mock");
+      ClassLoader cl1 = createMockClassLoader(system, domain);
+      
+      List<ClassLoader> expected = new ArrayList<ClassLoader>();
+      expected.add(cl1);
+      
+      assertEquals(expected, domain.added);
+      assertEmpty(domain.removed);
+
+      system.unregisterClassLoader(domain, cl1);
+      
+      assertEquals(expected, domain.added);
+      assertEquals(expected, domain.removed);
+   }
+   
+   protected MockClassLoaderSystem createMockClassLoaderSystem()
+   {
+      return new MockClassLoaderSystem();
+   }
+}




More information about the jboss-cvs-commits mailing list