You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by bu...@apache.org on 2012/07/19 21:40:38 UTC

[Bug 53571] New: ClassLoader problems with Subclass of JUnitTask

https://issues.apache.org/bugzilla/show_bug.cgi?id=53571

          Priority: P2
            Bug ID: 53571
          Assignee: notifications@ant.apache.org
           Summary: ClassLoader problems with Subclass of JUnitTask
          Severity: normal
    Classification: Unclassified
                OS: All
          Reporter: brian.mcdonald@ca.com
          Hardware: All
            Status: NEW
           Version: 1.8.4
         Component: Optional Tasks
           Product: Ant

So I've run into a problem with my custom ant task that extends JUnitTask.
Because my subclass is loaded out of my custom jar and my custom jar also
requires the junit.jar on the tasked classpath I've run into an inconsistency
in how the JUnitTask determines if it needs to use a split classloader.

Here is the exception I run into:

/examples/build.xml:38: The <classpath> for <junit> must include junit.jar if
not in Ant's own classpath
    at
org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.createMirror(JUnitTask.java:695)
    at
org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.setupJUnitDelegate(JUnitTask.java:745)
    at
org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.execute(JUnitTask.java:755)

The <junit> classpath _does_ have the junit.jar, but it's not on Ant's own
classpath. This error is caused my an inconsistency between which classloader
is being used to check the junit classes.

Here is the code in question from JUnitTask - in setupJUnitDelegate it uses the
JUnitTask.class.getClassloader (which will be loaded in the default ant
classloader which does not have junit.jar on it's classpath). It then uses
splitJunit to determine if it needs to use the split classpath, but in my case
splitJunit is false when it should be true. Since it's false it uses the
JUnitTask.class.getClassLoader() to try and load the junit classes which fails.

    protected void setupJUnitDelegate() {
        ClassLoader myLoader = JUnitTask.class.getClassLoader();
        if (splitJunit) {


The reason splitJunit is false is because it's using a different classloader to
do it's initial check. Here it's set to the result of !addClasspathResource():

    public void init() {
        antRuntimeClasses = new Path(getProject());
        splitJunit = !addClasspathResource("/junit/framework/TestCase.class");
…
        } else {
            mirrorLoader = myLoader;
        }


And addClasspathResource uses getClass().getClassLoader() which in my case is
my subclass whose <taskdef> classpath _does_ have the junit.jar classes on it's
classpath (my subclass requires it to load).

    private boolean addClasspathResource(String resource) {
…
        File f = LoaderUtils.getResourceSource(getClass().getClassLoader(),
                                               resource);


Changing addClasspathResource to use JUnitTask.class.getClassLoader() seems to
solve the problem, but the fact that it's not consistent is probably all that's
required.

-- 
You are receiving this mail because:
You are the assignee for the bug.

[Bug 53571] ClassLoader problems with Subclass of JUnitTask

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=53571

Jesse Glick <jg...@apache.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |jglick@apache.org
         Resolution|---                         |FIXED
   Target Milestone|---                         |1.9.0

--- Comment #1 from Jesse Glick <jg...@apache.org> ---
Committed revision 1363748. Using JUnitTask.class in both places now, rather
than getClass() - while your subclass may happen to link against junit.jar, the
mirror classes are designed to let the task instance use whatever copy of JUnit
is in the project classpath.

-- 
You are receiving this mail because:
You are the assignee for the bug.