Community

Classloading and caching changes

reply from Ales Justin in JBoss Microcontainer Development - View the full discussion

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

Reply to this message by going to Community

Start a new discussion in JBoss Microcontainer Development at Community