Java Mailing List Archive

http://www.ant-tasks.com/

Apache Ant Archive

» Ant Users List
» Ant Developers List
The AntClassLoader created in one JUnitTask can not be used in another.

The AntClassLoader created in one JUnitTask can not be used in another.

2007-05-10       - By Xu Xin
Reply:     1     2  

Hello everyone,

I had a problem with JUnitTask, I have a couple of xml files where I also
have a lot of targets which contain <junit> tasks, originally I used the
Apache Ant's JUnitTask, but unfortunately the test run had performance
issue, that was caused by  each <test> has its own classloader, as a result
some static memory was created multiple times.

So I customized the JUnitTask by making the classloader created for each
test cacheable, the <junit> task has the same customer classpath elements
share the same classloader, so I can save the memory as I can, but the
strange thing is  junit testcase was not recognized, it seemed a
classloading issue, but after I ran the tests in DEBUG mode, I can find the
classloader hierarchy is correct, I do not know what's going wrong. The
snippet code is below:



private void createClassLoader() {
   Path userClasspath = getCommandline().getClasspath();

   if (userClasspath != null) {

   //get cached classloader from the pool if it exists
     classLoader = getCachedClassLoader(userClasspath);


     Path classpath = (Path) userClasspath.clone();
     if (includeAntRuntime) {
       log("Implicitly adding " + antRuntimeClasses + " to CLASSPATH",
           Project.MSG_VERBOSE);
       classpath.append(antRuntimeClasses);
     }
     if (reloading || classLoader == null) {

     //create a new one if no cached

       classLoader = getProject().createClassLoader(classpath);
       if (getClass().getClassLoader() != null
           && getClass().getClassLoader() != Project.class.getClassLoader())
{
         classLoader.setParent(getClass().getClassLoader());
       }
       classLoader.setParentFirst(false);
       classLoader.addJavaLibraries();
       // make sure the test will be accepted as a TestCase
       classLoader.addSystemPackageRoot("junit");
       // will cause trouble in JDK 1.1 if omitted
       classLoader.addSystemPackageRoot("org.apache.tools.ant");
       // testlogic: this fixes 'not a JUnitResultFormatter' issue
       classLoader.addSystemPackageRoot("org.testlogic.testrunner.ant.junit
");

       cacheClassLoader(userClasspath, classLoader);
     } else {

    //this is the cached one
       if (classLoader != null) {
         classLoader.setProject(this.getProject());
         classLoader.setClassPath(classpath);
           if (getClass().getClassLoader() != null
             && getClass().getClassLoader() != Project.class.getClassLoader())
{
           classLoader.setParent(getClass().getClassLoader());
         }

       }
     }

   }
 }

and next pass the classLoader to JUnitTestRunner as usual, the test class
can be loaded, as well as JUnit class: TestSuite and Test, but when
constructing TestCase, TestSuite complains the test class is not
implementation of Test, but I can see the test class was loaded by cached
AntClassLoader, and TestSuite and Test were loaded by its parent
classloader. So could you guys please tell me what's wrong?
Thanks
--
anfernee

©2008 ant-tasks.com - Jax Systems, LLC, U.S.A.