26
votes

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)!!

15
In my case, this problem came up when moved a project from java 1.6 to java 1.5. I don't know if this matters.Raul Luna

15 Answers

14
votes

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.

9
votes

add also hamcrest.jar to your testing classpath

8
votes

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.

3
votes

Faced exactly the same problem in eclipse but resolved it following the given steps

  1. Go to Preferences | Java | JUnit
  2. Click "Add Package" and add "org.hamcrest.*"

Voila... the problem is gone..

2
votes

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...

2
votes

I had same problem with jUnit 4.11, Ant and Ivy. This code works for me but you have to make sure that you have hamcrest-core-1.3.jar (for jUnit 4.11) in your lib folder.

<property name="lib.dir">lib</property>
<property name="test.dir">src/test/java</property>
<property name="build.test">build/test/java</property>

<path id="test.path.id">
    <path location="${build.test}" />
    <path refid="lib.path.id" />
</path>

<path id="lib.path.id">
    <fileset dir="${lib.dir}" />
</path>

<!-- ================================= 
              Runs Tests         
================================= -->
<target name="junit">
    <junit>
        <classpath refid="test.path.id" />
        <batchtest>
            <fileset dir="${test.dir}" />
        </batchtest>
        <formatter type="plain" usefile="false" />
    </junit>
</target>
2
votes

I added hamcrest and junit jar files to java/lib/ext directory and than it worked fine for me.

1
votes

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).

1
votes

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.

1
votes

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.

0
votes

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

0
votes

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).

0
votes

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.

0
votes

In eclipse, this happens when you add the junit jar using the Properties->Libaries->Add External JARs...

Rather than using Properties->Libaries->Add Library... which allows you to select Junit3 or Junit4 and automatically adds the hamcrest library to the path.

0
votes

I had a similar problem which I overcome by placing a copy of "hamcrest-core-1.3.jar" under \lib folder.