[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