[jboss-cvs] JBossAS SVN: r83504 - in projects/aop/trunk: aop/src/main/java/org/jboss/aop/instrument and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Jan 27 10:36:36 EST 2009


Author: kabir.khan at jboss.com
Date: 2009-01-27 10:36:36 -0500 (Tue, 27 Jan 2009)
New Revision: 83504

Modified:
   projects/aop/trunk/aop/src/main/java/org/jboss/aop/classpool/AOPClassPool.java
   projects/aop/trunk/aop/src/main/java/org/jboss/aop/instrument/TransformerCommon.java
   projects/aop/trunk/asintegration-core/src/main/java/org/jboss/aop/classpool/DelegatingClassPool.java
   projects/aop/trunk/asintegration-core/src/test/java/org/jboss/test/aop/classpool/test/ParentFirstDelegatingClassPoolTestCase.java
   projects/aop/trunk/asintegration-core/src/test/java/org/jboss/test/aop/classpool/test/ParentLastDelegatingClassPoolTestCase.java
Log:
[JBAOP-666] Better documentation of AOPClassPool.generatedClasses, some tests to illustrate why it is needed and fixes for how it is used

Modified: projects/aop/trunk/aop/src/main/java/org/jboss/aop/classpool/AOPClassPool.java
===================================================================
--- projects/aop/trunk/aop/src/main/java/org/jboss/aop/classpool/AOPClassPool.java	2009-01-27 15:22:12 UTC (rev 83503)
+++ projects/aop/trunk/aop/src/main/java/org/jboss/aop/classpool/AOPClassPool.java	2009-01-27 15:36:36 UTC (rev 83504)
@@ -21,9 +21,11 @@
   */
 package org.jboss.aop.classpool;
 
+import java.security.ProtectionDomain;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import javassist.CannotCompileException;
 import javassist.ClassPool;
 import javassist.CtClass;
 import javassist.NotFoundException;
@@ -42,13 +44,18 @@
 {
    protected final Logger logger = Logger.getLogger(this.getClass());
    
-   /** Classnames of classes that will be created - we do not want to look for these in other pools */
-   protected ConcurrentHashMap<String, String> generatedClasses = new ConcurrentHashMap<String, String>();
+   /** Classnames of classes that will be created - we do not want to look for these in other pools.
+    * The main use for this is when a class is created in a parent pool, and we then want to 
+    * create a class with the same name in a parent-last child pool. As part of the create process
+    * javassist.ClassPool will check if that class is frozen (which in turn will call getCached()
+    * and get0()). If the classname exists in this map, get0() and getCached() should return null;   
+    */
+   protected final ConcurrentHashMap<String, String> generatedClasses = new ConcurrentHashMap<String, String>();
 
-   protected ConcurrentHashMap<String, Boolean> localResources = new ConcurrentHashMap<String, Boolean>();
+   protected final ConcurrentHashMap<String, Boolean> localResources = new ConcurrentHashMap<String, Boolean>();
 
    /** Classnames of classes that have been loaded, but were not woven */
-   protected ConcurrentHashMap<String, Boolean> loadedButNotWovenClasses = new ConcurrentHashMap<String, Boolean>();
+   protected final ConcurrentHashMap<String, Boolean> loadedButNotWovenClasses = new ConcurrentHashMap<String, Boolean>();
 
    /** Causes the AOPClassPool.getCached() method to search all ClassPools registered in the repository */
    public static final Class<SearchAllRegisteredLoadersSearchStrategy> SEARCH_ALL_STRATEGY = SearchAllRegisteredLoadersSearchStrategy.class;
@@ -119,6 +126,16 @@
       generatedClasses.put(className, className);
    }
 
+   public boolean isGeneratedClass(String className)
+   {
+      return generatedClasses.containsKey(className);
+   }
+   
+   public void doneGeneratingClass(String className)
+   {
+      generatedClasses.remove(className);
+   }
+
    public void close()
    {
       super.close();
@@ -154,7 +171,7 @@
       if (dynamic)
       {
          if (trace) logger.trace(this + " registering dynamic class " + classname);
-         registerGeneratedClass(classname);
+         doneGeneratingClass(classname);
          String resourcename = getResourceName(classname);
          localResources.put(resourcename, Boolean.TRUE);
       }

Modified: projects/aop/trunk/aop/src/main/java/org/jboss/aop/instrument/TransformerCommon.java
===================================================================
--- projects/aop/trunk/aop/src/main/java/org/jboss/aop/instrument/TransformerCommon.java	2009-01-27 15:22:12 UTC (rev 83503)
+++ projects/aop/trunk/aop/src/main/java/org/jboss/aop/instrument/TransformerCommon.java	2009-01-27 15:36:36 UTC (rev 83504)
@@ -216,15 +216,17 @@
     */
    public static CtClass makeNestedClass(CtClass outer, String name, boolean isStatic) throws CannotCompileException
    {
+      final String classname = outer.getName() + "$" + name;
       try
       {
-         registerGeneratedClass(outer.getClassPool(), outer.getName() + "$" + name);
+         registerGeneratedClass(outer.getClassPool(), classname);
          CtClass inner = outer.makeNestedClass(name, true);
          return inner;
       }
-      catch (Exception e)
+      catch (RuntimeException e)
       {
-         throw new CannotCompileException("Error creating " + name + " in " + outer.getName(),e);
+         unregisterGeneratedClass(outer.getClassPool(), classname);
+         throw e;
       }
    }
 
@@ -243,20 +245,43 @@
    public static CtClass makeClass(ClassPool pool, String name, CtClass superClass)
    {
       registerGeneratedClass(pool, name);
-      return pool.makeClass(name, superClass);
+      try
+      {
+         return pool.makeClass(name, superClass);
+      }
+      catch(RuntimeException e)
+      {
+         unregisterGeneratedClass(pool, name);
+         throw e;
+      }
    }
 
    private static void registerGeneratedClass(ClassPool pool, String name)
    {
-      try
+      AOPClassPool aopPool = getAOPClassPool(pool);
+      if (aopPool != null)
       {
-         ((AOPClassPool)pool).registerGeneratedClass(name);
+         aopPool.registerGeneratedClass(name);
       }
-      catch(ClassCastException e)
+   }
+   
+   private static void unregisterGeneratedClass(ClassPool pool, String name)
+   {
+      AOPClassPool aopPool = getAOPClassPool(pool);
+      if (aopPool != null)
       {
-
+         aopPool.doneGeneratingClass(name);
       }
    }
+   
+   private static AOPClassPool getAOPClassPool(ClassPool pool)
+   {
+      if (pool instanceof AOPClassPool)
+      {
+         return (AOPClassPool)pool;
+      }
+      return null;
+   }
 
    private interface ToClassAction
    {

Modified: projects/aop/trunk/asintegration-core/src/main/java/org/jboss/aop/classpool/DelegatingClassPool.java
===================================================================
--- projects/aop/trunk/asintegration-core/src/main/java/org/jboss/aop/classpool/DelegatingClassPool.java	2009-01-27 15:22:12 UTC (rev 83503)
+++ projects/aop/trunk/asintegration-core/src/main/java/org/jboss/aop/classpool/DelegatingClassPool.java	2009-01-27 15:36:36 UTC (rev 83504)
@@ -80,6 +80,10 @@
    @Override
    protected synchronized CtClass get0(String classname, boolean useCache) throws NotFoundException
    {
+      if (isGeneratedClass(classname))
+      {
+         return null;
+      }
       return domain.getCachedOrCreate(this, classname, true);
    }
    
@@ -100,6 +104,10 @@
    @Override
    public CtClass getCached(String classname)
    {
+      if (isGeneratedClass(classname))
+      {
+         return null;
+      }
       return domain.getCachedOrCreate(this, classname, false);
    }
    

Modified: projects/aop/trunk/asintegration-core/src/test/java/org/jboss/test/aop/classpool/test/ParentFirstDelegatingClassPoolTestCase.java
===================================================================
--- projects/aop/trunk/asintegration-core/src/test/java/org/jboss/test/aop/classpool/test/ParentFirstDelegatingClassPoolTestCase.java	2009-01-27 15:22:12 UTC (rev 83503)
+++ projects/aop/trunk/asintegration-core/src/test/java/org/jboss/test/aop/classpool/test/ParentFirstDelegatingClassPoolTestCase.java	2009-01-27 15:36:36 UTC (rev 83504)
@@ -7,6 +7,7 @@
 import junit.framework.TestSuite;
 
 import org.jboss.aop.classpool.ClassPoolDomain;
+import org.jboss.aop.instrument.TransformerCommon;
 
 
 /*
@@ -263,4 +264,31 @@
       assertEquals(grandParentPool, a3.getClassPool());
       assertSame(a2, a3);
    }
+   
+   public void testGenerateSameNestedClassInChildAndParent() throws Exception
+   {
+      ClassPoolDomain parent = createClassPoolDomain("PARENT", null, false);
+      ClassPool parentPool = createDelegatingClassPool(parent, JAR_A);
+      ClassPoolDomain child = createClassPoolDomain("CHILD", parent, true);
+      ClassPool childPool = createDelegatingClassPool(child, JAR_A);
+      CtClass parentA = parentPool.get(CLASS_A);
+      CtClass parentClazz = TransformerCommon.makeNestedClass(parentA, "Test", true);
+      assertSame(parentPool, parentClazz.getClassPool());
+      Class<?> parentClass = parentClazz.toClass();
+      assertSame(parentPool.getClassLoader(), parentClass.getClassLoader());
+      Class<?> parentAClass = parentA.toClass();
+      assertSame(parentPool.getClassLoader(), parentAClass.getClassLoader());
+      
+      CtClass childA = childPool.get(CLASS_A);
+      try
+      {
+         TransformerCommon.makeNestedClass(childA, "Test", true);
+      }
+      catch(Exception e)
+      {
+         
+      }
+      assertSame(parentA, childA);
+      assertSame(parentClazz, childPool.get(CLASS_A + "$Test"));
+   }
 }

Modified: projects/aop/trunk/asintegration-core/src/test/java/org/jboss/test/aop/classpool/test/ParentLastDelegatingClassPoolTestCase.java
===================================================================
--- projects/aop/trunk/asintegration-core/src/test/java/org/jboss/test/aop/classpool/test/ParentLastDelegatingClassPoolTestCase.java	2009-01-27 15:22:12 UTC (rev 83503)
+++ projects/aop/trunk/asintegration-core/src/test/java/org/jboss/test/aop/classpool/test/ParentLastDelegatingClassPoolTestCase.java	2009-01-27 15:36:36 UTC (rev 83504)
@@ -4,6 +4,7 @@
 import javassist.CtClass;
 
 import org.jboss.aop.classpool.ClassPoolDomain;
+import org.jboss.aop.instrument.TransformerCommon;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -219,4 +220,46 @@
       CtClass a3 = childPool.get(CLASS_A);
       assertEquals(grandParentPool, a3.getClassPool());
    }
+   
+   public void testGenerateSameClassInChildAndParent() throws Exception
+   {
+      ClassPoolDomain parent = createClassPoolDomain("PARENT", null, false);
+      ClassPool parentPool = createDelegatingClassPool(parent, JAR_A);
+      ClassPoolDomain child = createClassPoolDomain("CHILD", parent, false);
+      ClassPool childPool = createDelegatingClassPool(child, JAR_A);
+      CtClass parentClazz = TransformerCommon.makeClass(parentPool, "test.Test");
+      assertSame(parentClazz, parentPool.get("test.Test"));
+      assertSame(parentPool, parentClazz.getClassPool());
+      Class<?> parentClass = parentClazz.toClass();
+      assertSame(parentPool.getClassLoader(), parentClass.getClassLoader());
+      
+      CtClass childClazz = TransformerCommon.makeClass(childPool, "test.Test"); 
+      assertSame(childClazz, childPool.get("test.Test"));
+      assertSame(childPool, childClazz.getClassPool());
+      Class<?> childClass = childClazz.toClass();
+      assertSame(childPool.getClassLoader(), childClass.getClassLoader());
+   }
+
+   public void testGenerateSameNestedClassInChildAndParent() throws Exception
+   {
+      ClassPoolDomain parent = createClassPoolDomain("PARENT", null, false);
+      ClassPool parentPool = createDelegatingClassPool(parent, JAR_A);
+      ClassPoolDomain child = createClassPoolDomain("CHILD", parent, false);
+      ClassPool childPool = createDelegatingClassPool(child, JAR_A);
+      CtClass parentA = parentPool.get(CLASS_A);
+      CtClass parentClazz = TransformerCommon.makeNestedClass(parentA, "Test", true);
+      assertSame(parentPool, parentClazz.getClassPool());
+      Class<?> parentClass = parentClazz.toClass();
+      assertSame(parentPool.getClassLoader(), parentClass.getClassLoader());
+      Class<?> parentAClass = parentA.toClass();
+      assertSame(parentPool.getClassLoader(), parentAClass.getClassLoader());
+      
+      CtClass childA = childPool.get(CLASS_A);
+      CtClass childClazz = TransformerCommon.makeNestedClass(childA, "Test", true); 
+      assertSame(childPool, childClazz.getClassPool());
+      Class<?> childClass = childClazz.toClass();
+      assertSame(childPool.getClassLoader(), childClass.getClassLoader());
+      Class<?> childAClass = childA.toClass();
+      assertSame(childPool.getClassLoader(), childAClass.getClassLoader());
+   }
 }




More information about the jboss-cvs-commits mailing list