So, once we determined what we need to do, this is how it's impled atm.
A new CachedLoader interface was introduced
public interface CacheLoader extends Loader
{
/**
* Check the class cache.
*
* @param classLoader the reference classloader (possibly null)
* @param name the name of the class
* @param path the path of the class resource
* @param allExports whether to look at all exports
* @return the class if cached
*/
Class<?> checkClassCache(BaseClassLoader classLoader, String name, String path, boolean allExports);
}
where the BaseClassLoaderDomain does before and after checks
public Class<?> checkClassCache(BaseClassLoader classLoader, String name, String path, boolean allExports)
{
Class<?> result = checkCacheBefore(classLoader, name, path, allExports);
if (result != null)
return result;
result = checkCacheAfter(classLoader, name, path, allExports);
if (result != null)
return result;
result = checkClassCacheLocally(classLoader, name, path, allExports);
if (result != null)
return result;
return null;
}
where the actual impl lives in ClassLoaderDomain
protected Class<?> checkCacheBefore(BaseClassLoader classLoader, String name, String path, boolean allExports)
{
if (parent == null || parent instanceof CacheLoader == false)
return null;
ClassFilter filter = getParentPolicy().getBeforeFilter();
if (filter.matchesClassName(name))
{
CacheLoader loader = (CacheLoader) parent;
return loader.checkClassCache(classLoader, name, path, allExports);
}
return null;
}
/**
* Only check parent after if we already blacklisted this resource.
*/
@Override
protected Class<?> checkCacheAfter(BaseClassLoader classLoader, String name, String path, boolean allExports)
{
if (parent == null || parent instanceof CacheLoader == false || isBlackListedClass(path) == false)
return null;
ClassFilter filter = getParentPolicy().getAfterFilter();
if (filter.matchesClassName(name))
{
CacheLoader loader = (CacheLoader) parent;
return loader.checkClassCache(classLoader, name, path, allExports);
}
return null;
}
The 3 current CacheLoader impls are
* BaseClassLoaderDomain (we already saw its impl)
* BaseDelegateLoader (it just delegates to its domain)
* ClassLoaderToLoaderAdapter (see below)
public Class<?> checkClassCache(BaseClassLoader bcl, String name, String path, boolean allExports)
{
if (findLoadedClass == null)
return null;
final ClassLoader classLoader = getClassLoader();
try
{
return (Class<?>) findLoadedClass.invoke(classLoader, name);
}
catch (Exception e)
{
log.warn("Unexpected error retrieving found class " + name + " from classloader " + classLoader, e);
return null;
}
}
I have also hacked a simple debug-able mock in Deployers project -- where we can check different deployment types
* http://anonsvn.jboss.org/repos/jbossas/projects/jboss-deployers/trunk/deployers-vfs/src/test/java/org/jboss/test/deployers/vfs/classloading/test/ClassLoaderCachingTestCase.java