[jboss-cvs] jboss-aop/src/main/org/jboss/aop/classpool ...

Kabir Khan kkhan at jboss.com
Thu Jul 13 14:31:08 EDT 2006


  User: kkhan   
  Date: 06/07/13 14:31:08

  Added:       src/main/org/jboss/aop/classpool     AOPClassPool.java
                        AOPClassPoolRepository.java
                        AOPScopedClassLoaderHelper.java
                        AOPClassPoolFactory.java
  Log:
  Refactor to wrap arouind ScopedClassPoolRepository and ScopedClassPool which has been moved to javassist
  
  Revision  Changes    Path
  1.1      date: 2006/07/13 18:31:08;  author: kkhan;  state: Exp;jboss-aop/src/main/org/jboss/aop/classpool/AOPClassPool.java
  
  Index: AOPClassPool.java
  ===================================================================
  /*
    * JBoss, Home of Professional Open Source
    * Copyright 2005, JBoss Inc., and individual contributors as indicated
    * by the @authors tag. See the copyright.txt 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.aop.classpool;
  
  import java.lang.ref.WeakReference;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.jboss.aop.AspectManager;
  
  import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
  import javassist.ClassPool;
  import javassist.CtClass;
  import javassist.NotFoundException;
  import javassist.scopedpool.ScopedClassPool;
  import javassist.scopedpool.ScopedClassPoolRepository;
  
  /**
   * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
   * @version $Revision: 1.1 $
   */
  public class AOPClassPool extends ScopedClassPool
  {
     /** Classnames of classes that will be created - we do not want to look for these in other pools */
     protected ConcurrentReaderHashMap generatedClasses = new ConcurrentReaderHashMap();
     
     protected ConcurrentReaderHashMap localResources = new ConcurrentReaderHashMap();
  
     static 
     {
        ClassPool.doPruning = false;
        ClassPool.releaseUnmodifiedClassFile = false;
     }   
     
     public AOPClassPool(ClassLoader cl, ClassPool src, ScopedClassPoolRepository repository)
     {
        super(cl, src, repository);
     }
  
     protected AOPClassPool(ClassPool src, ScopedClassPoolRepository repository)
     {
        this(null, src, repository);
     }
  
     public void setClassLoader(ClassLoader cl)
     {
        classLoader = new WeakReference(cl);
     }
     
     public void registerGeneratedClass(String className)
     {
        generatedClasses.put(className, className);
     }
        
     public void close()
     {
        super.close();
        AOPClassPoolRepository.getInstance().perfomUnregisterClassLoader(getClassLoader());
     }
  
     protected CtClass getCached(String classname)
     {
        CtClass clazz = getCachedLocally(classname);
        if (clazz == null)
        {
           boolean isLocal = false; 
           
           ClassLoader cl = null;
           try
           {
              cl = getClassLoader();
           }
           catch (RuntimeException e)
           {
              //Ignore, the ScopedClassPoll throws an exception if pool is not associated with a cl
           }
           if (cl != null)
           {
              String classReeourceName = getResourceName(classname);
              isLocal = isLocalResource(classReeourceName); 
           }
           
           if (!isLocal)
           {
              Object o = generatedClasses.get(classname);
              if (o == null)
              {
                 Map registeredCLs = AspectManager.getRegisteredCLs();
                 synchronized (registeredCLs)
                 {
                    Iterator it = registeredCLs.values().iterator();
                    while (it.hasNext())
                    {
                       AOPClassPool pool = (AOPClassPool) it.next();
                       if (pool.isUnloadedClassLoader())
                       {
                          AspectManager.instance().unregisterClassLoader(pool.getClassLoader());
                          continue;
                       }
        
                       clazz = pool.getCachedLocally(classname);
                       if (clazz != null)
                       {
                          return clazz;
                       }
                    }
                 }
              }
           }
        }
        // *NOTE* NEED TO TEST WHEN SUPERCLASS IS IN ANOTHER UCL!!!!!!
        return clazz;
     }
     
     protected String getResourceName(String classname)
     {
        final int lastIndex = classname.lastIndexOf('$');
        if (lastIndex < 0)
        {
           return classname.replaceAll("[\\.]", "/") + ".class";
        }
        else
        {
           return classname.substring(0, lastIndex).replaceAll("[\\.]", "/") + classname.substring(lastIndex) + ".class";
        }
     }
     
     protected boolean isLocalResource(String resourceName)
     {
        String classResourceName = getResourceName(resourceName);
        Boolean isLocal = (Boolean)localResources.get(classResourceName);
        if (isLocal != null)
        {
           return isLocal.booleanValue();
        }
        boolean localResource = getClassLoader().getResource(classResourceName) != null;
        localResources.put(classResourceName, localResource ? Boolean.TRUE : Boolean.FALSE);
        return localResource;
     }
     
     public synchronized CtClass getLocally(String classname)
             throws NotFoundException
     {
        softcache.remove(classname);
        CtClass clazz = (CtClass) classes.get(classname);
        if (clazz == null)
        {
           clazz = createCtClass(classname, true);
           if (clazz == null) throw new NotFoundException(classname);
           lockInCache(clazz);//Avoid use of the softclasscache
        }
  
        return clazz;
     }
  
  
     public static AOPClassPool createAOPClassPool(ClassLoader cl, ClassPool src, ScopedClassPoolRepository repository)
     {
        return (AOPClassPool)AspectManager.getClassPoolFactory().create(cl, src, repository);
     }
  
     public static AOPClassPool createAOPClassPool(ClassPool src, ScopedClassPoolRepository repository)
     {
        return (AOPClassPool)AspectManager.getClassPoolFactory().create(src, repository);
     }
  }
  
  
  
  1.1      date: 2006/07/13 18:31:08;  author: kkhan;  state: Exp;jboss-aop/src/main/org/jboss/aop/classpool/AOPClassPoolRepository.java
  
  Index: AOPClassPoolRepository.java
  ===================================================================
  /*
  * JBoss, Home of Professional Open Source
  * Copyright 2005, JBoss Inc., and individual contributors as indicated
  * by the @authors tag. See the copyright.txt 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.aop.classpool;
  
  import java.lang.reflect.Field;
  import java.security.AccessController;
  import java.security.PrivilegedActionException;
  import java.security.PrivilegedExceptionAction;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.jboss.aop.AspectManager;
  import org.jboss.aop.instrument.Instrumentor;
  
  import javassist.ClassPool;
  import javassist.scopedpool.ScopedClassPool;
  import javassist.scopedpool.ScopedClassPoolFactory;
  import javassist.scopedpool.ScopedClassPoolRepository;
  import javassist.scopedpool.ScopedClassPoolRepositoryImpl;
  
  /**
   * Singleton classpool repository used by aop
   * 
   * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
   * @version $Revision: 1.1 $
   */
  public class AOPClassPoolRepository implements ScopedClassPoolRepository
  {
     private final static AOPClassPoolRepository instance = new AOPClassPoolRepository();
     
     /** The classes per classppol */
     protected final HashMap ucl2classes = new HashMap();
  
     /** The top-level AspectManager this pool belongs to */
     AspectManager manager;
     
     ScopedClassPoolRepository delegate;
  
     public static AOPClassPoolRepository getInstance()
     {
        return instance;
     }
     
     private AOPClassPoolRepository()
     {
        this.delegate = ScopedClassPoolRepositoryImpl.getInstance();
        delegate.setClassPoolFactory(new AOPClassPoolFactory());
     }
  
  
     public void setClassPoolFactory(ScopedClassPoolFactory factory)
     {
        delegate.setClassPoolFactory(factory);
     }
     
     public ScopedClassPoolFactory getClassPoolFactory()
     {
        return delegate.getClassPoolFactory();
     }
  
     public boolean isPrune()
     {
        return delegate.isPrune();
     }
  
     public void setPrune(boolean prune)
     {
        delegate.setPrune(prune);
     }
  
     public ScopedClassPool createScopedClassPool(ClassLoader cl, ClassPool src)
     {
        return delegate.createScopedClassPool(cl, src);
     }
  
     public ClassPool findClassPool(ClassLoader cl)
     {
        return delegate.findClassPool(cl);
     }
  
     public void setAspectManager(AspectManager manager)
     {
        this.manager = manager;
     }
     
     /**
      * Get the registered classloaders
      * 
      * @return the registered classloaders
      */
     public Map getRegisteredCLs()
     {
        return delegate.getRegisteredCLs();
     }
  
     /**
      * This method will check to see if a register classloader has been undeployed (as in JBoss)
      */
     public void clearUnregisteredClassLoaders()
     {
        delegate.clearUnregisteredClassLoaders();
     }
     
     public ClassPool registerClassLoader(ClassLoader ucl)
     {
        return delegate.registerClassLoader(ucl);
     }
  
     public void unregisterClassLoader(ClassLoader cl)
     {
        delegate.unregisterClassLoader(cl);
     }
     
     public void registerClass(Class clazz)
     {
        HashSet classes = (HashSet) ucl2classes.get(clazz.getClassLoader());
        if (classes == null)
        {
           classes = new HashSet();
           ucl2classes.put(clazz.getClassLoader(), classes);
        }
        classes.add(clazz);
     }
  
     public void perfomUnregisterClassLoader(ClassLoader cl)
     {
        if (System.getSecurityManager() == null)
        {
           UnregisterClassLoaderAction.NON_PRIVILEGED.unregister(this, cl);
        }
        else
        {
           UnregisterClassLoaderAction.PRIVILEGED.unregister(this, cl);
        }
     }
     
     private void doUnregisterClassLoader(ClassLoader cl)
     {
        synchronized (delegate.getRegisteredCLs())
        {
           HashSet classes = (HashSet) ucl2classes.remove(cl);
           if (classes != null)
           {
              Iterator it = classes.iterator();
              while (it.hasNext())
              {
                 Object clazz = it.next();
                 synchronized (manager.getAdvisors())
                 {
                    manager.getAdvisors().remove(clazz);
                    Class advisedClass = (Class)clazz;
                    try
                    {
                       //The static advisor field should be the only remaining hard reference to the advisor
                       Field f = advisedClass.getDeclaredField(Instrumentor.HELPER_FIELD_NAME);
                       f.setAccessible(true);
                       f.set(null, null);
                    }
                    catch(NoSuchFieldException e)
                    {
                       System.out.println("[warn] Error unsetting advisor for " + advisedClass.getName() + " " + e);
                    }
                    catch(IllegalAccessException e)
                    {
                       System.out.println("[warn] Error unsetting advisor for " + advisedClass.getName() + " " + e);
                    }
                 }
              }
           }
        }
     }
  
     
     interface UnregisterClassLoaderAction
     {
        void unregister(AOPClassPoolRepository repository, ClassLoader loader);
        
        UnregisterClassLoaderAction PRIVILEGED = new UnregisterClassLoaderAction()
        {
           public void unregister(final AOPClassPoolRepository repository, final ClassLoader loader)
           {
              try
              {
                 AccessController.doPrivileged(new PrivilegedExceptionAction()
                 {
                    public Object run()
                    {
                       repository.doUnregisterClassLoader(loader);
                       return null;
                    }
                 });
              }
              catch (PrivilegedActionException e)
              {
                 Exception ex = e.getException();
                 if (ex instanceof RuntimeException) 
                 { 
                    throw (RuntimeException)ex;
                 }
                 throw new RuntimeException(ex);
              }
           }
        };
  
        UnregisterClassLoaderAction NON_PRIVILEGED = new UnregisterClassLoaderAction()
        {
           public void unregister(AOPClassPoolRepository repository, ClassLoader loader)
           {
              repository.doUnregisterClassLoader(loader);
           }
        };
     }
  }
  
  
  
  1.1      date: 2006/07/13 18:31:08;  author: kkhan;  state: Exp;jboss-aop/src/main/org/jboss/aop/classpool/AOPScopedClassLoaderHelper.java
  
  Index: AOPScopedClassLoaderHelper.java
  ===================================================================
  /*
  * JBoss, Home of Professional Open Source
  * Copyright 2005, JBoss Inc., and individual contributors as indicated
  * by the @authors tag. See the copyright.txt 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.aop.classpool;
  
  /**
   * Helper to determine if we are running within a scoped classloader. 
   * 
   * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
   * @version $Revision: 1.1 $
   */
  public interface AOPScopedClassLoaderHelper
  {
  
     ClassLoader ifScopedDeploymentGetScopedParentUclForCL(ClassLoader loader);
     ClassLoader getTopLevelJBossClassLoader();
  }
  
  
  
  1.1      date: 2006/07/13 18:31:08;  author: kkhan;  state: Exp;jboss-aop/src/main/org/jboss/aop/classpool/AOPClassPoolFactory.java
  
  Index: AOPClassPoolFactory.java
  ===================================================================
  /*
    * JBoss, Home of Professional Open Source
    * Copyright 2005, JBoss Inc., and individual contributors as indicated
    * by the @authors tag. See the copyright.txt 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.aop.classpool;
  
  import org.jboss.aop.AspectManager;
  
  import javassist.ClassPool;
  import javassist.scopedpool.ScopedClassPool;
  import javassist.scopedpool.ScopedClassPoolFactory;
  import javassist.scopedpool.ScopedClassPoolRepository;
  
  /**
   * Comment
   *
   * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
   * @version $Revision: 1.1 $
   *
   **/
  public class AOPClassPoolFactory implements ScopedClassPoolFactory
  {
     public ScopedClassPool create(ClassLoader cl, ClassPool src, ScopedClassPoolRepository repository)
     {
        return new AOPClassPool(cl, src, repository);
     }
  
     public ScopedClassPool create(ClassPool src, ScopedClassPoolRepository repository)
     {
        return new AOPClassPool(src, repository);
     }   
  }
  
  
  



More information about the jboss-cvs-commits mailing list