[Jboss-cvs] JBossAS SVN: r56431 - branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Aug 30 03:53:42 EDT 2006


Author: scott.stark at jboss.org
Date: 2006-08-30 03:53:38 -0400 (Wed, 30 Aug 2006)
New Revision: 56431

Modified:
   branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/ClassLoaderUtils.java
   branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/DomainClassLoaderUCLImpl.java
   branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/UnifiedLoaderRepository3.java
   branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/UnifiedLoaderRepositoryDCL.java
Log:
Refactory the class loader package name mapping to be usable with the legacy ucls and DomainClassLoaders

Modified: branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/ClassLoaderUtils.java
===================================================================
--- branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/ClassLoaderUtils.java	2006-08-30 07:52:42 UTC (rev 56430)
+++ branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/ClassLoaderUtils.java	2006-08-30 07:53:38 UTC (rev 56431)
@@ -57,7 +57,7 @@
    private static Logger log = Logger.getLogger(ClassLoaderUtils.class);
 
    /** The singleton instance of repository classloader comparator */
-   private static final Comparator repostiroyClassLoaderComparator = new RepositoryClassLoaderComparator();
+   private static final Comparator repositoryClassLoaderComparator = new RepositoryClassLoaderComparator();
 
    /** Format a string buffer containing the Class, Interfaces, CodeSource,
     and ClassLoader information for the given object clazz.
@@ -222,7 +222,7 @@
     */
    public static Set newPackageSet()
    {
-      return new TreeSet(repostiroyClassLoaderComparator);
+      return new TreeSet(repositoryClassLoaderComparator);
    }
 
    /**
@@ -237,21 +237,6 @@
       return (Set) original.clone();
    }
       
-   /** Given a UCL this method determine what packages
-    it contains and create a mapping from the package names to the cl.
-    * @param cl the UCL that loads from url
-    * @param packagesMap the Map<cl, String[]> to update
-    * @return the updated unique set of package names
-    * @throws Exception
-    */
-   public static String[] updatePackageMap(RepositoryClassLoader cl, Map packagesMap)
-      throws Exception
-   {
-      URL url = cl.getURL();
-      ClassPathIterator cpi = new ClassPathIterator(url);
-      HashSet pkgNameSet = new HashSet();
-      return updatePackageMap(cl, packagesMap, cpi, pkgNameSet);
-   }
    /** Augment the package name associated with a UCL.
     * @param cl the UCL that loads from url
     * @param packagesMap the Map<cl, String[]> to update
@@ -260,35 +245,13 @@
     * @return the updated unique set of package names
     * @throws Exception
     */
-   public static String[] updatePackageMap(RepositoryClassLoader cl, Map packagesMap,
-      URL url, String[] prevPkgNames)
+   public static void updatePackageMap(Object cl, URL url, PkgNameListener listener)
       throws Exception
    {
       ClassPathIterator cpi = new ClassPathIterator(url);
-      HashSet pkgNameSet = null;
-      if (prevPkgNames == null)
-         pkgNameSet = new HashSet();
-      else
-         pkgNameSet = new HashSet(Arrays.asList(prevPkgNames));
-      return updatePackageMap(cl, packagesMap, cpi, pkgNameSet);
+      updatePackageMap(cl, cpi, listener);
    }
 
-   /** Given a UCL this method determine what classes it contains
-    and create a mapping from the class names to the cl.
-    * @param cl the UCL that loads from url
-    * @param classNamesMap the Map<cl, String[]> to update
-    * @return the class names directly visible to the cl
-    * @throws Exception
-    */
-   public static String[] updateClassNamesMap(RepositoryClassLoader cl,
-      Map classNamesMap)
-      throws Exception
-   {
-      URL url = cl.getURL();
-      ClassPathIterator cpi = new ClassPathIterator(url);
-      HashSet classNameSet = new HashSet();
-      return updateClassNamesMap(cl, classNamesMap, cpi, classNameSet);
-   }
    /** Augment the class names associated with a UCL.
     * @param cl the UCL that loads from url
     * @param classNamesMap the Map<cl, String[]> to update
@@ -297,7 +260,7 @@
     * @return the updated list of class names
     * @throws Exception
     */
-   public static String[] updateClassNamesMap(RepositoryClassLoader cl,
+   public static String[] updateClassNamesMap(Object cl,
       Map classNamesMap, URL url, String[] prevClassNames)
       throws Exception
    {
@@ -310,11 +273,9 @@
       return updateClassNamesMap(cl, classNamesMap, cpi, classNameSet);
    }
 
-   static String[] updatePackageMap(RepositoryClassLoader cl, Map packagesMap,
-      ClassPathIterator cpi, HashSet pkgNameSet)
+   static void updatePackageMap(Object cl, ClassPathIterator cpi, PkgNameListener listener)
       throws Exception
    {
-      boolean trace = log.isTraceEnabled();
       ClassPathEntry entry;
       while( (entry = cpi.getNextEntry()) != null )
       {
@@ -322,7 +283,7 @@
          // First look for a META-INF/INDEX.LIST entry
          if( name.equals("META-INF/INDEX.LIST") )
          {
-            readJarIndex(cl, cpi, packagesMap, pkgNameSet);
+            readJarIndex(cl, cpi, /*packagesMap, pkgNameSet*/ listener);
             // We are done
             break;
          }
@@ -332,17 +293,12 @@
             continue;
 
          String pkgName = entry.toPackageName();
-         addPackage(pkgName, packagesMap, pkgNameSet, cl, trace);
+         listener.addPackage(pkgName, cl);
       }
       cpi.close();
-
-      // Return an array of the package names
-      String[] pkgNames = new String[pkgNameSet.size()];
-      pkgNameSet.toArray(pkgNames);
-      return pkgNames;
    }
 
-   static String[] updateClassNamesMap(RepositoryClassLoader cl, Map classNamesMap,
+   static String[] updateClassNamesMap(Object cl, Map classNamesMap,
       ClassPathIterator cpi, HashSet classNameSet)
       throws Exception
    {
@@ -372,8 +328,8 @@
    /** Read the JDK 1.3+ META-INF/INDEX.LIST entry to obtain the package
     names without having to iterate through all entries in the jar.
     */
-   private static void readJarIndex(RepositoryClassLoader cl, ClassPathIterator cpi,
-      Map packagesMap, Set pkgNameSet)
+   private static void readJarIndex(Object cl, ClassPathIterator cpi,
+      /*Map packagesMap, Set pkgNameSet,*/ PkgNameListener listener)
       throws Exception
    {
       boolean trace = log.isTraceEnabled();
@@ -396,38 +352,11 @@
          if( line.length() == 0 )
             break;
          String pkgName = line.replace('/', '.');
-         addPackage(pkgName, packagesMap, pkgNameSet, cl, trace);
+         listener.addPackage(pkgName, cl);
       }
       br.close();
    }
 
-   private static void addPackage(String pkgName, Map packagesMap,
-      Set pkgNameSet, RepositoryClassLoader cl, boolean trace)
-   {
-      // Skip the standard J2EE archive directories
-      if( pkgName.startsWith("META-INF") || pkgName.startsWith("WEB-INF") )
-         return;
-
-      Set pkgSet = (Set) packagesMap.get(pkgName);
-      if( pkgSet == null )
-      {
-         pkgSet = newPackageSet();
-         packagesMap.put(pkgName, pkgSet);
-      }
-      if( pkgSet.contains(cl) == false )
-      {
-         pkgSet.add(cl);
-         pkgNameSet.add(pkgName);
-         // Anytime more than one class loader exists this may indicate a problem
-         if( pkgSet.size() > 1 )
-         {
-            log.debug("Multiple class loaders found for pkg: "+pkgName);
-         }
-         if( trace )
-            log.trace("Indexed pkg: "+pkgName+", UCL: "+cl);
-      }
-   }
-
    /** Add a class name to the UCL map.
     * @param jarClassName the class name in the jar (java/lang/String.class)
     * @param classNamesMap the UCL class name mappings
@@ -435,7 +364,7 @@
     * @param trace the logging trace level flag
     */
    private static void addClass(String jarClassName, Map classNamesMap,
-      RepositoryClassLoader cl, boolean trace)
+      Object cl, boolean trace)
    {
       LinkedList ucls = (LinkedList) classNamesMap.get(jarClassName);
       if( ucls == null )
@@ -458,6 +387,11 @@
          log.trace("Indexed class: "+jarClassName+", UCL: "+ucls.get(0));
    }
 
+   public static interface PkgNameListener
+   {
+      public void addPackage(String name, Object loader);
+   }
+
    /**
    */
    static class FileIterator

Modified: branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/DomainClassLoaderUCLImpl.java
===================================================================
--- branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/DomainClassLoaderUCLImpl.java	2006-08-30 07:52:42 UTC (rev 56430)
+++ branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/DomainClassLoaderUCLImpl.java	2006-08-30 07:53:38 UTC (rev 56431)
@@ -13,7 +13,6 @@
 import javax.management.ObjectName;
 
 import org.jboss.logging.Logger;
-import org.jboss.util.loading.Translatable;
 
 /**
 * A port of the UnifiedClassLoader3 to a DomainClassLoader
@@ -26,7 +25,7 @@
 * @version $Revision: 44243 $
 */
 public class DomainClassLoaderUCLImpl extends LegacyDomainClassLoader
-   implements UnifiedClassLoaderMBean, Translatable
+   implements UnifiedClassLoaderMBean
 {
    // Static --------------------------------------------------------
 
@@ -34,85 +33,8 @@
 
    // Attributes ----------------------------------------------------
 
-   /** One URL per ClassLoader in our case */
-   protected URL url = null;
-   /** An optional URL from which url may have been copied. It is used to
-    allow the security permissions to be based on a static url namespace. */
-   protected URL origURL = null;
-
    // Constructors --------------------------------------------------
    /**
-    * Construct a DomainClassLoaderUCLImpl without registering it to the
-    * classloader repository.
-    *
-    * @param url   the single URL to load classes from.
-    */
-   public DomainClassLoaderUCLImpl(URL url)
-   {
-      this(url, (URL) null);
-   }
-   /**
-    * Construct a DomainClassLoaderUCLImpl without registering it to the
-    * classloader repository.
-    *
-    * @param url   the single URL to load classes from.
-    * @param origURL the possibly null original URL from which url may
-    * be a local copy or nested jar.
-    */
-   public DomainClassLoaderUCLImpl(URL url, URL origURL)
-   {
-      this(url, origURL, DomainClassLoaderUCLImpl.class.getClassLoader());
-   }
-
-   /**  Construct a DomainClassLoaderUCLImpl without registering with the
-    * classloader repository.
-    *
-    * @param url   the single URL to load classes from.
-    * @param origURL the possibly null original URL from which url may
-    * be a local copy or nested jar.
-    * @param parent the parent class loader to use
-    */
-   public DomainClassLoaderUCLImpl(URL url, URL origURL, ClassLoader parent)
-   {
-      super(url == null ? new URL[]{} : new URL[] {url}, parent);
-
-      if (log.isTraceEnabled())
-         log.trace("New jmx UCL with url " + url);
-      this.url = url;
-      this.origURL = origURL;
-   }
-
-   /**
-    * Construct a DomainClassLoaderUCLImpl and registers it to the given
-    * repository.
-    *
-    * @param   url   The single URL to load classes from.
-    * @param   repository the repository this classloader delegates to
-    */
-   public DomainClassLoaderUCLImpl(URL url, LoaderRepositoryDomain repository)
-   {
-      this(url, null, repository);
-   }
-   /**
-    * Construct a DomainClassLoaderUCLImpl and registers it to the given
-    * repository.
-    * @param url The single URL to load classes from.
-    * @param origURL the possibly null original URL from which url may
-    * be a local copy or nested jar.
-    * @param repository the repository this classloader delegates to
-    */
-   public DomainClassLoaderUCLImpl(URL url, URL origURL, LoaderRepositoryDomain repository)
-   {
-      this(url, origURL);
-
-      // set the repository reference
-      this.setDomain(repository);
-
-      // register this loader to the given repository
-      repository.addClassLoader(this);
-   }
-
-   /**
     * Construct a DomainClassLoaderUCLImpl with the given classpath and register
     * it to the given repository.
     * @param cp - the loader classpath
@@ -122,49 +44,10 @@
    {
       super(cp, null);
 
-      // set the repository reference
-      this.setDomain(repository);
-
       // register this loader to the given repository
       repository.addClassLoader(this);
    }
 
-   /**
-    * DomainClassLoaderUCLImpl constructor that can be used to
-    * register with a particular Loader Repository identified by ObjectName.
-    *
-    * @param url an <code>URL</code> value
-    * @param server a <code>MBeanServer</code> value
-    * @param repositoryName an <code>ObjectName</code> value
-    * @exception Exception if an error occurs
-    */
-   public DomainClassLoaderUCLImpl(final URL url, final MBeanServer server,
-      final ObjectName repositoryName) throws Exception
-   {
-      this(url, null, server, repositoryName);
-   }
-   /**
-    * DomainClassLoaderUCLImpl constructor that can be used to
-    * register with a particular Loader Repository identified by ObjectName.
-    *
-    * @param url an <code>URL</code> value
-    * @param origURL the possibly null original URL from which url may
-    * be a local copy or nested jar.
-    * @param server a <code>MBeanServer</code> value
-    * @param repositoryName an <code>ObjectName</code> value
-    * @exception Exception if an error occurs
-    */
-   public DomainClassLoaderUCLImpl(final URL url, final URL origURL,
-      final MBeanServer server, final ObjectName repositoryName) throws Exception
-   {
-      this(url, origURL);
-      LoaderRepositoryDomain rep = (LoaderRepositoryDomain)server.invoke(repositoryName,
-                    "registerClassLoader",
-                    new Object[] {this},
-                    new String[] {getClass().getName()});
-      this.setDomain(rep);
-   }
-
    // Public --------------------------------------------------------
 
    /** Obtain the ObjectName under which the UCL can be registered with the
@@ -177,32 +60,20 @@
       return new ObjectName(name);
    }
 
-   public String[] getPackagNames()
+   /**
+    * Get the class loader package names from the class loader URLs
+    */
+   public String[] getPackageNames()
    {
-      // TODO Auto-generated method stub
-      return null;
+      UnifiedLoaderRepositoryDCL ulr = (UnifiedLoaderRepositoryDCL) domain;
+      return ulr.getPackageNames(this);
    }
+
    public void unregister()
    {
       super.unregister();
-      this.origURL = null;
-      this.url = null;
    }
 
-   /** Get the URL associated with the UCL.
-    */
-   public URL getURL()
-   {
-      return url;
-   }
-   
-   /** Get the original URL associated with the UCL. This may be null.
-    */
-   public URL getOrigURL()
-   {
-      return origURL;
-   }
-   
    public synchronized Class loadClassImpl(String name, boolean resolve, int stopAt)
       throws ClassNotFoundException
    {
@@ -332,10 +203,6 @@
    protected PermissionCollection getPermissions(CodeSource cs)
    {
       CodeSource permCS = cs;
-      if( origURL != null )
-      {
-         permCS = new CodeSource(origURL, cs.getCertificates());
-      }
       Policy policy = Policy.getPolicy();
       PermissionCollection perms = super.getPermissions(permCS);
       PermissionCollection perms2 = super.getPermissions(cs);
@@ -347,19 +214,8 @@
       while( iter.hasMoreElements() )
          perms.add((Permission) iter.nextElement());
       if( log.isTraceEnabled() )
-         log.trace("getPermissions, url="+url+", origURL="+origURL+" -> "+perms);
+         log.trace("getPermissions, cp: "+getURLs()+" -> "+perms);
       return perms;
    }
 
-   /**
-    * Determine the protection domain. If we are a copy of the original
-    * deployment, use the original url as the codebase.
-    * @return the protection domain
-    * @todo certificates and principles?
-    */
-   protected ProtectionDomain getProtectionDomain()
-   {
-      return getProtectionDomain(origURL != null ? origURL : url);
-   }
 }
-

Modified: branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/UnifiedLoaderRepository3.java
===================================================================
--- branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/UnifiedLoaderRepository3.java	2006-08-30 07:52:42 UTC (rev 56430)
+++ branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/UnifiedLoaderRepository3.java	2006-08-30 07:53:38 UTC (rev 56431)
@@ -32,6 +32,7 @@
 import java.util.Enumeration;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeSet;
 import java.io.IOException;
 
 import javax.management.ListenerNotFoundException;
@@ -132,7 +133,7 @@
     * they serve
     * Access synchronized via this.packagesMap monitor.
     */
-   private HashMap loaderToPackagesMap = new HashMap();
+   private HashMap<RepositoryClassLoader, List<String>> loaderToPackagesMap = new HashMap<RepositoryClassLoader, List<String>>();
 
    /**
     * The sequenceNumber used to number notifications.
@@ -781,8 +782,9 @@
    {
       try
       {
-         String[] pkgNames = ClassLoaderUtils.updatePackageMap(cl, packagesMap);
-         loaderToPackagesMap.put(cl, pkgNames);
+         URL url = cl.getURL();
+         PackageMapper listener = new PackageMapper();
+         ClassLoaderUtils.updatePackageMap(cl, url, listener);
       }
       catch (Exception e)
       {
@@ -800,9 +802,8 @@
    {
       try
       {
-         String[] prevPkgNames = (String[]) loaderToPackagesMap.get(cl);
-         String[] pkgNames = ClassLoaderUtils.updatePackageMap(cl, packagesMap, url, prevPkgNames);
-         loaderToPackagesMap.put(cl, pkgNames);
+         PackageMapper listener = new PackageMapper();
+         ClassLoaderUtils.updatePackageMap(cl, url, listener);
       }
       catch (Exception e)
       {
@@ -892,18 +893,16 @@
          // Clean up the package name to class loader mapping
          if (dynamic == false)
          {
-            String[] pkgNames = (String[]) loaderToPackagesMap.remove(cl);
-            int length = pkgNames != null ? pkgNames.length : 0;
-            for (int p = 0; p < length; p++)
+            List<String> pkgNames = loaderToPackagesMap.remove(cl);
+            for(String pkgName : pkgNames)
             {
-               String pkgName = pkgNames[p];
                Set pkgSet = (Set) packagesMap.get(pkgName);
                if (pkgSet != null)
                {
                   pkgSet.remove(cl);
                   if (pkgSet.isEmpty())
                      packagesMap.remove(pkgName);
-               }
+               }               
             }
          }
          else
@@ -1057,4 +1056,40 @@
          return rcl;
       }
    }
+
+   private class PackageMapper implements ClassLoaderUtils.PkgNameListener
+   {
+      public void addPackage(String pkgName, Object loader)
+      {
+         // Skip the standard J2EE archive directories
+         if( pkgName.startsWith("META-INF") || pkgName.startsWith("WEB-INF") )
+            return;
+
+         Set<RepositoryClassLoader> pkgSet = (Set<RepositoryClassLoader>) packagesMap.get(pkgName);
+         if( pkgSet == null )
+         {
+            pkgSet = ClassLoaderUtils.newPackageSet();
+            packagesMap.put(pkgName, pkgSet);
+         }
+         if( pkgSet.contains(loader) == false )
+         {
+            pkgSet.add((RepositoryClassLoader)loader);
+            List<String> loaderPkgNames = loaderToPackagesMap.get(loader);
+            if( loaderPkgNames == null )
+            {
+               loaderPkgNames = new ArrayList<String>();
+               loaderToPackagesMap.put((RepositoryClassLoader)loader, loaderPkgNames);
+            }
+            loaderPkgNames.add(pkgName);
+
+            // Anytime more than one class loader exists this may indicate a problem
+            if( pkgSet.size() > 1 )
+            {
+               log.debug("Multiple class loaders found for pkg: "+pkgName);
+            }
+            if( log.isTraceEnabled() )
+               log.trace("Indexed pkg: "+pkgName+", UCL: "+loader);
+         }
+      }
+   }
 }

Modified: branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/UnifiedLoaderRepositoryDCL.java
===================================================================
--- branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/UnifiedLoaderRepositoryDCL.java	2006-08-30 07:52:42 UTC (rev 56430)
+++ branches/MC_VDF_WORK/jmx/src/main/org/jboss/mx/loading/UnifiedLoaderRepositoryDCL.java	2006-08-30 07:53:38 UTC (rev 56431)
@@ -26,6 +26,7 @@
 import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -33,6 +34,7 @@
 import java.util.Enumeration;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeSet;
 import java.io.IOException;
 
 import javax.management.ListenerNotFoundException;
@@ -44,12 +46,11 @@
 import javax.management.MBeanRegistration;
 import javax.management.ObjectName;
 import javax.management.MBeanServer;
-import javax.management.loading.MLet;
 
 import org.jboss.classloading.spi.ClassLoadingDomain;
 import org.jboss.classloading.spi.DomainClassLoader;
-import org.jboss.classloading.spi.Translator;
 import org.jboss.logging.Logger;
+import org.jboss.mx.loading.LoadMgr3.PkgClassLoader;
 import org.jboss.mx.util.JBossNotificationBroadcasterSupport;
 import org.jboss.util.Classes;
 
@@ -136,7 +137,7 @@
     * they serve
     * Access synchronized via this.packagesMap monitor.
     */
-   private HashMap loaderToPackagesMap = new HashMap();
+   private HashMap<DomainClassLoader, List<String>> loaderToPackagesMap = new HashMap<DomainClassLoader, List<String>>();
 
    /**
     * The sequenceNumber used to number notifications.
@@ -159,7 +160,8 @@
    public DomainClassLoader newClassLoader(final URL url, boolean addToRepository)
            throws Exception
    {
-      DomainClassLoaderUCLImpl ucl = new DomainClassLoaderUCLImpl(url, null, this);
+      URL[] cp = {url};
+      DomainClassLoaderUCLImpl ucl = new DomainClassLoaderUCLImpl(cp, this);
       if (addToRepository)
          this.registerClassLoader(ucl);
       return ucl;
@@ -168,7 +170,8 @@
    public DomainClassLoader newClassLoader(final URL url, final URL origURL, boolean addToRepository)
            throws Exception
    {
-      DomainClassLoaderUCLImpl ucl = new DomainClassLoaderUCLImpl(url, origURL, this);
+      URL[] cp = {url};
+      DomainClassLoaderUCLImpl ucl = new DomainClassLoaderUCLImpl(cp, this);
       if (addToRepository)
          this.registerClassLoader(ucl);
       return ucl;
@@ -654,7 +657,7 @@
    public void addClassLoader(DomainClassLoader loader)
    {
       // if you come to us as UCL we send you straight to the orbit
-      addDomainClassLoader((DomainClassLoader) loader);
+      addDomainClassLoader((DomainClassLoaderUCLImpl) loader);
    }
 
    public boolean addClassLoaderURL(DomainClassLoader cl, URL url)
@@ -697,7 +700,7 @@
     * This sychronizes on classLoaders.
     * @param cl
     */
-   private void addDomainClassLoader(DomainClassLoader cl)
+   private void addDomainClassLoader(DomainClassLoaderUCLImpl cl)
    {
       cl.setDomain(this);
       boolean added = false;
@@ -711,6 +714,7 @@
          {
             log.debug("Adding " + cl);
             addedCount++;
+            cl.setAddedOrder(addedCount);
             updatePackageMap(cl);
          }
          else
@@ -723,12 +727,17 @@
    /** Walk through the class loader URL to see what packages it is capable
     of handling
     */
-   private void updatePackageMap(DomainClassLoader cl)
+   private synchronized void updatePackageMap(DomainClassLoader cl)
    {
+      boolean trace = log.isTraceEnabled();
       try
       {
-         String[] pkgNames = cl.getPackagNames();
-         loaderToPackagesMap.put(cl, pkgNames);
+         PackageMapper listener = new PackageMapper();
+         URL[] cp = cl.getClasspath();
+         for(URL url : cp)
+         {
+            ClassLoaderUtils.updatePackageMap(cl, url, listener);
+         }
       }
       catch (Exception e)
       {
@@ -818,18 +827,16 @@
          // Clean up the package name to class loader mapping
          if (dynamic == false)
          {
-            String[] pkgNames = (String[]) loaderToPackagesMap.remove(cl);
-            int length = pkgNames != null ? pkgNames.length : 0;
-            for (int p = 0; p < length; p++)
+            List<String> pkgNames = loaderToPackagesMap.remove(cl);
+            for(String pkgName : pkgNames)
             {
-               String pkgName = pkgNames[p];
                Set pkgSet = (Set) packagesMap.get(pkgName);
                if (pkgSet != null)
                {
                   pkgSet.remove(cl);
                   if (pkgSet.isEmpty())
                      packagesMap.remove(pkgName);
-               }
+               }               
             }
          }
          else
@@ -965,10 +972,108 @@
       loaderToPackagesMap.clear();
    }
 
+   /**
+    * lookup the package names for a given class loader
+    * @param loader
+    * @return
+    */
+   String[] getPackageNames(DomainClassLoaderUCLImpl loader)
+   {
+      List<String> pkgNames = loaderToPackagesMap.get(loader);
+      String[] tmp = {};
+      if( pkgNames != null )
+      {
+         tmp = new String[pkgNames.size()];
+         pkgNames.toArray(tmp);
+      }
+      return tmp;
+   }
+
    private synchronized long getNextSequenceNumber()
    {
       return sequenceNumber++;
    }
 
+   /**
+    * A comparator for comparing repository classloaders
+    */
+   private static class DomainClassLoaderUCLImplComparator implements Comparator
+   {
+      /**
+       * Compares two repository classloaders, they are ordered by:
+       * 1) parent->child delegation rules in the loader repository
+       * 2) added order inside the loader repository
+       */
+      public int compare(Object o1, Object o2)
+      {
+         if (o1 instanceof PkgClassLoader)
+         {
+            PkgClassLoader pkg1 = (PkgClassLoader) o1;
+            PkgClassLoader pkg2 = (PkgClassLoader) o2;
+            RepositoryClassLoader rcl1 = pkg1.ucl;
+            RepositoryClassLoader rcl2 = pkg2.ucl;
+            // We use the package classloader ordering before the repository order
+            int test = (pkg1.order - pkg2.order);
+            if (test != 0)
+               return test;
+            else
+               return rcl1.getAddedOrder() - rcl2.getAddedOrder();
+         }
+         else
+         {
+            DomainClassLoaderUCLImpl rcl1 = (DomainClassLoaderUCLImpl) o1;
+            DomainClassLoaderUCLImpl rcl2 = (DomainClassLoaderUCLImpl) o2;
+            return rcl1.getAddedOrder() - rcl2.getAddedOrder();
+            
+            // REVIEW: Alternative to using the pkgClassLoader is
+            //         ordering based on the loader repository
+            
+            //LoaderRepository lr1 = rcl1.getLoaderRepository();
+            //LoaderRepository lr2 = rcl2.getLoaderRepository();
 
+            // Are the loader repositories ordered?
+            //int test = lr1.compare(lr2);
+            //if (test != 0)
+            //   return test;
+            //else
+            //   return rcl1.getAddedOrder() - rcl2.getAddedOrder();
+         }
+      }
+   }
+
+   class PackageMapper implements ClassLoaderUtils.PkgNameListener
+   {
+      public void addPackage(String pkgName, Object loader)
+      {
+         // Skip the standard J2EE archive directories
+         if( pkgName.startsWith("META-INF") || pkgName.startsWith("WEB-INF") )
+            return;
+
+         Set<DomainClassLoader> pkgSet = (Set<DomainClassLoader>) packagesMap.get(pkgName);
+         if( pkgSet == null )
+         {
+            pkgSet = new TreeSet<DomainClassLoader>(new DomainClassLoaderUCLImplComparator());
+            packagesMap.put(pkgName, pkgSet);
+         }
+         if( pkgSet.contains(loader) == false )
+         {
+            pkgSet.add((DomainClassLoader)loader);
+            List<String> loaderPkgNames = loaderToPackagesMap.get(loader);
+            if( loaderPkgNames == null )
+            {
+               loaderPkgNames = new ArrayList<String>();
+               loaderToPackagesMap.put((DomainClassLoader)loader, loaderPkgNames);
+            }
+            loaderPkgNames.add(pkgName);
+
+            // Anytime more than one class loader exists this may indicate a problem
+            if( pkgSet.size() > 1 )
+            {
+               log.debug("Multiple class loaders found for pkg: "+pkgName);
+            }
+            if( log.isTraceEnabled() )
+               log.trace("Indexed pkg: "+pkgName+", UCL: "+loader);
+         }
+      }
+   }
 }




More information about the jboss-cvs-commits mailing list