[jboss-cvs] JBossAS SVN: r96496 - in projects/jboss-cl/trunk/classloader/src: main/java/org/jboss/classloader/spi/base and 6 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Wed Nov 18 11:54:15 EST 2009
Author: adrian at jboss.org
Date: 2009-11-18 11:54:13 -0500 (Wed, 18 Nov 2009)
New Revision: 96496
Added:
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundEvent.java
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundHandler.java
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEvent.java
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEventHandler.java
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundEvent.java
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundHandler.java
projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/
projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/ClassLoaderNotificationsTestSuite.java
projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/support/
projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/support/a/
projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/support/a/A.java
projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/
projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassFoundHandlerUnitTestCase.java
projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassLoaderEventHandlerUnitTestCase.java
projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassNotFoundHandlerUnitTestCase.java
Modified:
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomain.java
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystem.java
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoader.java
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java
projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java
projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/ClassLoaderAllTestSuite.java
projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java
Log:
[JBCL-127] [JBCL-128] - Notifications and handlers for ClassLoader create/destroy, ClassNotFound and ClassFound
Added: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundEvent.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundEvent.java (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundEvent.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -0,0 +1,87 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloader.spi;
+
+import java.util.EventObject;
+
+/**
+ * ClassFoundEvent.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassFoundEvent extends EventObject
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -8258925782380851534L;
+
+ /** The class */
+ private Class<?> clazz;
+
+ /**
+ * Create a new ClassFoundEvent.
+ *
+ * @param classLoader classLoader
+ * @param clazz the class
+ */
+ public ClassFoundEvent(ClassLoader classLoader, Class<?> clazz)
+ {
+ super(classLoader);
+ this.clazz = clazz;
+ }
+
+ /**
+ * Get the className.
+ *
+ * @return the className.
+ */
+ public String getClassName()
+ {
+ return clazz.getName();
+ }
+
+ /**
+ * Get the class.
+ *
+ * @return the class.
+ */
+ public Class<?> getClazz()
+ {
+ return clazz;
+ }
+
+ /**
+ * Get the classLoader.
+ *
+ * @return the classLoader
+ */
+ public ClassLoader getClassLoader()
+ {
+ return (ClassLoader) getSource();
+ }
+
+ @Override
+ public String toString()
+ {
+ return getClass().getSimpleName() + "[classLoader=" + getClassLoader() + " class=" + getClassName() + "]";
+ }
+}
Added: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundHandler.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundHandler.java (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassFoundHandler.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -0,0 +1,38 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloader.spi;
+
+/**
+ * ClassFoundHandler.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface ClassFoundHandler
+{
+ /**
+ * Fired when a class is found
+ *
+ * @param event the event
+ */
+ void classFound(ClassFoundEvent event);
+}
Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomain.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomain.java 2009-11-18 16:43:33 UTC (rev 96495)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderDomain.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -33,6 +33,7 @@
import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;
+import java.util.concurrent.CopyOnWriteArrayList;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
@@ -41,6 +42,7 @@
import org.jboss.classloader.plugins.ClassLoaderUtils;
import org.jboss.classloader.plugins.loader.ClassLoaderToLoaderAdapter;
import org.jboss.classloader.spi.base.BaseClassLoaderDomain;
+import org.jboss.classloader.spi.base.BaseClassLoaderSource;
import org.jboss.classloader.spi.filter.ClassFilter;
import org.jboss.classloading.spi.RealClassLoader;
import org.jboss.logging.Logger;
@@ -51,7 +53,7 @@
* @author <a href="adrian at jboss.com">Adrian Brock</a>
* @version $Revision: 1.1 $
*/
-public class ClassLoaderDomain extends BaseClassLoaderDomain implements Loader, ClassLoaderDomainMBean, MBeanRegistration
+public class ClassLoaderDomain extends BaseClassLoaderDomain implements Loader, ClassLoaderDomainMBean, MBeanRegistration, ClassNotFoundHandler, ClassFoundHandler
{
/** The log */
private static final Logger log = Logger.getLogger(ClassLoaderDomain.class);
@@ -73,6 +75,15 @@
/** Whether to use load class for the parent */
private boolean useLoadClassForParent = false;
+
+ /** The class not found handlers */
+ private List<ClassNotFoundHandler> classNotFoundHandlers;
+
+ /** The class found handlers */
+ private List<ClassFoundHandler> classFoundHandlers;
+
+ /** The class loader event handlers */
+ private List<ClassLoaderEventHandler> classLoaderEventHandlers;
/**
* Create a new ClassLoaderDomain with the {@link ParentPolicy#BEFORE} loading rules.
@@ -287,7 +298,228 @@
else
builder.append(getParentClassLoader());
}
+
+ /**
+ * Add a ClassNotFoundHandler
+ *
+ * @param handler the handler
+ */
+ public void addClassNotFoundHandler(ClassNotFoundHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classNotFoundHandlers == null)
+ classNotFoundHandlers = new CopyOnWriteArrayList<ClassNotFoundHandler>();
+
+ classNotFoundHandlers.add(handler);
+ }
+
+ /**
+ * Remove a ClassNotFoundHandler
+ *
+ * @param handler the handler
+ */
+ public void removeClassNotFoundHandler(ClassNotFoundHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classNotFoundHandlers == null)
+ return;
+ classNotFoundHandlers.remove(handler);
+ }
+ public boolean classNotFound(ClassNotFoundEvent event)
+ {
+ String className = event.getClassName();
+
+ ClassNotFoundHandler parent = null;
+ Loader parentLoader = getParent();
+ if (parentLoader instanceof ClassNotFoundHandler)
+ parent = (ClassNotFoundHandler) parentLoader;
+
+ ClassLoaderPolicy parentPolicy = getClassLoaderPolicy(parentLoader);
+ if (parentPolicy != null)
+ parent = parentPolicy;
+
+ boolean parentResult = false;
+ if (parent != null)
+ parentResult = parent.classNotFound(event);
+
+ // Try the parent before
+ if (parentResult && getParentPolicy().getBeforeFilter().matchesClassName(className))
+ return true;
+
+ if (classNotFoundHandlers != null && classNotFoundHandlers.isEmpty() == false)
+ {
+ for (ClassNotFoundHandler handler : classNotFoundHandlers)
+ {
+ try
+ {
+ if (handler.classNotFound(event))
+ return true;
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error invoking classNotFoundHandler: " + handler, t);
+ }
+ }
+ }
+
+ // Try the parent after
+ if (parentResult && getParentPolicy().getAfterFilter().matchesClassName(className))
+ return true;
+
+ ClassLoaderSystem system = (ClassLoaderSystem) getClassLoaderSystem();
+ if (system == null)
+ return false;
+ return system.classNotFound(event);
+ }
+
+ /**
+ * Add a ClassFoundHandler
+ *
+ * @param handler the handler
+ */
+ public void addClassFoundHandler(ClassFoundHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classFoundHandlers == null)
+ classFoundHandlers = new CopyOnWriteArrayList<ClassFoundHandler>();
+
+ classFoundHandlers.add(handler);
+ }
+
+ /**
+ * Remove a ClassFoundHandler
+ *
+ * @param handler the handler
+ */
+ public void removeClassFoundHandler(ClassFoundHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classFoundHandlers == null)
+ return;
+ classFoundHandlers.remove(handler);
+ }
+
+ public void classFound(ClassFoundEvent event)
+ {
+ ClassFoundHandler parent = null;
+ Loader parentLoader = getParent();
+ if (parentLoader instanceof ClassFoundHandler)
+ parent = (ClassFoundHandler) parentLoader;
+
+ ClassLoaderPolicy parentPolicy = getClassLoaderPolicy(parentLoader);
+ if (parentPolicy != null)
+ parent = parentPolicy;
+
+ if (parent != null)
+ parent.classFound(event);
+
+ if (classFoundHandlers != null && classFoundHandlers.isEmpty() == false)
+ {
+ for (ClassFoundHandler handler : classFoundHandlers)
+ {
+ try
+ {
+ handler.classFound(event);
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error invoking classFoundHandler: " + handler, t);
+ }
+ }
+ }
+
+ ClassLoaderSystem system = (ClassLoaderSystem) getClassLoaderSystem();
+ if (system == null)
+ return;
+ system.classFound(event);
+ }
+
+ /**
+ * Add a ClassLoaderEventHandler
+ *
+ * @param handler the handler
+ */
+ public void addClassLoaderEventHandler(ClassLoaderEventHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classLoaderEventHandlers == null)
+ classLoaderEventHandlers = new CopyOnWriteArrayList<ClassLoaderEventHandler>();
+
+ classLoaderEventHandlers.add(handler);
+ }
+
+ /**
+ * Remove a ClassLoaderEventHandler
+ *
+ * @param handler the handler
+ */
+ public void removeClassLoaderEventHandler(ClassLoaderEventHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classLoaderEventHandlers == null)
+ return;
+ classLoaderEventHandlers.remove(handler);
+ }
+
+ private void fireRegisterClassLoader(ClassLoaderEvent event)
+ {
+ if (classLoaderEventHandlers != null && classLoaderEventHandlers.isEmpty() == false)
+ {
+ for (ClassLoaderEventHandler handler : classLoaderEventHandlers)
+ {
+ try
+ {
+ handler.fireRegisterClassLoader(event);
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error invoking classLoaderEventHandler: " + handler, t);
+ }
+ }
+ }
+
+ ClassLoaderSystem system = (ClassLoaderSystem) getClassLoaderSystem();
+ if (system == null)
+ return;
+ system.fireRegisterClassLoader(event);
+ }
+
+ private void fireUnregisterClassLoader(ClassLoaderEvent event)
+ {
+ if (classLoaderEventHandlers != null && classLoaderEventHandlers.isEmpty() == false)
+ {
+ for (ClassLoaderEventHandler handler : classLoaderEventHandlers)
+ {
+ try
+ {
+ handler.fireUnregisterClassLoader(event);
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error invoking classLoaderEventHandler: " + handler, t);
+ }
+ }
+ }
+
+ ClassLoaderSystem system = (ClassLoaderSystem) getClassLoaderSystem();
+ if (system == null)
+ return;
+ system.fireUnregisterClassLoader(event);
+ }
+
@Override
public String toString()
{
@@ -686,7 +918,8 @@
}
finally
{
- setUseLoadClassForParent(parent instanceof ClassLoaderDomain == false);
+ if ((parent instanceof ClassLoaderDomain == false) && (parent instanceof BaseClassLoaderSource == false))
+ setUseLoadClassForParent(true);
}
}
@@ -728,11 +961,13 @@
protected void afterRegisterClassLoader(ClassLoader classLoader, ClassLoaderPolicy policy)
{
registerClassLoaderMBean(classLoader);
+ fireRegisterClassLoader(new ClassLoaderEvent(this, classLoader));
}
@Override
protected void beforeUnregisterClassLoader(ClassLoader classLoader, ClassLoaderPolicy policy)
{
+ fireUnregisterClassLoader(new ClassLoaderEvent(this, classLoader));
unregisterClassLoaderMBean(classLoader);
}
Added: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEvent.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEvent.java (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEvent.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -0,0 +1,77 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloader.spi;
+
+import java.util.EventObject;
+
+/**
+ * ClassLoaderEvent.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassLoaderEvent extends EventObject
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -5874702798336257018L;
+
+ /** The classLoader */
+ private ClassLoader classLoader;
+
+ /**
+ * Create a new ClassLoaderEvent.
+ *
+ * @param classLoaderDomain the classLoaderDomain
+ * @param classLoader classLoader
+ */
+ public ClassLoaderEvent(ClassLoaderDomain classLoaderDomain, ClassLoader classLoader)
+ {
+ super(classLoaderDomain);
+ this.classLoader = classLoader;
+ }
+
+ /**
+ * Get the classLoader.
+ *
+ * @return the classLoader
+ */
+ public ClassLoader getClassLoader()
+ {
+ return classLoader;
+ }
+
+ /**
+ * Get the classLoaderDomain.
+ *
+ * @return the classLoaderDomain
+ */
+ public ClassLoaderDomain getClassLoaderDomain()
+ {
+ return (ClassLoaderDomain) getSource();
+ }
+
+ @Override
+ public String toString()
+ {
+ return getClass().getSimpleName() + "[classLoaderDomain=" + getClassLoaderDomain() + " classLoader=" + getClassLoader() + "]";
+ }
+}
Added: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEventHandler.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEventHandler.java (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderEventHandler.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -0,0 +1,45 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloader.spi;
+
+/**
+ * ClassLoaderEventHandler.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface ClassLoaderEventHandler
+{
+ /**
+ * Fired when a classLoader is registered
+ *
+ * @param event the classloader event
+ */
+ void fireRegisterClassLoader(ClassLoaderEvent event);
+
+ /**
+ * Fired when a classLoader is registered
+ *
+ * @param event the classloader event
+ */
+ void fireUnregisterClassLoader(ClassLoaderEvent event);
+}
Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java 2009-11-18 16:43:33 UTC (rev 96495)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderPolicy.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -31,6 +31,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
@@ -48,11 +49,17 @@
* @author <a href="adrian at jboss.com">Adrian Brock</a>
* @version $Revision: 1.1 $
*/
-public abstract class ClassLoaderPolicy extends BaseClassLoaderPolicy
+public abstract class ClassLoaderPolicy extends BaseClassLoaderPolicy implements ClassNotFoundHandler, ClassFoundHandler
{
/** The log */
private static final Logger log = Logger.getLogger(ClassLoaderPolicy.class);
+ /** The class not found handlers */
+ private List<ClassNotFoundHandler> classNotFoundHandlers;
+
+ /** The class found handlers */
+ private List<ClassFoundHandler> classFoundHandlers;
+
/**
* Get the delegate loader for exported stuff<p>
*
@@ -142,6 +149,7 @@
* @param path the path
* @return the url or null if not found
*/
+ // FindBugs: The Set doesn't use equals/hashCode
public abstract URL getResource(String path);
/**
@@ -176,7 +184,6 @@
* @param urls the list of urls to add to
* @throws IOException for any error
*/
- // FindBugs: The Set doesn't use equals/hashCode
public abstract void getResources(String name, Set<URL> urls) throws IOException;
/**
@@ -237,7 +244,116 @@
return getSystemClassLoader();
return null;
}
+
+ /**
+ * Add a ClassNotFoundHandler
+ *
+ * @param handler the handler
+ */
+ public void addClassNotFoundHandler(ClassNotFoundHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classNotFoundHandlers == null)
+ classNotFoundHandlers = new CopyOnWriteArrayList<ClassNotFoundHandler>();
+
+ classNotFoundHandlers.add(handler);
+ }
+
+ /**
+ * Remove a ClassNotFoundHandler
+ *
+ * @param handler the handler
+ */
+ public void removeClassNotFoundHandler(ClassNotFoundHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classNotFoundHandlers == null)
+ return;
+ classNotFoundHandlers.remove(handler);
+ }
+ public boolean classNotFound(ClassNotFoundEvent event)
+ {
+ if (classNotFoundHandlers != null && classNotFoundHandlers.isEmpty() == false)
+ {
+ for (ClassNotFoundHandler handler : classNotFoundHandlers)
+ {
+ try
+ {
+ if (handler.classNotFound(event))
+ return true;
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error invoking classNotFoundHandler: " + handler, t);
+ }
+ }
+ }
+
+ ClassLoaderDomain domain = getDomain();
+ if (domain == null)
+ return false;
+ return domain.classNotFound(event);
+ }
+
+ /**
+ * Add a ClassFoundHandler
+ *
+ * @param handler the handler
+ */
+ public void addClassFoundHandler(ClassFoundHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classFoundHandlers == null)
+ classFoundHandlers = new CopyOnWriteArrayList<ClassFoundHandler>();
+
+ classFoundHandlers.add(handler);
+ }
+
+ /**
+ * Remove a ClassFoundHandler
+ *
+ * @param handler the handler
+ */
+ public void removeClassFoundHandler(ClassFoundHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classFoundHandlers == null)
+ return;
+ classFoundHandlers.remove(handler);
+ }
+
+ public void classFound(ClassFoundEvent event)
+ {
+ if (classFoundHandlers != null && classFoundHandlers.isEmpty() == false)
+ {
+ for (ClassFoundHandler handler : classFoundHandlers)
+ {
+ try
+ {
+ handler.classFound(event);
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error invoking classFoundHandler: " + handler, t);
+ }
+ }
+ }
+
+ ClassLoaderDomain domain = getDomain();
+ if (domain == null)
+ return;
+ domain.classFound(event);
+ }
+
@Override
public ObjectName getObjectName()
{
Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystem.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystem.java 2009-11-18 16:43:33 UTC (rev 96495)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassLoaderSystem.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -23,6 +23,7 @@
import java.security.ProtectionDomain;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
@@ -30,7 +31,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.Collections;
+import java.util.concurrent.CopyOnWriteArrayList;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
@@ -50,7 +51,7 @@
* @author <a href="ales.justin at jboss.com">Ales Justin</a>
* @version $Revision: 1.1 $
*/
-public abstract class ClassLoaderSystem extends BaseClassLoaderSystem implements ClassLoaderSystemMBean, MBeanRegistration
+public abstract class ClassLoaderSystem extends BaseClassLoaderSystem implements ClassLoaderSystemMBean, MBeanRegistration, ClassNotFoundHandler, ClassFoundHandler, ClassLoaderEventHandler
{
/** The log */
private static final Logger log = Logger.getLogger(ClassLoaderSystem.class);
@@ -78,6 +79,15 @@
/** The object name */
private ObjectName objectName;
+
+ /** The class not found handlers */
+ private List<ClassNotFoundHandler> classNotFoundHandlers;
+
+ /** The class found handlers */
+ private List<ClassFoundHandler> classFoundHandlers;
+
+ /** The class loader event handlers */
+ private List<ClassLoaderEventHandler> classLoaderEventHandlers;
/**
* Get the classloading system instance
@@ -182,6 +192,7 @@
public ClassLoaderDomain createAndRegisterDomain(String name, ParentPolicy parentPolicy, Loader parent)
{
ClassLoaderDomain result = createDomain(name);
+ assert result != null : "createDomain(" + name + ") returned null";
result.setParentPolicy(parentPolicy);
result.setParent(parent);
registerDomain(result);
@@ -520,7 +531,7 @@
* @deprecated use translator list
*/
@Deprecated
- public Translator getTranslator()
+ public synchronized Translator getTranslator()
{
if (translators == null || translators.isEmpty())
return null;
@@ -535,7 +546,7 @@
* @deprecated use translator list
*/
@Deprecated
- public void setTranslator(Translator translator)
+ public synchronized void setTranslator(Translator translator)
{
log.debug(this + " set translator to " + translator);
@@ -548,7 +559,7 @@
@Override
protected byte[] transform(ClassLoader classLoader, String className, byte[] byteCode, ProtectionDomain protectionDomain) throws Exception
{
- byte[] result = TranslatorUtils.applyTranslatorsOnTransform(translators, classLoader, className, byteCode, protectionDomain);
+ byte[] result = TranslatorUtils.applyTranslatorsOnTransform(getTranslators(), classLoader, className, byteCode, protectionDomain);
return super.transform(classLoader, className, result, protectionDomain);
}
@@ -557,7 +568,7 @@
{
try
{
- TranslatorUtils.applyTranslatorsAtUnregister(translators, classLoader);
+ TranslatorUtils.applyTranslatorsAtUnregister(getTranslators(), classLoader);
}
catch (Throwable t)
{
@@ -685,7 +696,174 @@
log.warn("Error unregistering domain: " + domain, e);
}
}
+
+ /**
+ * Add a ClassNotFoundHandler
+ *
+ * @param handler the handler
+ */
+ public void addClassNotFoundHandler(ClassNotFoundHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classNotFoundHandlers == null)
+ classNotFoundHandlers = new CopyOnWriteArrayList<ClassNotFoundHandler>();
+
+ classNotFoundHandlers.add(handler);
+ }
+
+ /**
+ * Remove a ClassNotFoundHandler
+ *
+ * @param handler the handler
+ */
+ public void removeClassNotFoundHandler(ClassNotFoundHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classNotFoundHandlers == null)
+ return;
+ classNotFoundHandlers.remove(handler);
+ }
+ public boolean classNotFound(ClassNotFoundEvent event)
+ {
+ if (classNotFoundHandlers != null && classNotFoundHandlers.isEmpty() == false)
+ {
+ for (ClassNotFoundHandler handler : classNotFoundHandlers)
+ {
+ try
+ {
+ if (handler.classNotFound(event))
+ return true;
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error invoking classNotFoundHandler: " + handler, t);
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Add a ClassFoundHandler
+ *
+ * @param handler the handler
+ */
+ public void addClassFoundHandler(ClassFoundHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classFoundHandlers == null)
+ classFoundHandlers = new CopyOnWriteArrayList<ClassFoundHandler>();
+
+ classFoundHandlers.add(handler);
+ }
+
+ /**
+ * Remove a ClassFoundHandler
+ *
+ * @param handler the handler
+ */
+ public void removeClassFoundHandler(ClassFoundHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classFoundHandlers == null)
+ return;
+ classFoundHandlers.remove(handler);
+ }
+
+ public void classFound(ClassFoundEvent event)
+ {
+ if (classFoundHandlers != null && classFoundHandlers.isEmpty() == false)
+ {
+ for (ClassFoundHandler handler : classFoundHandlers)
+ {
+ try
+ {
+ handler.classFound(event);
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error invoking classFoundHandler: " + handler, t);
+ }
+ }
+ }
+ }
+
+ /**
+ * Add a ClassLoaderEventHandler
+ *
+ * @param handler the handler
+ */
+ public void addClassLoaderEventHandler(ClassLoaderEventHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classLoaderEventHandlers == null)
+ classLoaderEventHandlers = new CopyOnWriteArrayList<ClassLoaderEventHandler>();
+
+ classLoaderEventHandlers.add(handler);
+ }
+
+ /**
+ * Remove a ClassLoaderEventHandler
+ *
+ * @param handler the handler
+ */
+ public void removeClassLoaderEventHandler(ClassLoaderEventHandler handler)
+ {
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
+ if (classLoaderEventHandlers == null)
+ return;
+ classLoaderEventHandlers.remove(handler);
+ }
+
+ public void fireRegisterClassLoader(ClassLoaderEvent event)
+ {
+ if (classLoaderEventHandlers != null && classLoaderEventHandlers.isEmpty() == false)
+ {
+ for (ClassLoaderEventHandler handler : classLoaderEventHandlers)
+ {
+ try
+ {
+ handler.fireRegisterClassLoader(event);
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error invoking classLoaderEventHandler: " + handler, t);
+ }
+ }
+ }
+ }
+
+ public void fireUnregisterClassLoader(ClassLoaderEvent event)
+ {
+ if (classLoaderEventHandlers != null && classLoaderEventHandlers.isEmpty() == false)
+ {
+ for (ClassLoaderEventHandler handler : classLoaderEventHandlers)
+ {
+ try
+ {
+ handler.fireUnregisterClassLoader(event);
+ }
+ catch (Throwable t)
+ {
+ log.warn("Error invoking classLoaderEventHandler: " + handler, t);
+ }
+ }
+ }
+ }
+
@Override
protected void toLongString(StringBuilder builder)
{
Added: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundEvent.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundEvent.java (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundEvent.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -0,0 +1,77 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloader.spi;
+
+import java.util.EventObject;
+
+/**
+ * ClassNotFoundEvent.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassNotFoundEvent extends EventObject
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 7445562838711417089L;
+
+ /** The class name */
+ private String className;
+
+ /**
+ * Create a new ClassNotFoundEvent.
+ *
+ * @param classLoader the classLoader
+ * @param className the class name
+ */
+ public ClassNotFoundEvent(ClassLoader classLoader, String className)
+ {
+ super(classLoader);
+ this.className = className;
+ }
+
+ /**
+ * Get the className.
+ *
+ * @return the className.
+ */
+ public String getClassName()
+ {
+ return className;
+ }
+
+ /**
+ * Get the classLoader.
+ *
+ * @return the classLoader
+ */
+ public ClassLoader getClassLoader()
+ {
+ return (ClassLoader) getSource();
+ }
+
+ @Override
+ public String toString()
+ {
+ return getClass().getSimpleName() + "[classLoader=" + getClassLoader() + " class=" + getClassName() + "]";
+ }
+}
Added: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundHandler.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundHandler.java (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/ClassNotFoundHandler.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -0,0 +1,39 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.classloader.spi;
+
+/**
+ * ClassNotFoundHandler.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface ClassNotFoundHandler
+{
+ /**
+ * Fired when a class is not found
+ *
+ * @param event the event
+ * @return true when the a retry of the classloading should be tried
+ */
+ boolean classNotFound(ClassNotFoundEvent event);
+}
Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoader.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoader.java 2009-11-18 16:43:33 UTC (rev 96495)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoader.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -46,8 +46,10 @@
import javax.management.ObjectName;
import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.ClassFoundEvent;
import org.jboss.classloader.spi.ClassLoaderDomain;
import org.jboss.classloader.spi.ClassLoaderPolicy;
+import org.jboss.classloader.spi.ClassNotFoundEvent;
import org.jboss.classloader.spi.DelegateLoader;
import org.jboss.classloader.spi.Loader;
import org.jboss.classloader.spi.PackageInformation;
@@ -57,39 +59,39 @@
/**
* BaseClassLoader.
- *
+ *
* @author <a href="adrian at jboss.com">Adrian Brock</a>
* @version $Revision: 1.1 $
*/
-public class BaseClassLoader extends SecureClassLoader implements BaseClassLoaderMBean, RealClassLoader
+public class BaseClassLoader extends SecureClassLoader implements BaseClassLoaderMBean, RealClassLoader
{
/** 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;
-
+
/** The loaded classes */
private Map<String, String> loadedClasses = new ConcurrentHashMap<String, String>();
-
+
/** Our resource cache */
private Map<String, URL> resourceCache;
-
+
/** Our black list */
private Map<String, String> blackList;
-
+
/**
* 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
+ * @throws IllegalArgumentException for a null policy
+ * @throws IllegalStateException if the policy is already associated with a classloader
*/
public BaseClassLoader(ClassLoaderPolicy policy)
{
@@ -108,7 +110,7 @@
if (basePolicy.isBlackListable())
blackList = new ConcurrentHashMap<String, String>();
-
+
log.debug("Created " + this + " with policy " + policy.toLongString());
}
@@ -116,7 +118,7 @@
{
return policy.getObjectName();
}
-
+
public ObjectName getClassLoaderDomain()
{
BaseClassLoaderPolicy basePolicy = policy;
@@ -128,7 +130,7 @@
{
return policy.getName();
}
-
+
public boolean isBlackListable()
{
BaseClassLoaderPolicy basePolicy = policy;
@@ -173,7 +175,7 @@
}
return result;
}
-
+
public String listPolicyDetails()
{
return policy.toLongString();
@@ -184,18 +186,18 @@
final Class<?> clazz = loadClass(name);
if (clazz == null)
return null;
-
+
ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
{
public ClassLoader run()
{
- return clazz.getClassLoader();
+ return clazz.getClassLoader();
}
});
-
+
if (cl != null && cl instanceof RealClassLoader)
return ((RealClassLoader) cl).getObjectName();
-
+
return null;
}
@@ -223,7 +225,7 @@
/**
* Get the policy.
- *
+ *
* @return the policy.
*/
ClassLoaderPolicy getPolicy()
@@ -233,7 +235,7 @@
/**
* Get the loader.
- *
+ *
* @return the loader.
*/
DelegateLoader getLoader()
@@ -250,12 +252,12 @@
if (name == null)
return null;
-
+
// Did we already load this package?
Package result = super.getPackage(name);
if (result != null && trace)
log.trace(this + " already loaded package " + name + " " + result.getName());
-
+
// Not already loaded use the domain
if (result == null)
{
@@ -267,14 +269,14 @@
log.trace(this + " getPackage " + name + " domain=" + domain);
result = domain.getPackage(this, name);
}
-
+
// Still not found
if (result == null)
{
if (trace)
log.trace(this + " package not found " + name);
}
-
+
return result;
}
@@ -296,7 +298,7 @@
/**
* Get a package locally
- *
+ *
* @param name the package name
* @return the package
*/
@@ -307,7 +309,7 @@
/**
* Get the packages locally
- *
+ *
* @param packages the packages
*/
void getPackagesLocally(Set<Package> packages)
@@ -316,10 +318,10 @@
for (Package pkg : pkgs)
packages.add(pkg);
}
-
+
/**
* Check to see if the class is already loaded
- *
+ *
* @param name the name of the class
* @param trace whether trace is enabled
* @return the class is if it is already loaded, null otherwise
@@ -347,10 +349,10 @@
log.trace(this + " already loaded class " + ClassLoaderUtils.classToString(result));
return result;
}
-
+
/**
* Check the cache and blacklist
- *
+ *
* @param name the name of the class
* @param failIfBlackListed <code>true</code> if a blacklisted class should
* result in ClassNotFoundException; <code>false</code>
@@ -367,12 +369,12 @@
if (domain == null)
return null;
- return domain.checkClassCacheAndBlackList(this, name, null, basePolicy.isImportAll(), failIfBlackListed);
+ return domain.checkClassCacheAndBlackList(this, name, null, basePolicy.isImportAll(), false);
}
/**
* Find the classloader for a class but don't load the class
- *
+ *
* @param className the class name
* @return the classloader
* @throws ClassNotFoundException if the class is not found
@@ -392,11 +394,11 @@
ClassLoaderUtils.checkClassName(className);
String path = ClassLoaderUtils.classNameToPath(className);
-
+
Loader loader = domain.findLoader(this, path, basePolicy.isImportAll(), true);
if (loader == null)
throw new ClassNotFoundException("Class " + className + " not found from " + this);
-
+
// This is a bit ugly but we can't abstract this behind an interface because
// that would make the methods public
if (loader instanceof BaseClassLoaderSource)
@@ -412,10 +414,10 @@
boolean trace = log.isTraceEnabled();
if (trace)
log.trace(this + " loadClass " + name + " resolve=" + resolve);
-
+
// Validate the class name makes sense
ClassLoaderUtils.checkClassName(name);
-
+
// Did we already load this class?
Class<?> result = isLoadedClass(name, trace);
@@ -434,21 +436,72 @@
result = checkCacheAndBlackList(name, false, trace);
if (result != null)
return result;
+
+ // Try to load the class
+ ClassNotFoundException exception = null;
+ try
+ {
+ result = doLoadClass(name, resolve, trace);
+ }
+ catch (ClassNotFoundException e)
+ {
+ exception = e;
+ }
+ // If we failed, try any class not found handlers and retry if one says it is resolved
+ if (result == null)
+ {
+ ClassLoaderPolicy policy = getPolicy();
+ if (policy != null && policy.classNotFound(new ClassNotFoundEvent(this, name)))
+ {
+ try
+ {
+ result = doLoadClass(name, resolve, trace);
+ }
+ catch (ClassNotFoundException e)
+ {
+ exception = e;
+ }
+ }
+ }
+
+ if (result == null)
+ {
+ if (trace)
+ log.trace(this + " class not found " + name);
+ if (exception != null)
+ throw exception;
+ throw new ClassNotFoundException(name + " from " + toString());
+ }
+ return result;
+ }
+
+ /**
+ * Do the load class
+ *
+ * @param name the name
+ * @param resolve whether to resolve
+ * @param trace whether trace is enabled
+ * @return the class or null if not found
+ * @throws ClassNotFoundException if a problem is raised
+ */
+ protected Class<?> doLoadClass(String name, boolean resolve, boolean trace) throws ClassNotFoundException
+ {
+ Class<?> result = null;
+
synchronized (this)
{
+ // JBCL-114: did we lose the race to the synchronized?
+ result = isLoadedClass(name, trace);
+
// 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());
- }
-
+ return null;
+
// Link the class if requested
if (resolve)
{
@@ -456,7 +509,7 @@
log.trace(this + " resolveClass " + ClassLoaderUtils.classToString(result));
resolveClass(result);
}
-
+
return result;
}
}
@@ -497,10 +550,10 @@
domain.getResources(this, name, resourceURLs);
return resourceURLs;
}
-
+
/**
* Try to load the class locally
- *
+ *
* @param name the class name
* @return the class
*/
@@ -511,7 +564,7 @@
/**
* Try to load the class locally
- *
+ *
* @param name the class name
* @param trace whether trace is enabled
* @return the class if found
@@ -528,7 +581,7 @@
// Look for the resource
final String resourcePath = ClassLoaderUtils.classNameToPath(name);
-
+
result = AccessController.doPrivileged(new PrivilegedAction<Class<?>>()
{
public Class<?> run()
@@ -543,7 +596,7 @@
// 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, resourcePath);
@@ -557,7 +610,7 @@
{
throw new RuntimeException("Unexpected error transforming class " + name, t);
}
-
+
// Create the package if necessary
URL codeSourceURL = null;
if (protectionDomain != null)
@@ -567,7 +620,7 @@
codeSourceURL = codeSource.getLocation();
}
definePackage(name, codeSourceURL);
-
+
// Finally we can define the class
Class<?> result;
if (protectionDomain != null)
@@ -579,15 +632,16 @@
return result;
}
}, policy.getAccessControlContext());
-
+
loadedClasses.put(name, name);
-
+ policy.classFound(new ClassFoundEvent(this, result));
+
return result;
}
/**
* Try to find the resource locally
- *
+ *
* @param name the resource name
* @return the url if found
*/
@@ -598,7 +652,7 @@
/**
* Try to find the resource locally
- *
+ *
* @param name the resource name
* @param trace whether trace is enabled
* @return the URL if found
@@ -619,7 +673,7 @@
return url;
}
}
-
+
// Is this resource blacklisted?
if (blackList != null && blackList.containsKey(name))
{
@@ -627,7 +681,7 @@
log.trace(this + " resource is blacklisted " + name);
return null;
}
-
+
// Ask the policy for the resource
URL result = AccessController.doPrivileged(new PrivilegedAction<URL>()
{
@@ -650,17 +704,17 @@
// Cache what we found
if (resourceCache != null && result != null)
resourceCache.put(name, result);
-
+
// Blacklist when not found
if (blackList != null && result == null)
blackList.put(name, name);
-
+
return result;
}
/**
* Try to find the resource locally
- *
+ *
* @param name the resource name
* @param urls the urls to add to
* @throws IOException for any error
@@ -673,7 +727,7 @@
/**
* Try to find the resources locally
- *
+ *
* @param name the resource name
* @param urls the urls to add to
* @param trace whether trace is enabled
@@ -709,7 +763,7 @@
throw e2;
}
}
-
+
/**
* Define the package for the class if not already done
*
@@ -721,10 +775,10 @@
String packageName = ClassLoaderUtils.getClassPackageName(className);
if (packageName.length() == 0)
return;
-
+
// Ask the policy for the information
PackageInformation pi = policy.getClassPackageInformation(className, packageName);
-
+
// Already defined?
Package pkge = getPackage(packageName);
if (pkge != null)
@@ -761,7 +815,7 @@
/**
* 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
@@ -771,17 +825,17 @@
{
// 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
+ // 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);
@@ -791,7 +845,7 @@
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);
@@ -815,7 +869,7 @@
BaseClassLoaderPolicy basePolicy = policy;
return basePolicy.getClassLoaderUnchecked() != null;
}
-
+
public Class<?> getCachedClass(String name)
{
// TODO look in global and/or local cache
@@ -880,10 +934,10 @@
policy.clearBlackList(name);
}
}
-
+
/**
* A long version of the classloader
- *
+ *
* @return the long string
*/
public String toLongString()
@@ -896,28 +950,29 @@
builder.append('}');
return builder.toString();
}
-
+
/**
* Shutdown the classloader
*/
protected void shutdownClassLoader()
{
log.debug(toString() + " shutdown!");
+ loadedClasses.clear();
if (resourceCache != null)
resourceCache.clear();
if (blackList != null)
blackList.clear();
}
-
+
/**
* For subclasses to add things to the long string
- *
+ *
* @param builder the builder
*/
protected void toLongString(StringBuilder builder)
{
}
-
+
@Override
public String toString()
{
@@ -930,7 +985,7 @@
/**
* Attempt to lock, but don't wait
- *
+ *
* @return true when the lock was obtained
*/
boolean attemptLock()
@@ -940,7 +995,7 @@
/**
* Lock
- *
+ *
* This method must be invoked with the monitor held
*/
void lock()
@@ -950,7 +1005,7 @@
/**
* Unlock
- *
+ *
* @param rescheduleTasks whether to reschedule tasks
*/
void unlock(boolean rescheduleTasks)
@@ -960,7 +1015,7 @@
/**
* Attempt to get the lock but don't wait
- *
+ *
* @param trace whether trace is enabled
* @return true when obtained the lock
*/
@@ -1000,12 +1055,12 @@
return result;
}
-
+
/**
* Acquire the lock on the classloader fairly<p>
*
* This must be invoked with the monitor held
- *
+ *
* @param trace whether trace is enabled
*/
private void acquireLockFairly(boolean trace)
@@ -1017,7 +1072,7 @@
boolean interrupted = Thread.interrupted();
int waits = 0;
-
+
try
{
while (true)
@@ -1052,14 +1107,14 @@
if (interrupted)
thread.interrupt();
}
-
+
if (lock.getHoldCount() == 1)
ClassLoaderManager.registerLoaderThread(this, thread);
}
/**
* Unlock
- *
+ *
* @param trace whether trace is enabled
* @param rescheduleTasks whether to reschedule tasks
*/
@@ -1071,8 +1126,8 @@
synchronized (this)
{
- lock.unlock();
-
+ lock.unlock();
+
if (lock.getHoldCount() == 0)
{
ClassLoaderManager.unregisterLoaderThread(this, thread, rescheduleTasks);
@@ -1083,7 +1138,7 @@
/**
* Get the classloader for a class
- *
+ *
* @param clazz the class
* @return the classloader or null if it doesn't have one
*/
@@ -1092,7 +1147,7 @@
SecurityManager sm = System.getSecurityManager();
if (sm == null)
return clazz.getClassLoader();
-
+
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
{
public ClassLoader run()
Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java 2009-11-18 16:43:33 UTC (rev 96495)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderDomain.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -1195,6 +1195,23 @@
}
/**
+ * Get the classloader policy associated with an object
+ *
+ * @param object the object
+ * @return the classloader policy or null if one is not associated
+ */
+ protected ClassLoaderPolicy getClassLoaderPolicy(Object object)
+ {
+ if (object instanceof BaseClassLoader)
+ return ((BaseClassLoader) object).getPolicy();
+
+ if (object instanceof BaseClassLoaderSource)
+ return getClassLoaderPolicy(((BaseClassLoaderSource) object).getClassLoader());
+
+ return null;
+ }
+
+ /**
* A long version of toString()
*
* @return the long string
Modified: projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java 2009-11-18 16:43:33 UTC (rev 96495)
+++ projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/BaseClassLoaderPolicy.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -256,6 +256,16 @@
*
* @return the domain
*/
+ protected ClassLoaderDomain getDomain()
+ {
+ return (ClassLoaderDomain) getClassLoaderDomain();
+ }
+
+ /**
+ * Get the classloader domain
+ *
+ * @return the domain
+ */
BaseClassLoaderDomain getClassLoaderDomain()
{
return domain;
@@ -336,7 +346,7 @@
log.debug(toString() + " shutdown!");
BaseClassLoader classLoader = this.classLoader;
this.classLoader = null;
- TranslatorUtils.applyTranslatorsAtUnregister(getTranslators(), classLoader);
+ TranslatorUtils.applyTranslatorsAtUnregister(translators, classLoader);
classLoader.shutdownClassLoader();
}
Modified: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/ClassLoaderAllTestSuite.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/ClassLoaderAllTestSuite.java 2009-11-18 16:43:33 UTC (rev 96495)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/ClassLoaderAllTestSuite.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -30,6 +30,7 @@
import org.jboss.test.classloader.filter.FilterTestSuite;
import org.jboss.test.classloader.jmx.JMXTestSuite;
import org.jboss.test.classloader.junit.JUnitTestSuite;
+import org.jboss.test.classloader.notifications.ClassLoaderNotificationsTestSuite;
import org.jboss.test.classloader.old.OldTestSuite;
import org.jboss.test.classloader.policy.test.ClassLoaderPolicyUnitTestCase;
import org.jboss.test.classloader.resources.ResourceTestSuite;
@@ -75,6 +76,7 @@
suite.addTest(JMXTestSuite.suite());
suite.addTest(JUnitTestSuite.suite());
suite.addTest(TransformTestSuite.suite());
+ suite.addTest(ClassLoaderNotificationsTestSuite.suite());
return suite;
}
Modified: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java 2009-11-18 16:43:33 UTC (rev 96495)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/domain/test/CustomParentLoaderUnitTestCase.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -29,9 +29,11 @@
import junit.framework.Test;
import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.spi.ClassFoundHandler;
import org.jboss.classloader.spi.ClassLoaderDomain;
import org.jboss.classloader.spi.ClassLoaderDomainMBean;
import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.spi.ClassNotFoundHandler;
import org.jboss.classloader.spi.Loader;
import org.jboss.classloader.spi.ParentPolicy;
import org.jboss.classloader.spi.base.BaseClassLoaderDomain;
@@ -159,7 +161,7 @@
ClassLoader classLoader = system.registerClassLoaderPolicy(domain, policy);
assertLoadClass(ClassLoaderDomain.class, classLoader);
- checkGetResource(loader, ClassLoaderDomain.class, BaseClassLoaderDomain.class, ClassLoaderDomainMBean.class, MBeanRegistration.class, Loader.class, Object.class);
+ checkGetResource(loader, ClassLoaderDomain.class, BaseClassLoaderDomain.class, ClassLoaderDomainMBean.class, MBeanRegistration.class, Loader.class, ClassNotFoundHandler.class, ClassFoundHandler.class, Object.class);
checkLoadClass(loader);
}
Added: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/ClassLoaderNotificationsTestSuite.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/ClassLoaderNotificationsTestSuite.java (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/ClassLoaderNotificationsTestSuite.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloader.notifications;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import org.jboss.test.classloader.notifications.test.ClassFoundHandlerUnitTestCase;
+import org.jboss.test.classloader.notifications.test.ClassLoaderEventHandlerUnitTestCase;
+import org.jboss.test.classloader.notifications.test.ClassNotFoundHandlerUnitTestCase;
+
+/**
+ * Notifications Test Suite.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 37459 $
+ */
+public class ClassLoaderNotificationsTestSuite extends TestSuite
+{
+ /**
+ * For running the testsuite from the command line
+ *
+ * @param args the command line args
+ */
+ public static void main(String[] args)
+ {
+ TestRunner.run(suite());
+ }
+
+ /**
+ * Create the testsuite
+ *
+ * @return the testsuite
+ */
+ public static Test suite()
+ {
+ TestSuite suite = new TestSuite("Notifications Tests");
+
+ suite.addTest(ClassLoaderEventHandlerUnitTestCase.suite());
+ suite.addTest(ClassNotFoundHandlerUnitTestCase.suite());
+ suite.addTest(ClassFoundHandlerUnitTestCase.suite());
+
+ return suite;
+ }
+}
Added: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/support/a/A.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/support/a/A.java (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/support/a/A.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -0,0 +1,32 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.classloader.notifications.support.a;
+
+/**
+ * A.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class A
+{
+}
Added: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassFoundHandlerUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassFoundHandlerUnitTestCase.java (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassFoundHandlerUnitTestCase.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -0,0 +1,286 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloader.notifications.test;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import junit.framework.Test;
+
+import org.jboss.classloader.plugins.loader.ClassLoaderToLoaderAdapter;
+import org.jboss.classloader.spi.ClassFoundEvent;
+import org.jboss.classloader.spi.ClassFoundHandler;
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.spi.ParentPolicy;
+import org.jboss.classloader.test.support.MockClassLoaderPolicy;
+import org.jboss.test.classloader.AbstractClassLoaderTestWithSecurity;
+import org.jboss.test.classloader.notifications.support.a.A;
+
+/**
+ * ClassFoundHnadlerUnitTestCase
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassFoundHandlerUnitTestCase extends AbstractClassLoaderTestWithSecurity implements ClassFoundHandler
+{
+ public static Test suite()
+ {
+ return suite(ClassFoundHandlerUnitTestCase.class);
+ }
+
+ public ClassFoundHandlerUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ List<ClassFoundEvent> events = new CopyOnWriteArrayList<ClassFoundEvent>();
+
+ public void classFound(ClassFoundEvent event)
+ {
+ events.add(event);
+ }
+
+ public void testClassFoundHandlerPolicy() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setPathsAndPackageNames(A.class);
+ policy.addClassFoundHandler(this);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ assertLoadClass(A.class, cl);
+ assertLoadClassNoEvent(A.class, cl);
+ }
+
+ public void testClassFoundHandlerDomain() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain domain = system.getDefaultDomain();
+ domain.addClassFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setPathsAndPackageNames(A.class);
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClass(A.class, cl);
+ assertLoadClassNoEvent(A.class, cl);
+ }
+
+ public void testClassFoundHandlerParentDomain() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+ ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, defaultDomain);
+ defaultDomain.addClassFoundHandler(this);
+
+ MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+ parentPolicy.setPathsAndPackageNames(A.class);
+ ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClass(A.class, cl, parentCl);
+ assertLoadClassNoEvent(A.class, cl, parentCl);
+ }
+
+ public void testClassFoundHandlerParentClassLoader() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+ defaultDomain.addClassFoundHandler(this);
+
+ MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+ parentPolicy.setPathsAndPackageNames(A.class);
+ ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+ ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, new ClassLoaderToLoaderAdapter(parentCl));
+ domain.setUseLoadClassForParent(false);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClass(A.class, cl, parentCl);
+ assertLoadClassNoEvent(A.class, cl, parentCl);
+ }
+
+ public void testClassFoundHandlerSystem() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ system.addClassFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setPathsAndPackageNames(A.class);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ assertLoadClass(A.class, cl);
+ assertLoadClassNoEvent(A.class, cl);
+ }
+
+ public void testClassFoundHandlerPolicyNoEvent() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setPathsAndPackageNames(A.class);
+ policy.addClassFoundHandler(this);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ assertLoadClassFail("does.not.exist.Class", cl);
+ }
+
+ public void testClassFoundHandlerDomainNoEvent() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain domain = system.getDefaultDomain();
+ domain.addClassFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setPathsAndPackageNames(A.class);
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClassFail("does.not.exist.Class", cl);
+ }
+
+ public void testClassFoundHandlerParentDomainNoEvent() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+ ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, defaultDomain);
+ defaultDomain.addClassFoundHandler(this);
+
+ MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+ parentPolicy.setPathsAndPackageNames(A.class);
+ system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClassFail("does.not.exist.Class", cl);
+ }
+
+ public void testClassFoundHandlerParentClassLoaderNoEvent() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+ defaultDomain.addClassFoundHandler(this);
+
+ MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+ parentPolicy.setPathsAndPackageNames(A.class);
+ ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+ ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, new ClassLoaderToLoaderAdapter(parentCl));
+ domain.setUseLoadClassForParent(false);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClassFail("does.not.exist.Class", cl);
+ }
+
+ public void testClassFoundHandlerSystemNoEvent() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ system.addClassFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setPathsAndPackageNames(A.class);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ assertLoadClassFail("does.not.exist.Class", cl);
+ }
+
+ public void testClassFoundHandlerWrongPolicy() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setImportAll(true);
+ policy.addClassFoundHandler(this);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+ a.setPathsAndPackageNames(A.class);
+ ClassLoader clA = system.registerClassLoaderPolicy(a);
+
+ assertLoadClassNoEvent(A.class, cl, clA);
+ }
+
+ public void testClassFoundHandlerDifferentPolicy() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setImportAll(true);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+ a.setPathsAndPackageNames(A.class);
+ a.addClassFoundHandler(this);
+ ClassLoader clA = system.registerClassLoaderPolicy(a);
+
+ assertLoadClass(A.class, cl, clA);
+ assertLoadClassNoEvent(A.class, cl, clA);
+ }
+
+ protected Class<?> assertLoadClassNoEvent(Class<?> reference, ClassLoader start)
+ {
+ return assertLoadClass(reference, start, start);
+ }
+
+ protected Class<?> assertLoadClassNoEvent(Class<?> reference, ClassLoader start, ClassLoader expected)
+ {
+ Class<?> result = super.assertLoadClass(reference, start, expected);
+ assertNoEvent();
+ return result;
+ }
+
+ protected Class<?> assertLoadClass(Class<?> reference, ClassLoader start, ClassLoader expected)
+ {
+ Class<?> result = super.assertLoadClass(reference, start, expected);
+ assertEvent(reference.getName(), expected);
+ return result;
+ }
+
+ protected void assertLoadClassFail(String name, ClassLoader start)
+ {
+ super.assertLoadClassFail(name, start);
+ assertNoEvent();
+ }
+
+ protected void assertEvent(String name, ClassLoader expected)
+ {
+ assertTrue("Expected an event", events.isEmpty() == false);
+ ClassFoundEvent event = events.remove(0);
+ assertEquals(name, event.getClassName());
+ assertEquals(expected, event.getClassLoader());
+ assertEquals(expected, event.getSource());
+ }
+
+ protected void assertNoEvent()
+ {
+ assertTrue("Expected no events: " + events, events.isEmpty());
+ }
+}
Added: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassLoaderEventHandlerUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassLoaderEventHandlerUnitTestCase.java (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassLoaderEventHandlerUnitTestCase.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -0,0 +1,186 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloader.notifications.test;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import junit.framework.Test;
+
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderEvent;
+import org.jboss.classloader.spi.ClassLoaderEventHandler;
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.test.support.MockClassLoaderPolicy;
+import org.jboss.test.classloader.AbstractClassLoaderTestWithSecurity;
+
+/**
+ * ClassFoundHnadlerUnitTestCase
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassLoaderEventHandlerUnitTestCase extends AbstractClassLoaderTestWithSecurity implements ClassLoaderEventHandler
+{
+ public static Test suite()
+ {
+ return suite(ClassLoaderEventHandlerUnitTestCase.class);
+ }
+
+ public ClassLoaderEventHandlerUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ List<ClassLoaderEvent> registered = new CopyOnWriteArrayList<ClassLoaderEvent>();
+ List<ClassLoaderEvent> unregistered = new CopyOnWriteArrayList<ClassLoaderEvent>();
+
+ public void fireRegisterClassLoader(ClassLoaderEvent event)
+ {
+ registered.add(event);
+ }
+
+ public void fireUnregisterClassLoader(ClassLoaderEvent event)
+ {
+ unregistered.add(event);
+ }
+
+ public void testClassLoaderEventDomain() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain domain = system.getDefaultDomain();
+ domain.addClassLoaderEventHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ assertRegistered(domain, cl);
+
+ system.unregisterClassLoader(cl);
+ assertUnregistered(domain, cl);
+ }
+
+ public void testClassLoaderEventSystem() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain domain = system.getDefaultDomain();
+ system.addClassLoaderEventHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ assertRegistered(domain, cl);
+
+ system.unregisterClassLoader(cl);
+ assertUnregistered(domain, cl);
+ }
+
+ public void testClassLoaderEventWrongDomain() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain domain1 = system.createAndRegisterDomain("Domain1");
+ ClassLoaderDomain domain2 = system.createAndRegisterDomain("Domain2");
+ domain1.addClassLoaderEventHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain2, policy);
+
+ assertNoRegistered();
+
+ system.unregisterClassLoader(cl);
+ assertNoUnregistered();
+ }
+
+ public void testClassLoaderEventCorrectDomain() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ system.createAndRegisterDomain("Domain1");
+ ClassLoaderDomain domain2 = system.createAndRegisterDomain("Domain2");
+ domain2.addClassLoaderEventHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain2, policy);
+
+ assertRegistered(domain2, cl);
+
+ system.unregisterClassLoader(cl);
+ assertUnregistered(domain2, cl);
+ }
+
+ public void testClassLoaderEventShutdownDomain() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain domain = system.getDefaultDomain();
+ domain.addClassLoaderEventHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ assertRegistered(domain, cl);
+
+ system.shutdown();
+ assertUnregistered(domain, cl);
+ }
+
+ public void testClassLoaderEventShutdownSystem() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain domain = system.getDefaultDomain();
+ system.addClassLoaderEventHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ assertRegistered(domain, cl);
+
+ system.shutdown();
+ assertUnregistered(domain, cl);
+ }
+
+ protected void assertRegistered(ClassLoaderDomain domain, ClassLoader expected)
+ {
+ assertTrue("Expected a registered", registered.isEmpty() == false);
+ ClassLoaderEvent event = registered.remove(0);
+ assertEquals(domain, event.getClassLoaderDomain());
+ assertEquals(domain, event.getSource());
+ assertEquals(expected, event.getClassLoader());
+ }
+
+ protected void assertNoRegistered()
+ {
+ assertTrue("Expected no registered: " + registered, registered.isEmpty());
+ }
+
+ protected void assertUnregistered(ClassLoaderDomain domain, ClassLoader expected)
+ {
+ assertTrue("Expected an unregistered", unregistered.isEmpty() == false);
+ ClassLoaderEvent event = unregistered.remove(0);
+ assertEquals(domain, event.getClassLoaderDomain());
+ assertEquals(domain, event.getSource());
+ assertEquals(expected, event.getClassLoader());
+ }
+
+ protected void assertNoUnregistered()
+ {
+ assertTrue("Expected no unregistered: " + unregistered, unregistered.isEmpty());
+ }
+}
Added: projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassNotFoundHandlerUnitTestCase.java
===================================================================
--- projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassNotFoundHandlerUnitTestCase.java (rev 0)
+++ projects/jboss-cl/trunk/classloader/src/test/java/org/jboss/test/classloader/notifications/test/ClassNotFoundHandlerUnitTestCase.java 2009-11-18 16:54:13 UTC (rev 96496)
@@ -0,0 +1,484 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.classloader.notifications.test;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import junit.framework.Test;
+
+import org.jboss.classloader.plugins.ClassLoaderUtils;
+import org.jboss.classloader.plugins.loader.ClassLoaderToLoaderAdapter;
+import org.jboss.classloader.spi.ClassLoaderDomain;
+import org.jboss.classloader.spi.ClassLoaderPolicy;
+import org.jboss.classloader.spi.ClassLoaderSystem;
+import org.jboss.classloader.spi.ClassNotFoundEvent;
+import org.jboss.classloader.spi.ClassNotFoundHandler;
+import org.jboss.classloader.spi.ParentPolicy;
+import org.jboss.classloader.test.support.MockClassLoaderPolicy;
+import org.jboss.test.classloader.AbstractClassLoaderTestWithSecurity;
+import org.jboss.test.classloader.notifications.support.a.A;
+
+/**
+ * ClassNotFoundHnadlerUnitTestCase
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassNotFoundHandlerUnitTestCase extends AbstractClassLoaderTestWithSecurity implements ClassNotFoundHandler
+{
+ public static Test suite()
+ {
+ return suite(ClassNotFoundHandlerUnitTestCase.class);
+ }
+
+ public ClassNotFoundHandlerUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ List<ClassNotFoundEvent> events = new CopyOnWriteArrayList<ClassNotFoundEvent>();
+
+ RegisterClassLoader runnable = null;
+
+ public boolean classNotFound(ClassNotFoundEvent event)
+ {
+ events.add(event);
+
+ if (runnable != null)
+ {
+ runnable.run();
+ return true;
+ }
+ return false;
+ }
+
+ public void testClassNotFoundHandlerPolicy() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.addClassNotFoundHandler(this);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ assertLoadClassFail("does.not.exist.ClassName", cl);
+ }
+
+ public void testClassNotFoundHandlerDomain() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain domain = system.getDefaultDomain();
+ domain.addClassNotFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClassFail("does.not.exist.ClassName", cl);
+ }
+
+ public void testClassNotFoundHandlerSystem() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ system.addClassNotFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ assertLoadClassFail("does.not.exist.ClassName", cl);
+ }
+
+ public void testClassNotFoundHandlerParentDomain() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+ ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, defaultDomain);
+ domain.addClassNotFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClassFail("does.not.exist.ClassName", cl);
+ }
+
+ public void testClassNotFoundHandlerParentClassLoader() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+
+ MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+ parentPolicy.addClassNotFoundHandler(this);
+ ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+ ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, new ClassLoaderToLoaderAdapter(parentCl));
+ domain.setUseLoadClassForParent(false);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ assertLoadClassFail("does.not.exist.ClassName", cl);
+ }
+
+ public void testClassNotFoundHandlerPolicyNoEvent() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setImportAll(true);
+ policy.addClassNotFoundHandler(this);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+ a.setPathsAndPackageNames(A.class);
+ ClassLoader expected = system.registerClassLoaderPolicy(a);
+
+ assertLoadClassNoEvent(A.class, cl, expected);
+ }
+
+ public void testClassNotFoundHandlerDomainNoEvent() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain domain = system.getDefaultDomain();
+ domain.addClassNotFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setImportAll(true);
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+ a.setPathsAndPackageNames(A.class);
+ ClassLoader expected = system.registerClassLoaderPolicy(a);
+
+ assertLoadClassNoEvent(A.class, cl, expected);
+ }
+
+ public void testClassNotFoundHandlerParentDomainNoEvent() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+ ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, defaultDomain);
+ domain.addClassNotFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+ a.setPathsAndPackageNames(A.class);
+ ClassLoader expected = system.registerClassLoaderPolicy(a);
+
+ assertLoadClassNoEvent(A.class, cl, expected);
+ }
+
+ public void testClassNotFoundHandlerParentClassLoaderNoEvent() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+
+ MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+ parentPolicy.setImportAll(true);
+ parentPolicy.addClassNotFoundHandler(this);
+ ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+ ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, new ClassLoaderToLoaderAdapter(parentCl));
+ domain.setUseLoadClassForParent(false);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+ a.setPathsAndPackageNames(A.class);
+ ClassLoader expected = system.registerClassLoaderPolicy(a);
+
+ assertLoadClassNoEvent(A.class, cl, expected);
+ }
+
+ public void testClassNotFoundHandlerSystemNoEvent() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ system.addClassNotFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setImportAll(true);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ MockClassLoaderPolicy a = createMockClassLoaderPolicy("a");
+ a.setPathsAndPackageNames(A.class);
+ ClassLoader expected = system.registerClassLoaderPolicy(a);
+
+ assertLoadClassNoEvent(A.class, cl, expected);
+ }
+
+ public void testClassNotFoundHandlerPolicyResolved() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setImportAll(true);
+ policy.addClassNotFoundHandler(this);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+ resolved.setPathsAndPackageNames(A.class);
+ runnable = new RegisterClassLoader(system, null, resolved);
+ assertLoadClass(A.class, cl, runnable);
+ assertLoadClassNoEvent(A.class, cl, runnable.getClassLoader());
+ }
+
+ public void testClassNotFoundHandlerDomainResolved() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain domain = system.getDefaultDomain();
+ domain.addClassNotFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setImportAll(true);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+ resolved.setPathsAndPackageNames(A.class);
+ runnable = new RegisterClassLoader(system, domain, resolved);
+ assertLoadClassFail("does.not.exist.ClassName", cl);
+ assertLoadClassNoEvent(A.class, cl, runnable.getClassLoader());
+ }
+
+ public void testClassNotFoundHandlerParentDomainResolved() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+ ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, defaultDomain);
+ domain.addClassNotFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+ resolved.setPathsAndPackageNames(A.class);
+ runnable = new RegisterClassLoader(system, null, resolved);
+ assertLoadClass(A.class, cl, runnable);
+ assertLoadClassNoEvent(A.class, cl, runnable.getClassLoader());
+ }
+
+ public void testClassNotFoundHandlerParentClassLoaderResolved() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+
+ MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+ parentPolicy.setImportAll(true);
+ parentPolicy.addClassNotFoundHandler(this);
+ ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+ ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, new ClassLoaderToLoaderAdapter(parentCl));
+ domain.setUseLoadClassForParent(false);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+ resolved.setPathsAndPackageNames(A.class);
+ runnable = new RegisterClassLoader(system, null, resolved);
+ assertLoadClass(A.class, cl, runnable);
+ assertLoadClassNoEvent(A.class, cl, runnable.getClassLoader());
+ }
+
+ public void testClassNotFoundHandlerSystemResolved() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ system.addClassNotFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setImportAll(true);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+ resolved.setPathsAndPackageNames(A.class);
+ runnable = new RegisterClassLoader(system, null, resolved);
+ assertLoadClass(A.class, cl, runnable);
+ assertLoadClassNoEvent(A.class, cl, runnable.getClassLoader());
+ }
+
+ public void testClassNotFoundHandlerPolicyNotResolved() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setImportAll(true);
+ policy.addClassNotFoundHandler(this);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+ resolved.setPathsAndPackageNames(A.class);
+ runnable = new RegisterClassLoader(system, null, resolved);
+ assertLoadClassFail("does.not.exist.ClassName", cl);
+ }
+
+ public void testClassNotFoundHandlerDomainNotResolved() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain domain = system.getDefaultDomain();
+ domain.addClassNotFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setImportAll(true);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+ resolved.setPathsAndPackageNames(A.class);
+ runnable = new RegisterClassLoader(system, domain, resolved);
+ assertLoadClassFail("does.not.exist.ClassName", cl);
+ }
+
+ public void testClassNotFoundHandlerParentDomainNotResolved() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+ ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, defaultDomain);
+ domain.addClassNotFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+ resolved.setPathsAndPackageNames(A.class);
+ runnable = new RegisterClassLoader(system, null, resolved);
+ assertLoadClassFail("does.not.exist.ClassName", cl);
+ }
+
+ public void testClassNotFoundHandlerParentClassLoaderNotResolved() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ ClassLoaderDomain defaultDomain = system.getDefaultDomain();
+
+ MockClassLoaderPolicy parentPolicy = createMockClassLoaderPolicy("parent");
+ parentPolicy.setImportAll(true);
+ parentPolicy.addClassNotFoundHandler(this);
+ ClassLoader parentCl = system.registerClassLoaderPolicy(defaultDomain, parentPolicy);
+
+ ClassLoaderDomain domain = system.createAndRegisterDomain("TestDomain", ParentPolicy.BEFORE, new ClassLoaderToLoaderAdapter(parentCl));
+ domain.setUseLoadClassForParent(false);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ ClassLoader cl = system.registerClassLoaderPolicy(domain, policy);
+
+ MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+ resolved.setPathsAndPackageNames(A.class);
+ runnable = new RegisterClassLoader(system, null, resolved);
+ assertLoadClassFail("does.not.exist.ClassName", cl);
+ }
+
+ public void testClassNotFoundHandlerSystemNotResolved() throws Exception
+ {
+ ClassLoaderSystem system = createClassLoaderSystemWithModifiedBootstrap();
+ system.addClassNotFoundHandler(this);
+
+ MockClassLoaderPolicy policy = createMockClassLoaderPolicy("test");
+ policy.setImportAll(true);
+ ClassLoader cl = system.registerClassLoaderPolicy(policy);
+
+ MockClassLoaderPolicy resolved = createMockClassLoaderPolicy("a");
+ resolved.setPathsAndPackageNames(A.class);
+ runnable = new RegisterClassLoader(system, null, resolved);
+ assertLoadClassFail("does.not.exist.ClassName", cl);
+ }
+
+ protected Class<?> assertLoadClassNoEvent(Class<?> reference, ClassLoader start, ClassLoader expected)
+ {
+ Class<?> result = assertLoadClass(reference, start, expected);
+ assertNoEvent();
+ return result;
+ }
+
+ protected Class<?> assertLoadClass(Class<?> reference, ClassLoader start, RegisterClassLoader runnable)
+ {
+ return assertLoadClass(reference, start, runnable, false);
+ }
+
+ protected Class<?> assertLoadClass(Class<?> reference, ClassLoader start, RegisterClassLoader runnable, boolean isReference)
+ {
+ String name = reference.getName();
+ Class<?> result = null;
+ try
+ {
+ result = start.loadClass(name);
+ getLog().debug("Got class: " + ClassLoaderUtils.classToString(result) + " for " + name + " from " + start);
+ }
+ catch (ClassNotFoundException e)
+ {
+ failure("Did not expect CNFE for " + name + " from " + start, e);
+ }
+ assertClassLoader(result, runnable.getClassLoader());
+ if (isReference)
+ assertClassEquality(reference, result);
+ else
+ assertNoClassEquality(reference, result);
+ assertEvent(name, start);
+ return result;
+ }
+
+ protected void assertLoadClassFail(String name, ClassLoader start)
+ {
+ super.assertLoadClassFail(name, start);
+ assertEvent(name, start);
+ }
+
+ protected void assertEvent(String name, ClassLoader start)
+ {
+ assertTrue("Expected an event", events.isEmpty() == false);
+ ClassNotFoundEvent event = events.remove(0);
+ assertEquals(name, event.getClassName());
+ assertEquals(start, event.getClassLoader());
+ assertEquals(start, event.getSource());
+ }
+
+ protected void assertNoEvent()
+ {
+ assertTrue("Expected no events: " + events, events.isEmpty());
+ }
+
+ class RegisterClassLoader implements Runnable
+ {
+ private ClassLoaderSystem system;
+ private ClassLoaderDomain domain;
+ private ClassLoaderPolicy policy;
+ private ClassLoader classLoader;
+
+ public RegisterClassLoader(ClassLoaderSystem system, ClassLoaderDomain domain, ClassLoaderPolicy policy)
+ {
+ this.system = system;
+ if (domain == null)
+ domain = system.getDefaultDomain();
+ this.domain = domain;
+ this.policy = policy;
+ }
+
+ public void run()
+ {
+ classLoader = system.registerClassLoaderPolicy(domain, policy);
+ }
+
+ public ClassLoader getClassLoader()
+ {
+ if (classLoader == null)
+ throw new Error("No classloader registered");
+ return classLoader;
+ }
+ }
+}
More information about the jboss-cvs-commits
mailing list