User: mnf999  
  Date: 02/01/20 07:20:39

  Modified:    src/main/org/jboss/system ServiceLibraries.java
  Log:
  Unified ClassLoaders
  
  Revision  Changes    Path
  1.13      +201 -194  jboss/src/main/org/jboss/system/ServiceLibraries.java
  
  Index: ServiceLibraries.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/system/ServiceLibraries.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- ServiceLibraries.java     2002/01/04 00:15:07     1.12
  +++ ServiceLibraries.java     2002/01/20 15:20:33     1.13
  @@ -1,10 +1,9 @@
   /*
  - * JBoss, the OpenSource J2EE webOS
  - *
  - * Distributable under LGPL license.
  - * See terms of license at gnu.org.
  - */
  -
  +* JBoss, the OpenSource J2EE webOS
  +*
  +* Distributable under LGPL license.
  +* See terms of license at gnu.org.
  +*/
   package org.jboss.system;
   
   import java.net.URL;
  @@ -18,203 +17,212 @@
   import javax.management.MBeanRegistration;
   import javax.management.MBeanServer;
   import javax.management.ObjectName;
  +
   
  -import org.jboss.system.URLClassLoader;
  +//import org.jboss.logging.log4j.JBossCategory;
   
  -/** 
  - * Service Libraries. The service libraries is a central repository of all
  - * classes loaded by the ClassLoaders
  - *
  - * @author <a href="mailto:[EMAIL PROTECTED]";>Marc Fleury</a>
  - * @author <a href="mailto:[EMAIL PROTECTED]";>Ole Husgaard</a>
  - * @version $Revision: 1.12 $ <p>
  - *
  - * <b>20010830 marc fleury:</b>
  - * <ul>
  - *   <li>initial import
  - * </ul>
  - *
  - * <b>20010908 david jencks:</b>
  - * <ul>
  - *   <li>Modified to make undeploy work better.
  - * </ul>
  - *
  - * <b>20011003 Ole Husgaard:</b>
  - * <ul>
  - *   <li>Changed synchronization to avoid deadlock with SUNs
  - *       java.lang.Classloader implementation. Kudos to Dr. Christoph Jung
  - *       and Sacha Labourey for identifying this problem.
  - * </ul>
  - */
  +/**
  +* Service Libraries. The service libraries is a central repository of all
  +* classes loaded by the ClassLoaders
  +*
  +* @see <related>
  +* @author <a href="mailto:[EMAIL PROTECTED]";>Marc Fleury</a>
  +* @author <a href="mailto:[EMAIL PROTECTED]";>Ole Husgaard</a>
  +* @version $Revision: 1.13 $ <p>
  +*
  +*      <b>20010830 marc fleury:</b>
  +*      <ul>initial import
  +*        <li>
  +*      </ul>
  +*      <b>20010908 david jencks:</b>
  +*      <ul>Modified to make undeploy work better.
  +*        <li>
  +*      <b>20011003 Ole Husgaard:</b>
  +*      <ul>Changed synchronization to avoid deadlock with SUNs
  +*          java.lang.Classloader implementation. Kudos to Dr. Christoph Jung
  +*          and Sacha Labourey for identifying this problem.
  +*        <li>
  +*      </ul>
  +*
  +*/
   public class ServiceLibraries
  -   implements ServiceLibrariesMBean, MBeanRegistration
  +implements ServiceLibrariesMBean, MBeanRegistration
   {
      /** The bootstrap interface to the log4j system */
  -   private static BootstrapLogger log = 
  -      BootstrapLogger.getLogger(ServiceLibraries.class);
  +   private static BootstrapLogger log = 
BootstrapLogger.getLogger(ServiceLibraries.class);
  +   
  +   // Static --------------------------------------------------------
   
      private static ServiceLibraries libraries;
  -
  +   
  +   // Constants -----------------------------------------------------
  +   
  +   // Attributes ----------------------------------------------------
  +   
  +   
      /**
  -    * The classloaders we use for loading classes here.
  -    */
  +   *  The classloaders we use for loading classes here.
  +   */
      private Set classLoaders;
  -
  -   /**
  -    * Maps class names of the classes loaded here to the classes.
  -    */
  +   
  +   /*
  +   *  Maps class names of the classes loaded here to the classes.
  +   */
      private Map classes;
  -
  -   /**
  -    * Maps class loaders to the set of classes they loaded here.
  -    */
  +   
  +   /*
  +   *  Maps class loaders to the set of classes they loaded here.
  +   */
      private Map clToClassSetMap;
  -
  +   
      /**
  -    * The version number of the {@link #clToClassSetMap} map.
  -    * If a lookup of a class detects a change in this while calling
  -    * the classloaders with locks removed, the {@link #clToClassSetMap}
  -    * and {@link #classes} fields should <em>only</em> be modified
  -    * if the classloader used for loading the class is still in the
  -    * {@link #classLoaders} set.
  -    */
  +   *  The version number of the {@link #clToClassSetMap} map.
  +   *  If a lookup of a class detects a change in this while calling
  +   *  the classloaders with locks removed, the {@link #clToClassSetMap}
  +   *  and {@link #classes} fields should <em>only</em> be modified
  +   *  if the classloader used for loading the class is still in the
  +   *  {@link #classLoaders} set.
  +   */
      private long clToClassSetMapVersion = 0;
  -
  -   /**
  -    * Maps resource names of resources looked up here to the URLs used to
  -    * load them.
  -    */
  +   
  +   /*
  +   *  Maps resource names of resources looked up here to the URLs used to
  +   *  load them.
  +   */
      private Map resources;
  -
  -   /**
  -    * Maps class loaders to the set of resource names they looked up here.
  -    */
  +   
  +   /*
  +   *  Maps class loaders to the set of resource names they looked up here.
  +   */
      private Map clToResourceSetMap;
  -
  +   
      /**
  -    * The version number of the {@link #clToResourceSetMap} map.
  -    * If a lookup of a resource detects a change in this while
  -    * calling the classloaders with locks removed, the
  -    * {@link #clToResourceSetMap} and {@link #resources} fields should
  -    * <em>only</em> be modified if the classloader used for loading
  -    * the class is still in the {@link #classLoaders} set.
  -    */
  +   *  The version number of the {@link #clToResourceSetMap} map.
  +   *  If a lookup of a resource detects a change in this while
  +   *  calling the classloaders with locks removed, the
  +   *  {@link #clToResourceSetMap} and {@link #resources} fields should
  +   *  <em>only</em> be modified if the classloader used for loading
  +   *  the class is still in the {@link #classLoaders} set.
  +   */
      private long clToResourceSetMapVersion = 0;
  -
  -   /**
  -    * Gets the Libraries attribute of the ServiceLibraries class
  -    *
  -    * @return The Libraries value
  -    */
  +   
  +   // Constructors --------------------------------------------------
  +   
  +   // Public --------------------------------------------------------
  +   
  +   /**
  +   * Gets the Libraries attribute of the ServiceLibraries class
  +   *
  +   * @return The Libraries value
  +   */
      public static ServiceLibraries getLibraries()
      {
         if (libraries == null)
            libraries = new ServiceLibraries();
  -
  +      
         return libraries;
      }
  -
  +   
      // ServiceClassLoaderMBean implementation ------------------------
  -
  +   
      /**
  -    * Gets the Name attribute of the ServiceLibraries object.
  -    *
  -    * @return The Name value
  -    */
  +   * Gets the Name attribute of the ServiceLibraries object.
  +   *
  +   * @return The Name value
  +   */
      public String getName()
      {
         return "ServiceLibraries";
      }
   
      /**
  -    * Find a resource in the ServiceLibraries object.
  -    *
  -    * @param name   The name of the resource
  -    * @param scl    The asking class loader
  -    * @return       An URL for reading the resource, or <code>null</code> if the
  -    *               resource could not be found.
  -    */
  +   *  Find a resource in the ServiceLibraries object.
  +   *
  +   *  @param name The name of the resource
  +   *  @param scl The asking class loader
  +   *  @return An URL for reading the resource, or <code>null</code> if the
  +   *          resource could not be found.
  +   */
      public URL getResource(String name, ClassLoader scl)
      {
         Set classLoaders2;
         long clToResourceSetMapVersion2;
  -
  +      
  +      URL resource = null;
  +      
  +      // First ask for the class to the asking class loader
  +      if (scl instanceof UnifiedClassLoader)
  +         resource = ((UnifiedClassLoader)scl).getResourceLocally(name);
  +      
  +      if (resource != null) return resource;
  +         
         synchronized (this)
         {
            // Is it in the global map?
            if (resources.containsKey(name))
               return (URL)resources.get(name);
  -
  +         
            // No, make copies of the classLoader reference to avoid working on
            // a later version of it.
            classLoaders2 = classLoaders;
  -
  +         
            // Save the current version of the resource map, so we
            // can detect if it has changed.
            clToResourceSetMapVersion2 = clToResourceSetMapVersion;
         }
  -
  -      URL resource = null;
  -
  -      // First ask for the class to the asking class loader
  -      if (scl instanceof URLClassLoader)
  -         resource = ((URLClassLoader)scl).getResourceLocally(name);
  -
  -      if (resource == null)
  +      
  +      // If not start asking around to URL classloaders for it
  +      for (Iterator iter = classLoaders2.iterator(); iter.hasNext();)
         {
  -         // If not start asking around to URL classloaders for it
  -         for (Iterator iter = classLoaders2.iterator(); iter.hasNext();)
  -         {
  -            URLClassLoader cl = (URLClassLoader)iter.next();
  -
  -            if (!cl.equals(scl))
  -            { // already tried this one
  -               resource = cl.getResourceLocally(name);
  -
  -               if (resource != null)
  +         UnifiedClassLoader cl = (UnifiedClassLoader)iter.next();
  +         
  +         if (!cl.equals(scl))
  +         { // already tried this one
  +            resource = cl.getResourceLocally(name);
  +            
  +            if (resource != null)
  +            {
  +               synchronized (this)
                  {
  -                  synchronized (this)
  +                  // Did the version change?
  +                  if (clToResourceSetMapVersion2 != clToResourceSetMapVersion)
                     {
  -                     // Did the version change?
  -                     if (clToResourceSetMapVersion2 != clToResourceSetMapVersion)
  -                     {
  -                        // Yes. Is the class loader we used still here?
  -                        if (!classLoaders.contains(cl))
  -                        {
  -                           // No, it was removed from under us.
  -                           // Don't change the maps, simply return the resource.
  -                           return resource;
  -                        }
  -                     }
  -                     // We can keep track
  -                     resources.put(name, resource);
  -
  -                     // When we cycle the cl we also need to remove the classes it 
loaded
  -                     Set set = (Set)clToResourceSetMap.get(cl);
  -                     if (set == null)
  +                     // Yes. Is the class loader we used still here?
  +                     if (!classLoaders.contains(cl))
                        {
  -                        set = new HashSet();
  -                        clToResourceSetMap.put(cl, set);
  +                        // No, it was removed from under us.
  +                        // Don't change the maps, simply return the resource.
  +                        return resource;
                        }
  -
  -                     set.add(name);
  -
  -                     return resource;
                     }
  -               } // if we found it
  -            }
  -         } // for all ClassLoaders
  -      } // If we reach here, all of the classloaders currently in the VM don't know 
about the resource
  -
  +                  // We can keep track
  +                  resources.put(name, resource);
  +                  
  +                  // When we cycle the cl we also need to remove the classes it 
loaded
  +                  Set set = (Set)clToResourceSetMap.get(cl);
  +                  if (set == null)
  +                  {
  +                     set = new HashSet();
  +                     clToResourceSetMap.put(cl, set);
  +                  }
  +                  
  +                  set.add(name);
  +                  
  +                  return resource;
  +               }
  +            } // if we found it
  +         }
  +      } // for all ClassLoaders, If we reach here, all of the classloaders 
currently in the VM don't know about the resource
  +      
         return resource;
      }
   
      /**
  -    * Add a ClassLoader to the ServiceLibraries object.
  -    *
  -    * @param cl The class loader to be added.
  -    */
  -   public synchronized void addClassLoader(URLClassLoader cl)
  +   *  Add a ClassLoader to the ServiceLibraries object.
  +   *
  +   *  @param cl The class loader to be added.
  +   */
  +   public synchronized void addClassLoader(UnifiedClassLoader cl)
      {
         // we allow for duplicate class loader definitions in the services.xml files
         // we should however only keep the first classloader declared
  @@ -223,46 +231,46 @@
         {
            // We create a new copy of the classLoaders set.
            classLoaders = new HashSet(classLoaders);
  -
  +         
            classLoaders.add(cl);
            if( trace )
            {
  -            log.trace("Libraries adding URLClassLoader " + cl.hashCode() +
  -               " key URL " + cl.getKeyURL().toString());
  +            log.trace("Libraries adding UnifiedClassLoader " + cl.hashCode() +
  +               " key URL " + cl.getURL().toString());
            }
         }
         else if( trace )
         {
  -         log.trace("Libraries skipping duplicate URLClassLoader for key URL " +
  -            cl.getKeyURL().toString());
  +         log.trace("Libraries skipping duplicate UnifiedClassLoader for key URL " +
  +            cl.getURL().toString());
         }
      }
  -
  +   
      /**
  -    * Remove a ClassLoader from the ServiceLibraries object.
  -    *
  -    * @param cl The ClassLoader to be removed.
  -    */
  -   public synchronized void removeClassLoader(URLClassLoader cl)
  +   *  Remove a ClassLoader from the ServiceLibraries object.
  +   *
  +   *  @param cl The ClassLoader to be removed.
  +   */
  +   public synchronized void removeClassLoader(UnifiedClassLoader cl)
      {
         boolean trace = log.isTraceEnabled();
         if( trace )
            log.trace("removing classloader " + cl);
  -
  +      
         if (!classLoaders.contains(cl))
            return; // nothing to remove
  -
  +      
         // We create a new copy of the classLoaders set.
         classLoaders = new HashSet(classLoaders);
         classLoaders.remove(cl);
  -
  +      
         if (clToClassSetMap.containsKey(cl))
         {
            // We have a new version of the map
            ++clToClassSetMapVersion;
  -
  +         
            Set clClasses = (Set)clToClassSetMap.remove(cl);
  -
  +         
            for (Iterator iter = clClasses.iterator(); iter.hasNext();)
            {
               Object o = iter.next();
  @@ -276,9 +284,9 @@
         if (clToResourceSetMap.containsKey(cl))
         {
            ++clToResourceSetMapVersion;
  -
  +         
            Set clResources = (Set)clToResourceSetMap.remove(cl);
  -
  +         
            for (Iterator iter = clResources.iterator(); iter.hasNext();)
            {
               Object o = iter.next();
  @@ -290,64 +298,64 @@
      }
   
      /**
  -    * Load a class in the ServiceLibraries object.
  -    *
  -    * @param name The name of the class
  -    * @param resolve If <code>true</code>, the class will be resolved
  -    * @param scl The asking class loader
  -    * @return The loaded class.
  -    *         resource could not be found.
  -    * @throws ClassNotFoundException If the class could not be found.
  -    */
  +   *  Load a class in the ServiceLibraries object.
  +   *
  +   *  @param name The name of the class
  +   *  @param resolve If <code>true</code>, the class will be resolved
  +   *  @param scl The asking class loader
  +   *  @return The loaded class.
  +   *          resource could not be found.
  +   *  @throws ClassNotFoundException If the class could not be found.
  +   */
      public Class loadClass(String name, boolean resolve, ClassLoader scl)
  -          throws ClassNotFoundException
  +   throws ClassNotFoundException
      {
         Class foundClass;
         Set classLoaders2;
         long clToClassSetMapVersion2;
  -
  +      
         synchronized (this)
         {
            // Try the local map already
            foundClass = (Class)classes.get(name);
  -
  +         
            if (foundClass != null)
               return foundClass;
  -
  +         
            // Not found, make copies of the classLoader reference to avoid
            // working on a later version of it.
            classLoaders2 = classLoaders;
  -
  +         
            // Save the current version of the class map, so we
            // can detect if it has changed.
            clToClassSetMapVersion2 = clToClassSetMapVersion;
         }
  -
  +      
         // If not start asking around to URL classloaders for it
         // who will find it?
  -      URLClassLoader cl = null;
  -
  -      if (scl instanceof URLClassLoader)
  +      UnifiedClassLoader cl = null;
  +      
  +      if (scl instanceof UnifiedClassLoader)
         {
            // First ask the asking classloader chances are the dependent class is in 
there
            try
            {
  -            foundClass = ((URLClassLoader)scl).loadClassLocally(name, resolve);
  -
  +            foundClass = ((UnifiedClassLoader)scl).loadClassLocally(name, resolve);
  +            
               //If we get here we know the scl is the right one
  -            cl = (URLClassLoader)scl;
  +            cl = (UnifiedClassLoader)scl;
            }
            catch (ClassNotFoundException ignored)
            {
            }
         }
  -
  +      
         Iterator allLoaders = classLoaders2.iterator();
         while (allLoaders.hasNext() && (foundClass == null))
         {
            // next!
  -         cl = (URLClassLoader)allLoaders.next();
  -
  +         cl = (UnifiedClassLoader)allLoaders.next();
  +         
            if (!scl.equals(cl))
            {
               try
  @@ -360,7 +368,7 @@
               }
            }
         } //allLoaders
  -
  +      
         if (foundClass != null)
         {
            synchronized (this)
  @@ -378,7 +386,7 @@
               }
               // We can keep track
               classes.put(name, foundClass);
  -
  +            
               // When we cycle the cl we also need to remove the classes it loaded
               Set set = (Set)clToClassSetMap.get(cl);
               if (set == null)
  @@ -388,12 +396,12 @@
               }
               set.add(name);
            }
  -
  +         
            return foundClass;
         }
  +      
  +      // If we reach here, all of the classloaders currently in the VM don't know 
about the class
   
  -      // If we reach here, all of the classloaders currently in the VM don't 
  -      // know about the class
         throw new ClassNotFoundException(name);
      }
   
  @@ -408,7 +416,6 @@
      public ObjectName preRegister(MBeanServer server, ObjectName name)
         throws Exception
      {
  -      // this.server = server;
   
         classLoaders = new HashSet();
         classes = new HashMap();
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to