Solution for ClassNotFoundException with JUnit and Ant
Last time I sat down to work on a new build.xml file I ran into a ClassNotFoundException while trying to run my JUnit tests. It turns out that a few other people have experienced the same problem, too. None of the pages I found from Google had a solution posted so I will post the solution I came up with. The problem that I am trying to solve is:
Testsuite: net.anthonychaves.test.geoip.locator.LocatorServiceTest
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 3.634 secTestcase: testGetLocation took 3.622 sec
Caused an ERROR
net/anthonychaves/geoip/locator/LocatorService
java.lang.NoClassDefFoundError: net/anthonychaves/geoip/locator/LocatorService
at net.anthonychaves.test.geoip.locator.LocatorServiceTest.setUp(Unknown Source)
at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423)
at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137)
The first thing I did was fire up Ant with the -debug flag so I could examine the classpath carefully. My *Test.class files were definitely in the classpath passed to the forked JVM but they were not found. Because I was using a forked JVM and doing so erases a lot of useful information I set fork=”no” and ran it again. This time I got:
Finding class net.anthonychaves.test.geoip.locator.LocatorServiceTest
Ignoring Exception java.util.zip.ZipException: error in opening zip file reading resource net/anthonychaves/test/geoip/locator/LocatorServiceTest.class from /home/anthony/workspace/IPAddressLocatorClient/build/classes/net/anthonychaves/test/geoip/locator/LocatorHelpersTest.class
The good news is that this is a message that I did not get while running the test in a forked JVM. The better news is I had a good idea what the exception means. Apparently Ant expects all the classes to be in Jar files rather than in directories on the file system. A few tweaks to my build.xml file and it looked like this: build.xml
Now I’m creating two jar files, one for the application and one for the unit tests. After the unit test jar is created I run them in the JUnit task after setting the classpath with the test jar file. I would have liked to put off creating the application jar file until I knew the JUnit tests passed but that is not an option at this point. I don’t feel strongly enough to make it an option either. I have a 2.4 GHz Pentium 4 computer, I can afford to make a few extra jar files.
When debugging Ant build problems run with the -debug flag and turn off JVM forking if possible. If I didn’t do those two things I would still be debugging.




