views:

3609

answers:

11

Ok, I'm frustrated! I've hunted around for a good number of hours and am still stumped.

Environment: WinXP, Eclipse Galileo 3.5 (straight install - no extra plugins).

So, I have a simple JUnit test. It runs fine from it's internal Eclipse JUnit run configuration. This class has no dependencies on anything. To narrow this problem down as much as possible it simply contains:

@Test
public void testX() {
    assertEquals("1", new Integer(1).toString());
}

No sweat so far. Now I want to take the super advanced step of running this test case from within Ant (the final goal is to integrate with Hudson).

So, I create a build.xml:

<project name="Test" default="basic">
    <property name="default.target.dir" value="${basedir}/target" />
    <property name="test.report.dir" value="${default.target.dir}/test-reports" />

    <target name="basic">
        <mkdir dir="${test.report.dir}" />
        <junit fork="true" printSummary="true" showOutput="true">
            <formatter type="plain" />
            <classpath>
                <pathelement path="${basedir}/bin "/>
            </classpath>
            <batchtest fork="true" todir="${test.report.dir}" >
                <fileset dir="${basedir}/bin">
                    <include name="**/*Test.*" />
                </fileset>
            </batchtest>
        </junit>
    </target>
</project>

${basedir} is the Java project name in the workspace that contains the source, classes and build file. All .java's and the build.xml are in ${basedir}/src. The .class files are in ${basedir}/bin.

I have added eclipse-install-dir/plugins/org.junit4_4.5.0.v20090423/junit.jar to the Ant Runtime Classpath via Windows / Preferences / Ant / Runtime / Contributed Entries. ant-junit.jar is in Ant Home Entries.

So, what happens when I run this insanely complex target? My report file contains:

Testsuite: com.xyz.test.RussianTest
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec

Testcase: initializationError took 0 sec
Caused an ERROR
org/hamcrest/SelfDescribing
java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$000(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClassInternal(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    Caused by: java.lang.ClassNotFoundException: org.hamcrest.SelfDescribing
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClassInternal(Unknown Source)

What is this org.hamcrest.SelfDescribing class? Something to do with mocks? OK, fine. But why the dependency? I'm not doing anything at all with it. This is literally a Java project with no dependencies other than JUnit.

Stumped (and frustrated)!!

+1  A: 

add also hamcrest.jar to your testing classpath

dfa
A: 

JUnit 4.5 includes Hamcrest as part of its matching system. You'll want to ensure you've got that JAR file on your classpath too

MrWiggles
A: 

The class you are missing is included in junit from version 4.4 and on (link).

Check if an older version of jUnit is in your classpath. Try running the ant script in a command shell to see if you get the same error. If you do, then probably ant uses a jUnit version older than 4.4

Update:

Look at the ANT_HOME folder. Right click a build.xml file, select the second "Ant build" at the Run As.. dialog. A dialog for editing the ant run configuration will open (There might be an easier way to open this). Go to the Classpath tab. Add the newest junit at the classpath (lib folder of ant).

kgiannakakis
probably he is using a -dep version of junit.jar
dfa
Thanks for all the replies. We're on to something, but not solved yet. I downloaded junit-4.6.jar from junit.org. It contains the org.hamcrest classes.I add that jar to the classpath and still get the same error.I do not have a stray Ant or JUnit install floating around someplace.
K-Boo
This is crazy. More info...The Java project has the Eclipse-standard JUnit4 library. That library includes two jars - plugins/org.junit4_4.5.0.v20090423/junit.jarplugins/org.hamcrest.core_1.1.0.v20090501071000.jarIn my Ant Global Entries I have added those two jars.When I run the task I get the exact same error. A NCDFE on org.hamcrest.SelfDescribing.Completely baffled...
K-Boo
A: 

I dont think it is required to add the JUnit jar to your Ant classpath. Instead, check that you have the JUnit library in your Java Build Path (Windows/Preferences/Java/Build Path/Classpath Variables).

akf
A: 

OK. I finally worked around this issue. I won't say "solved" since I am still quite confused as to what's going on. Anyway...

I downloaded the latest Ant (1.7.1) and JUnit (4.6) and exploded them into an external directory - NOT in the workspace or "in" Eclipse in any way.

I then went to Windows / Preferences / Ant / Runtime / Classpath / Ant Home Entries and kill all the existing (default) values. I replaced them with the contents of the newly downloaded Ant lib directory.

I then added the downloaded junit.jar in Global Entries. It contains the org.hamcrest classes, just like the junit.jar included with Eclipse, so I don't know why this is necessary, but it is.

That's it. My junit task in the build file works perfectly.

K-Boo
A: 

I had the same problem and tried many ways to alter the classpath. The easiest solution for me was to use the parameter fork="no" at the junit target. Seems like Eclipse can "automagically" do it better than me...

Bananeweizen
+3  A: 

I downloaded JUnit 4.7 and put junit-4.7.jar in my build path (instead of the older version). That solved it. I didn't touch ant.

JB
Junit 4.8 in my case.
Ritesh M Nayak
A: 

I searched the Eclipse install directory from the top level for "hamcrest.jar" (wildcard '*' around hamcrest not showing in this web post). I then added the one found jar-file to the classpath in Ant build.xml. Fixed.

Rolf
A: 

I had this problem trying to run junit tests from Run -> Run As -> JUnit Test (I checked, and I do have the latest junit plugin (junit4_4.5.0) installed).

I created a new directory (externalJars) in the eclipse installation main directory, downloaded the most recent junit jar (4.8.1) there.

Next, from Eclipse, with the project selected, I modified the jar files in the build path (Project --> Properties --> Java Build Path). When I first tried junit, I added the junit jar file from the plugin/org.junit4_4.5.0.v20090824 folder. I removed this jar file, and I added externalJars/junit-4.8.1.jar (the one I just downloaded) to the build path by clicking the "Add External Jars" button.

hamcrest.org is a library of "matchers". You can find info at:

http://code.google.com/p/hamcrest/

Provides a library of matcher objects (also known as constraints or predicates) allowing 'match' rules to be defined declaratively, to be used in other frameworks. Typical scenarios include testing frameworks, mocking libraries and UI validation rules.

Hamcrest has been ported to Java, C++, Objective-C, Python and PhP.

Note: Hamcrest it is not a testing library: it just happens that matchers are very useful for testing.

Jay Elston
A: 

Had the exact same problem and fixed it following Jay Elston's reply. Using JUnit 4.8.1 w/eclipse 3.5.1.

Sean Horgan
+1  A: 

I found the reason to an identical problem, but only when running the test with Ant on the commandline.

You might want to run Ant in debug mode (ant -d) and watch out for this statement:

[junit] Implicitly adding /usr/share/ant/lib/junit4.jar:...

Im my case, this JAR was added to the end of my classpath when running the test and overrode my JUnit reference in my Ant script.

It turned out that my Ant installation was bundled with a set of older JUnit libs. I had to remove the junit4.jar above in order to make my Ant classpath ref to take effect.

PålOliver
+1. This worked for me (Ubuntu Karmic).
Manoj Govindan