tags:

views:

3873

answers:

4

I can't figure out why I am getting this exception from my ant build.xml file. I checked and everything is in the classpath. Why must this be so complicated?!

I had trouble with Ant in the past and it seems it always is something related to the classpath. I am pointing to junit.jar using both ways: within eclipse: window->preferences->ant->runtime->Ant Home->Add External Jars, and also within the build.xml script. This time Ant is not able to locate my test class in the junit task. Is there something wrong with the way I am pointing to this class?

    <target name="init">
     <property name="sourceDir" value="src"/>
        <property name="outputDir" value="build" />
        <property name="junitLocation" value="C:\...\org.junit4_4.3.1\junit.jar" /> 
    </target>

<target name="clean" depends="init">
         <delete dir="${outputDir}" />
</target>

<target name="prepare" depends="clean">
          <mkdir dir="${outputDir}" />
</target>

    <target name="compile" depends="prepare">
         <javac srcdir="${sourceDir}" destdir="${outputDir}" classpath="${junitLocation}"/>
    </target>

    <path id="classpath">
      <pathelement location="${outputDir}" />
      <pathelement location="${junitLocation}" />
    </path>

    <target name="testApplication" depends="compile">
      <echo>Running the junit tests...</echo>
      <junit fork="yes" haltonfailure="yes">
        <test name="my.package.MyTest" />
        <formatter type="plain" usefile="false" />     
        <classpath refid="classpath" />
      </junit>
    </target>

I am always getting:

    [junit] Testsuite: my.package.MyTest
    [junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
    [junit]     Caused an ERROR
    [junit] my.package.MyTest
    [junit] java.lang.ClassNotFoundException: my.package.MyTest
    [junit]     at java.net.URLClassLoader$1.run(Unknown Source)
    [junit]     at java.security.AccessController.doPrivileged(Native Method)
    [junit]     at java.net.URLClassLoader.findClass(Unknown Source)
    [junit]     at java.lang.ClassLoader.loadClass(Unknown Source)
    [junit]     at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    [junit]     at java.lang.ClassLoader.loadClass(Unknown Source)
    [junit]     at java.lang.ClassLoader.loadClassInternal(Unknown Source)
    [junit]     at java.lang.Class.forName0(Native Method)
    [junit]     at java.lang.Class.forName(Unknown Source)

BUILD FAILED

Apparently, Ant finds junit.jar and attempts to start the test, but why can't it find my test class? I point to the folder with compiled test class. So I know that junit is on Ant's classpath at least, but the ClassNotFound puzzles me.

Any ideas perhaps? Many thanks!

+1  A: 

Are you sure your test class is in the build folder? You're invoking junit in a separate JVM (fork=true) so it's possible that working folder would change during that invocation and with build being relative, that may cause a problem.

Run ant from command line (not from Eclipse) with -verbose or -debug switch to see the detailed classpath / working dir junit is being invoked with and post the results back here if you're still can't resolve this issue.

ChssPly76
I'll be danged! I think you are on to something! I changed the script to <junit fork="no" haltonfailure="yes"> and it worked!Are there any particular disadvantages to set fork=no?
denchr
It spawns a new JVM. Unless there's need for you to do so, you may want to just leave it off so your tests run in-process with ant. Or, if you do use fork, set 'dir' attribute to explicitly specify your working folder.
ChssPly76
Forking is useful if your tests use a lot of memory; when fork=yes you can set the maxmemory which does a -Xmx on the forked JVM instance.
Spyder
Thanks a bunch! I did run ant with -verbose (from within eclipse). It is confirmed that with fork=yes, junit fails. But with fork=no, it works just fine. What should I be looking for in the ant verbose output? I concentrate only on what [junit] task spits out, so a good starting point might be the classpath statements
denchr
If you do need to keep fork set to yes, set dir to your "root" folder (e.g. parent of `build`). That should work. Details are here: http://ant.apache.org/manual/OptionalTasks/junit.html
ChssPly76
A: 

You don't need to add the JUnit jar to the classpath. If ant can't find it, the <junit> task won't run.

I suggest trying different ways of specifying the classpath as described in the ant doc at http://ant.apache.org/manual/using.html#path; specifically <classpath path="${srcdir}" /> might help.

If not, ChssPly76's suggestion of running ant -debug from the command line is the best bet. You'll want to bump up the buffer on your command prompt window though, because ant's debugger is extremely verbose.

Spyder
You're wrong about `<junit>` not running without junit.jar. Since Ant 1.7 it's possible to put junit.jar in classpath of `<junit>` task as long as `ant-junit.jar` is available to Ant. That said, I do agree it's not necessarily the best approach
ChssPly76
Don't know why this was voted down. +1 to offset
ChssPly76
Thanks for that. I don't use Ant 1.7 much :)
Spyder
A: 

You should solve your problem if you insert your classpath section testApplication section ...

Regards

Patrick
A: 

it looks like you didn't set the right classpath, are you sure you have successfully compile your test class and output to outputDir before testing, I'd like to you read http://www.javarmi.com/2010/09/junit-and-ant/

chisrsig