[jboss-cvs] JBossAS SVN: r65280 - in projects/aop/trunk/aop: src/test/org/jboss/test/aop/memoryleaks and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Sep 10 15:03:12 EDT 2007
Author: flavia.rainone at jboss.com
Date: 2007-09-10 15:03:12 -0400 (Mon, 10 Sep 2007)
New Revision: 65280
Modified:
projects/aop/trunk/aop/build-tests-jdk50.xml
projects/aop/trunk/aop/src/test/org/jboss/test/aop/memoryleaks/MemoryLeakTestCase.java
Log:
[JBAOP-226] Integrated test cases from leak branch with trunk.
Modified: projects/aop/trunk/aop/build-tests-jdk50.xml
===================================================================
--- projects/aop/trunk/aop/build-tests-jdk50.xml 2007-09-10 15:16:07 UTC (rev 65279)
+++ projects/aop/trunk/aop/build-tests-jdk50.xml 2007-09-10 19:03:12 UTC (rev 65280)
@@ -249,7 +249,6 @@
<src path="${source.tests.java}"/>
<classpath refid="test.classpath"/>
<include name="**/*.java"/>
- <exclude name="org/jboss/test/aop/memoryleaks/**/*.java"/>
</javac>
<jar destfile="${build.tests.classes}/org/jboss/test/aop/jdk15/dynamic/common/scenario.jar"
basedir="${build.tests.classes}" includes="org/jboss/test/aop/jdk15/dynamic/common/scenario/**"/>
@@ -1462,7 +1461,6 @@
<target name="memory-tests" depends="compile-test-classes">
<taskdef name="annotationc" classname="org.jboss.aop.ant.AnnotationC" classpathref="jboss.aop.classpath"/>
-
<antcall target="memory-test" inheritRefs="true">
<param name="test" value="annotatedcflow"/>
<param name="case" value="AnnotatedCFlowTestCase"/>
@@ -1476,10 +1474,6 @@
<param name="case" value="ArgsTestCase"/>
</antcall>
<antcall target="memory-test" inheritRefs="true">
- <param name="test" value="invocationParams"/>
- <param name="case" value="ArgsTestCase"/>
- </antcall>
- <antcall target="memory-test" inheritRefs="true">
<param name="test" value="basic"/>
<param name="case" value="AOPTester"/>
</antcall>
@@ -1488,6 +1482,54 @@
<param name="case" value="ConfigTester"/>
</antcall>
<antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="typedAdvices"/>
+ <param name="case" value="BeforeAfterThrowingTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="annotatedAdviceParams"/>
+ <param name="case" value="ArgsTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="annotatedAdviceParams"/>
+ <param name="case" value="ArgTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="annotatedAdviceParams"/>
+ <param name="case" value="CallerTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="annotatedAdviceParams"/>
+ <param name="case" value="JoinPointTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="annotatedAdviceParams"/>
+ <param name="case" value="OverloadedAdviceTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="annotatedAdviceParams"/>
+ <param name="case" value="ReturnTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="annotatedAdviceParams"/>
+ <param name="case" value="TargetTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="annotatedAdviceParams"/>
+ <param name="case" value="ThrownTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="beforeafterthrowingscoped"/>
+ <param name="case" value="BeforeAfterThrowingScopedTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="beforeafterthrowingstack"/>
+ <param name="case" value="BeforeAfterThrowingStackTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="bridgemethod"/>
+ <param name="case" value="BridgeMethodWeavingTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
<param name="test" value="callerargs"/>
<param name="case" value="CallerArgsTestCase"/>
</antcall>
@@ -1507,19 +1549,47 @@
<param name="test" value="dotinpointcutname"/>
<param name="case" value="DotInPointcutNameTestCase"/>
</antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="dynamicgenadvisor"/>
+ <param name="case" value="DynamicTester"/>
+ </antcall>
<antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="extender"/>
+ <param name="case" value="ExtenderTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="field"/>
+ <param name="case" value="FieldTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
<param name="test" value="implementz"/>
<param name="case" value="ImplementsTester"/>
</antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="inforesolve"/>
+ <param name="case" value="InfoResolveAnnotationTestCase"/>
+ </antcall>
<antcall target="memory-test" inheritRefs="true">
<param name="test" value="instanceofannotated"/>
<param name="case" value="InstanceOfAnnotatedTester"/>
</antcall>
<antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="instanceofintroduced"/>
+ <param name="case" value="InstanceofIntroducedTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
<param name="test" value="introduction"/>
<param name="case" value="IntroductionTester"/>
</antcall>
<antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="invoketarget"/>
+ <param name="case" value="InvokeTargetTestCase"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
+ <param name="test" value="marshalling"/>
+ <param name="case" value="MarshallingTester"/>
+ </antcall>
+ <antcall target="memory-test" inheritRefs="true">
<param name="test" value="override"/>
<param name="case" value="OverrideTestCase"/>
</antcall>
@@ -1538,7 +1608,10 @@
<property name="aoppath" value="${source.res}/test/${test}/jboss-aop.xml"/>
<property name="testcase" value="org.jboss.test.aop.${test}.${case}"/>
-
+ <condition property="extra.classes" value="${extraClasses}" else="">
+ <isset property="extraClasses"/>
+ </condition>
+
<aopc compilerclasspathref="aopc.task.classpath">
<classpath refid="aopc.task.classpath"/>
<classpath path="${build.tests.classes}"/>
@@ -1556,10 +1629,12 @@
<sysproperty key="jboss.aop.path" value="${aoppath}"/>
<sysproperty key="test.to.run" value="${testcase}"/>
<sysproperty key="leak.report.dir" value="${report.dir}"/>
+ <sysproperty key="extraClasses" value="${extra.classes}"/>
<classpath refid="test.classpath"/>
<classpath path="${build.tests.classes}"/>
<jvmarg value="-agentlib:jbossAgent"/>
- <formatter usefile="true" type="xml" extension="-${testcase}.xml"/>
+ <sysproperty key="jboss-junit-configuration" value="${testcase}"/>
+ <formatter classname="org.jboss.ant.taskdefs.XMLJUnitMultipleResultFormatter" extension="-${testcase}.xml"/>
<formatter usefile="true" type="plain" extension="-${testcase}.txt"/>
<test fork="yes" name="org.jboss.test.aop.memoryleaks.MemoryLeakTestCase" todir="${report.dir}"/>
</junit>
Modified: projects/aop/trunk/aop/src/test/org/jboss/test/aop/memoryleaks/MemoryLeakTestCase.java
===================================================================
--- projects/aop/trunk/aop/src/test/org/jboss/test/aop/memoryleaks/MemoryLeakTestCase.java 2007-09-10 15:16:07 UTC (rev 65279)
+++ projects/aop/trunk/aop/src/test/org/jboss/test/aop/memoryleaks/MemoryLeakTestCase.java 2007-09-10 19:03:12 UTC (rev 65280)
@@ -42,6 +42,7 @@
import junit.framework.TestCase;
import org.jboss.profiler.jvmti.JVMTIInterface;
+import org.jboss.test.aop.AOPTestWithSetup;
/**
*
@@ -50,6 +51,11 @@
*/
public class MemoryLeakTestCase extends TestCase
{
+ String jbossAopPath;
+ String extraClasses;
+ Method aspectXmkLoaderUndeployXmlMethod;
+ Method aspectManagerInstanceMethod;
+ Method aspectManagerUnregisterClassLoader;
/**
* Constructor for UndeployTester.
@@ -65,6 +71,21 @@
super();
}
+ public static void main(String[] args) throws Exception
+ {
+ MemoryLeakTestCase test = new MemoryLeakTestCase();
+ test.testWithClassLoader();
+ }
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ System.setProperty(AOPTestWithSetup.DISABLE_SECURITY_KEY, "true");
+ jbossAopPath = System.getProperty("jboss.aop.path");
+ extraClasses = System.getProperty("extraClasses", null);
+ super.setUp();
+ }
+
public void testWithClassLoader() throws Exception
{
@@ -77,21 +98,34 @@
{
String className = null;
{
- ClassLoader oldloader = Thread.currentThread().getContextClassLoader();
- ClassLoader loader = newClassLoader();
+ final ClassLoader oldloader = Thread.currentThread().getContextClassLoader();
+ ClassLoader loader = newClassLoader(oldloader);
weakReferenceOnLoader = new WeakReference(loader);
Thread.currentThread().setContextClassLoader(loader);
+ System.out.println("OLD Loader " + oldloader);
+ System.out.println("NEW Loader " + loader);
+ ClassLoader parent = loader.getParent();
+ while (parent != null)
+ {
+ System.out.println("Parent " + parent);
+ parent = parent.getParent();
+ }
+
+
Class testClass = getTestCaseClass(loader);
className = testClass.getName();
Class aspectManagerClass = loader.loadClass("org.jboss.aop.AspectManager");
assertNotSame(aspectManagerClass.getClassLoader(), this.getClass().getClassLoader());
+ assertNotSame(aspectManagerClass.getClassLoader(), testClass.getClassLoader());
System.out.println("oldLoader");
xmlLoader = loader.loadClass("org.jboss.aop.AspectXmlLoader");
+ initMethods(aspectManagerClass, xmlLoader);
+
assertNotSame(xmlLoader.getClassLoader(),loader);
ArrayList methods = getTestMethods(testClass);
@@ -111,12 +145,40 @@
testClass=null;
testInstance = null;
methods.clear();
- //xmlLoader = null;
- Thread.currentThread().setContextClassLoader(oldloader);
+
+ AccessController.doPrivileged(new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ Thread.currentThread().setContextClassLoader(oldloader);
+ return null;
+ }
+ });
+
+ //The test framework does not clear some static fields, make sure these are cleared
+ clearEverySingleFieldOnInstances("org.jboss.test.JBossTestSetup");
+ clearEverySingleFieldOnInstances("org.jboss.test.AbstractTestSetup");
+ clearEverySingleFieldOnInstances("org.jboss.test.AbstractTestCaseWithSetup");
}
assertEquals(1, countInstances("org.jboss.aop.AspectManager", true));
- //checkUnload( weakReferenceOnLoader,"org.jboss.test.aop.memoryleaks.Test");
+
+ if (extraClasses != null)
+ {
+ StringTokenizer tok = new StringTokenizer(extraClasses, ":;,");
+ while (tok.hasMoreTokens())
+ {
+ String clazz = tok.nextToken();
+ try
+ {
+ reportInstanceReferences(weakReferenceOnLoader, clazz);
+ }
+ catch(Throwable t)
+ {
+ }
+ }
+ }
+
checkUnload( weakReferenceOnLoader, className);
// I'm pretty sure nobody would clear that reference. I'm keeping this assertion here just to make it clear why we can't clear xmlLoader
@@ -262,7 +324,7 @@
assertNotNull("Test to be run must be passed in test.to.run system property", className);
Class testClass = loader.loadClass(className);
- assertSame("Fix your classpath, this test is not valid",loader, testClass.getClassLoader());
+ assertSame("Fix your classpath, this test is not valid", loader, testClass.getClassLoader());
assertNotSame(testClass.getClassLoader(), this.getClass().getClassLoader());
return testClass;
}
@@ -283,7 +345,7 @@
jvmti.heapSnapshot("snapshot", "mem");
clazz=null;
- String report =jvmti.exploreClassReferences(className, 15, true, false, false, false, false);
+ String report =jvmti.exploreClassReferences(className, 15, true, false, false, false, true);
//System.out.println(report);
String reportDir = System.getProperty("leak.report.dir");
@@ -299,6 +361,9 @@
clazz = jvmti.getClassByName(className);
+ clearEverySingleFieldOnInstances("org.jboss.aop.AspectManager"); // This part is not intended to be commited. It could be used during debug, and you could use to release references on purpose, just to evaluate behavior
+
+ clazz = jvmti.getClassByName(className);
if (clazz==null)
{
System.out.println("Attention: After clearing every field on AspectManager, GC could release the classLoader");
@@ -307,9 +372,42 @@
fail ("Class " + className + " still referenced. Look at report for more details");
}
}
- assertNull("The classLoader is supposed to be released. Something is holding a reference. If you activate -agentlib:jbossAgent this testcase will generate a report with referenceHolders.",weakReferenceOnLoader.get());
}
+ private void reportInstanceReferences(WeakReference weakReferenceOnLoader, String className) throws Exception
+ {
+ JVMTIInterface jvmti = new JVMTIInterface();
+ if (jvmti.isActive())
+ {
+
+ jvmti.forceReleaseOnSoftReferences();
+ jvmti.forceGC();
+ Class clazz = jvmti.getClassByName(className);
+ if (clazz!=null)
+ {
+ jvmti.heapSnapshot("snapshot", "mem");
+ clazz=null;
+ Object[] objects = jvmti.getAllObjects(className);
+ System.out.println("============> Instances of " + className + " " + objects.length);
+
+ //String report =jvmti.exploreClassReferences(className, 15, true, false, false, false, true);
+ String report = jvmti.exploreObjectReferences(className, 15, false);
+
+
+
+ System.out.println("================= " + className + " ================");
+ System.out.println(report);
+ String reportDir = System.getProperty("leak.report.dir");
+ assertNotNull("You must pass in the directory for the reports as leak.report.dir", reportDir);
+ File outputfile = new File(reportDir + "/leak-report-instances" + className + ".html");
+ FileOutputStream outfile = new FileOutputStream(outputfile);
+ PrintStream realoutput = new PrintStream(outfile);
+ realoutput.println(report);
+ realoutput.close();
+ }
+ }
+ }
+
public Field[] getDeclaredFields(Class clazz)
{
ArrayList list = new ArrayList();
@@ -339,11 +437,13 @@
{
if (classes[i].getName().equals(className))
{
+ System.out.println("---> Found class " + className);
Field fields[] = getDeclaredFields(classes[i]);
objects = jvmti.getAllObjects(classes[i]);
for (int j=0;j<objects.length;j++)
{
resetObject(objects[j], fields);
+
}
if (objects.length==0)
{
@@ -361,14 +461,11 @@
{
try
{
- //System.out.print("Setting "+fields[fieldN].getName());
fields[fieldN].set(object,null);
- //System.out.println("...done");
}
catch (Exception e)
{
- // System.out.println("...error " + e.getMessage());
- //System.out.println("Exception " + e.getMessage() + " happened during setField");
+ System.out.println("Exception happened during setField " + e);
}
}
}
@@ -392,11 +489,9 @@
private void unregisterClassLoader(Class aspectManagerClass, ClassLoader loader) throws Exception
{
System.out.println("============ Unregistering ClassLoader");
- Method instance = aspectManagerClass.getDeclaredMethod("instance", new Class[0]);
- Object aspectManager = instance.invoke(null, new Object[0]);
+ Object aspectManager = aspectManagerInstanceMethod.invoke(null, new Object[0]);
- Method unregisterClassLoader = aspectManagerClass.getDeclaredMethod("unregisterClassLoader", new Class[] {ClassLoader.class});
- unregisterClassLoader.invoke(aspectManager, new Object[] {loader});
+ aspectManagerUnregisterClassLoader.invoke(aspectManager, new Object[] {loader});
}
private static void printVariables()
@@ -413,11 +508,13 @@
}
}
- private static ClassLoader newClassLoader() throws Exception {
+ private static ClassLoader newClassLoader(ClassLoader parent) throws Exception {
//printVariables();
- URL classLocation = MemoryLeakTestCase.class.getProtectionDomain().getCodeSource().getLocation();
+ URL classLocation = MemoryLeakTestCase.class.getProtectionDomain().getCodeSource().getLocation();
StringTokenizer tokenString = new StringTokenizer(System.getProperty("java.class.path"),File.pathSeparator);
+ System.out.println("java.class.path " + System.getProperty("java.class.path"));
String pathIgnore = System.getProperty("path.ignore");
+ System.out.println("path.ignore " + pathIgnore);
if (pathIgnore==null)
{
pathIgnore = classLocation.toString();
@@ -427,19 +524,23 @@
}
- ArrayList urls = new ArrayList();
+ //ArrayList urls = new ArrayList();
+ ArrayList<URL> urls = new ArrayList<URL>();
while (tokenString.hasMoreElements())
{
String value = tokenString.nextToken();
URL itemLocation = new File(value).toURL();
if (!itemLocation.equals(classLocation) && !itemLocation.toString().equals(pathIgnore))
{
- //System.out.println("Location:" + itemLocation);
urls.add(itemLocation);
}
+ else
+ {
+ System.out.println("Skipping " + classLocation);
+ }
}
- URL[] urlArray= (URL[])urls.toArray(new URL[urls.size()]);
+ URL[] urlArray= urls.toArray(new URL[urls.size()]);
ClassLoader masterClassLoader = URLClassLoader.newInstance(urlArray,null);
@@ -449,31 +550,29 @@
return appClassLoader;
}
+ private void initMethods(Class aspectManagerClass, Class xmlLoader) throws Exception
+ {
+ aspectXmkLoaderUndeployXmlMethod = xmlLoader.getDeclaredMethod("undeployXML", new Class[] {URL.class});
+ aspectManagerInstanceMethod = aspectManagerClass.getDeclaredMethod("instance", new Class[0]);
+ aspectManagerUnregisterClassLoader = aspectManagerClass.getDeclaredMethod("unregisterClassLoader", new Class[] {ClassLoader.class});
+ }
private void undeploy(Class xmlLoader) throws Exception
{
-
- String strurl = (String)AccessController.doPrivileged(new PrivilegedAction(){
-
- public Object run()
- {
- return System.getProperty("jboss.aop.path");
- }
-
- });
-// String strurl = System.getProperty("jboss.aop.path");
+ String strurl = jbossAopPath;
assertNotNull("Property jboss.aop.path should be defined",strurl);
strurl = strurl.replace('\\','/');
+ if (!strurl.startsWith("/"))
+ {
+ strurl = "/" + strurl;
+ }
URL url = new URL("file://" + strurl);
+
+ aspectXmkLoaderUndeployXmlMethod.invoke(null, new Object[] {url});
- Method method = xmlLoader.getDeclaredMethod("undeployXML", new Class[] {URL.class});
- method.invoke(null, new Object[] {url});
-
System.out.println("\n====================================================================");
System.out.println("!!!! Undeployed " + url);
System.out.println("=====================================================================\n");
-
- //AspectXmlLoader.undeployXML(url); -- I need to use reflection operations as I don't want to take the chance on letting the JVM using a different classLoader
}
}
More information about the jboss-cvs-commits
mailing list