java.lang.ClassNotFoundException: main.java.KmToMileTest - java

I have a problem with running JUnit test with Ant in OSX Terminal.
I understand the problem must lie with the classpaths or I have messed up my file directory, please help!
The errors I'm getting:
test1:
[junit] Running main.java.KmToMileTest
[junit] Testsuite: main.java.KmToMileTest
[junit] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0 sec
[junit] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0 sec
[junit]
[junit] Caused an ERROR
[junit] main.java.KmToMileTest
[junit] java.lang.ClassNotFoundException: main.java.KmToMileTest
[junit] at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
[junit] at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
[junit] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
[junit] at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
[junit] at java.lang.Class.forName0(Native Method)
[junit] at java.lang.Class.forName(Class.java:264)
[junit]
[junit] Test main.java.KmToMileTest FAILED
BUILD SUCCESSFUL
Here's my build.xml:
<project name="MyProject" default="test1" basedir=".">
<description>
Ant build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="bin" location="bin"/>
<property name="junit" location="junit/"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory -->
<mkdir dir="${bin}"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${bin} -->
<javac includeantruntime="false"
srcdir="${src}"
destdir="${bin}"
debug="on">
<classpath location="${junit}/junit-4.11.jar"/>
<classpath location="${junit}/hamcrest-all-1.3.jar"/>
</javac>
</target>
<target name="test1" depends="compile">
<!-- Run junit tests -->
<junit printsummary="yes" fork="yes">
<classpath location="${bin}"/>
<classpath location="${junit}/junit-4.11.jar"/>
<classpath location="${junit}/hamcrest-all-1.3.jar"/>
<formatter type="plain" usefile="false" /> <!-- to screen -->
<formatter type="plain" /> <!-- to file -->
<test name="main.java.KmToMileTest"/>
</junit>
</target>
<target name="clean">
<!-- Delete the ${bin} folder -->
<delete dir="${bin}"/>
</target>
</project>
My files directory:
project:
build.xml
junit/
hamcrest-all-1.3.jar
junit-4.11.jar
bin/prject/
lengthConverter.class
kmToMilesTest.class
milesToKmTest.class
parameterizedTest.class
src/main/java/
lengthConverter.java
kmToMilesTest.java
milesToKmTest.java
parameterizedTest.java

I see a number of issues:
You set your source directory for the compiler to src, when it should be src/main/java
Your package does not match your folder structure (it appears that kmToMilesTest has a package of prject (which is why the classes are in bin/prject instead of bin), but is not in the src/main/java/prject folder).
Your test name does not match; You try to run the test class main.java.KmToMileTest, but your test class is named prject.kmToMilesTest

Related

Ant throws ClassNotFoundException when running JUnit tests that work in Eclipse

I've been scratching my head at this for a while now. I have been looking at all related posts on Stack Overflow and the ones I could find with Google but it was to no avail.
I'm trying to build a Java program that has Mancala.java as main class. The directory structure is as follows: a folder called mancala with one subfolder called test and one subfolder called mancala_test. The test folder has the Mancala.java file and other files and the mancala_test folder contains the JUnit test file called MancalaTest.java. In Eclipse the test file runs, but when running via Ant I get the following error:
init:
compile:
[javac] Compiling 6 source files to C:\Users\[me]\Desktop\build
runjunit:
[junit] Running mancala_test.MancalaTest
[junit] Testsuite: mancala_test.MancalaTest
[junit] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0 sec
[junit] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0 sec
[junit]
[junit] Caused an ERROR
[junit] mancala_test.MancalaTest
[junit] java.lang.ClassNotFoundException: mancala_test.MancalaTest
[junit] at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
[junit] at java.lang.Class.forName0(Native Method)
[junit] at java.lang.Class.forName(Class.java:266)
[junit]
[junit] Test mancala_test.MancalaTest FAILED
BUILD SUCCESSFUL
Total time: 1 second
I'm using the following build file in the mancala folder:
<project default="runjunit" name="Compile and run JUnit tests">
<target name="clean">
<delete dir="build"/>
</target>
<target name="clean2">
<delete dir="build"/>
</target>
<target name="init">
<record name="build.log" loglevel="verbose" append="false"/>
</target>
<target name="runjunit" depends="compile">
<junit printsummary="on">
<test name="mancala_test.MancalaTest"/>
<classpath>
<pathelement location="build"/>
</classpath>
<formatter
type="plain"
usefile="false"
/>
</junit>
</target>
<target name="compile" depends="init">
<mkdir dir="build"/>
<javac includeantruntime="false" srcdir="./test" destdir="build"/>
</target>
</project>
Other possible relevant information is that the Mancala.java file contains two static initializers being the GUI and the Mancala class itself (e.g., static Mancala mancala; static GUI gui; and the Mancala_test.java just uses a Mancala mancala = new Mancala() object in each test.
An example of one test:
#Test
public void testAmountOfSeed() {
Mancala mancala = new Mancala();
mancala.divideBoard();
int totalAmountOfSeed = 0;
for (int i = 0; i < mancala.gameBoard.size(); i++) {
totalAmountOfSeed +=mancala.gameBoard.get(i).getSeed();
}
assertTrue("Total amount of seed in initial condition not 48!", totalAmountOfSeed == 48);
}
It probably has something to do with the classpaths (I tried every possible variation I could think of) or the static stuff. I would be very grateful if someone could put me out of my misery.
/edit Directory structure after build: http://i.imgur.com/vvFJtNB.png
You need a target to compile the test_mancala directory and add the destination of that compile to your runjunit target's classpath.
<target name="compile-test_mancala" depends="init, compile">
<mkdir dir="build-test_mancala"/>
<javac includeantruntime="false" srcdir="./test_mancala" destdir="build_mancala">
<classpath>
<pathelement location="build"/>
<pathelement location="${junit_lib}"/>
</classpath>
</javac>
</target>
<target name="runjunit" depends="compile, compile-test_mancala">
<junit printsummary="on">
<test name="mancala_test.MancalaTest"/>
<classpath>
<pathelement location="build"/>
<pathelement location="build-test_mancala"/>
</classpath>
<formatter
type="plain"
usefile="false"
/>
</junit>
</target>

Ant and Junit test java.lang.ClassNotFoundException

I'm having a problem with an ant build.xml file that's giving me a java.lang.ClassNotFoundExcpetion. I am able to run it fine on windows, but when I port it over to a Linux vm, I get the exception.
<project name="OBJECT" default="compile" >
<!--
Properties for the directories of .java
These are the locations the the source files
These are the locations of the .jar dependancy
-->
<property name="src.dir" location="src"/>
<property name="src.java.dir" location="${src.dir}/csc439"/>
<property name="src.test.dir" location="${src.dir}/test"/>
<property name="lib.dir" location="lib"/>
<!--
Properties for the directories of .class
This gets deleted when ant clean is run
-->
<property name="target.dir" location="target"/>
<property name="target.classes.java.dir" location="${target.dir}/classes/java"/>
<property name="target.classes.test.dir" location="${target.dir}/classes/test"/>
<!--Properties for the report directory-->
<property name="target.report.dir" location="${target.dir}/report"/>
<!--
compile.java
Creates a directory for the .class files of the Java files for the file being tested
Compiles the files and places the .class into the java file created
Imports the necissary .jar files from the lib directory
-->
<target name="compile.java">
<mkdir dir="${target.classes.java.dir}"/>
<javac includeantruntime="true" destdir="${target.classes.java.dir}">
<src path="${src.java.dir}"/>
<classpath>
<pathelement location="${target.classes.java.dir}"/>
<pathelement location="${lib.dir}"/>
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</classpath>
</javac>
</target>
<!--
compile.test
Depends on compile.java to complete first
Creates a directory for the .class files of the Test files
Compiles the files and places the .class into the test file created
-->
<target name="compile.test" depends="compile.java">
<mkdir dir="${target.classes.test.dir}"/>
<javac includeantruntime="true" destdir="${target.classes.test.dir}">
<src path="${src.test.dir}"/>
<classpath>
<pathelement location="${target.classes.java.dir}"/>
<pathelement location="${lib.dir}"/>
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</classpath>
</javac>
</target>
<!--
compile
This the the default
Depends on compile.java, and compile.test
-->
<target name="compile" depends="compile.java,compile.test"/>
<!--
test
Depends on compile
Creates the report file
Runs the JUnit test TestCacheSuite in the test file in the test .class directory
-->
<target name="test" depends="compile">
<mkdir dir="${target.report.dir}"/>
<junit printsummary="yes" haltonerror="yes" haltonfailure="yes" fork="yes">
<formatter type="plain" usefile="false"/>
<formatter type="xml"/>
<test name="test.TestMediaPlayer" todir="${target.report.dir}"/>
<classpath>
<pathelement location="${target.classes.java.dir}"/>
<pathelement location="${target.classes.test.dir}"/>
</classpath>
</junit>
</target>
<!--
report
Depends on test
Creates the file for html documents
Depends on Test
Creates a Junit report
-->
<target name="report" depends="test">
<mkdir dir="${target.report.dir}/html"/>
<junitreport todir="${target.report.dir}">
<fileset dir="${target.report.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report todir="${target.report.dir}/html"/>
</junitreport>
</target>
<!--
clean
Deletes the target directory
This file contains all of the .class files
This file contains all of the reports
-->
<target name = "clean">
<delete dir = "${target.dir}"/>
</target>
This is the error I get while running it on linux.
[junit] Running test.MockObject
[junit] Testsuite: test.MockObject
[junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
[junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
[junit]
[junit] Caused an ERROR
[junit] test.MockObject
[junit] java.lang.ClassNotFoundException: test.MockObject
[junit] at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
[junit] at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
[junit] at java.security.AccessController.doPrivileged(Native Method)
[junit] at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
[junit] at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
[junit] at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
[junit] at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
[junit] at java.lang.Class.forName0(Native Method)
[junit] at java.lang.Class.forName(Class.java:264)
[junit]
With the exact same build file I get it to run fine on windows.
I have run it fine from command line on windows, as well as using Eclipse both work flawlessly.
From everything that I read it says that I need to check the CLASSPATH, and PATH variables.
I have done this, but I must be doing something wrong. I don't understand why with the same build information that it would run in one os, and not the other.
Any help would be greatly appreciated
There isn't tons and tons of information to go on, but to hazard a guess, I'd say you needed to add your ${lib.dir} as a <pathelement> in the classpath of your junit invocation.
<echoproperties/>
This is your best friend in such cases. If it runs fine on windows, but does not run on linux, then it must be some problem with the file separator (however with ant / works on windows as well), or simply you have different current directory (you use relative path everywhere). If you have different current directory, you will see it in the output of echoproperties as "user.dir". You can set also the javac to verbose="true" and then you can compare the windows output of the script with the linux output.
For me this issue arose because my test file used an inner class. this is compiled as a seperate classfile in eclipse and you will need both classname.class and classname$1.class for ant to run your test.
Try adding junit jar location to your classpath element. I don't know how but that worked for me!
Something like,
<classpath>
<pathelement location="path/to/junit/jar"/>
<pathelement location="${target.classes.java.dir}"/>
<pathelement location="${target.classes.test.dir}"/>
</classpath>

New to Ant, ClassNotFoundException with JUnit

I've been scratching my head over this for a while now (Googled a bunch, looked through other related SO posts to no avail). I have a Java program comprised of two files, Logic and Tests. Tests contains about a hundred JUnit tests, and I've gotten 100% success rate with said tests by calling javac *.java followed by java org.junit.runner.JUnitCore Tests. However when I run my build.xml with a simple ant -verbose test (in order to follow the output since I'm new to all this), I get the following output:
[junit] Testsuite: Tests
[junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
[junit]
[junit] Null Test: Caused an ERROR
[junit] Tests
[junit] java.lang.ClassNotFoundException: Tests
[junit] at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
[junit] at java.lang.Class.forName0(Native Method)
[junit] at java.lang.Class.forName(Class.java:247)
[junit]
[junit]
[junit] Test Tests FAILED
BUILD SUCCESSFUL
My build.xml is as follows:
<project name="ETL_Automation" default="test" basedir=".">
<path id="classpath.base">
</path>
<path id="classpath.test">
<pathelement location="${basedir}/mysql-connector-java-5.1.18-bin.jar" />
<pathelement location="${basedir}/junit-4.10.jar"/>
<path refid="classpath.base" />
</path>
<target name="compile">
<javac srcdir="${basedir}">
<classpath refid="classpath.test"/>
</javac>
</target>
<target name="test" depends="compile">
<junit fork="no">
<classpath refid="classpath.test" />
<formatter type="brief" usefile="false" />
<batchtest>
<fileset dir="${basedir}/" includes="Tests.class" />
</batchtest>
</junit>
</target>
<target name="clean" depends="test">
<delete>
<fileset dir="${basedir}" includes="*.class"/>
</delete>
</target>
The directory structure is pretty straightforward. Tests.java, Logic.java, junit-4.10.jar, mysql-connector-java-5.1.18-bin.jar, build.xml, and a referenced .properties file are all in the same folder. The java code references external files but those are unrelated to this particular issue. I don't know if the classpath could be the cause of this issue (as I'm pretty convinced what I currently have doesn't work).
Thanks!
You will need to add the directory with the Tests.class to the classpath.tests classpath (which is ${basedir} in your setup)
Try:
<path id="classpath.test">
<pathelement location="${basedir}/mysql-connector-java-5.1.18-bin.jar" />
<pathelement location="${basedir}/junit-4.10.jar"/>
<pathelement location="${basedir}" />
<path refid="classpath.base" />
</path>

JUnit AntClassNotFoundException

I'm getting ClassNotFoundException when running "ant test" target.
All path and libraries exists including junit-4.8.1.jar located in lib folder.
<project name="progs" default="test" basedir=".">
<!--++++++++++ Properties ++++++++++-->
<property name="src-main" location="PC_Serie_3"/>
<property name="src-test" location="PC_Serie_3_Tests"/>
<property name="target" location="target"/>
<property name="target-classes" location="target/PC_Serie_3"/>
<property name="target-test-classes" location="target/PC_Serie_3_Tests"/>
<property name="target-test-reports" location="target/test-reports"/>
<path id="test.extlibs.class.path">
<fileset dir="lib">
<include name="**/*.jar" />
</fileset>
</path>
<!--++++++++++ Targets ++++++++++-->
<target name="init" description ="Creates the target folders">
<mkdir dir="${target-classes}"/>
<mkdir dir="${target-test-classes}"/>
<mkdir dir="${target-test-reports}"/>
</target>
<target name="clean" description="Removes the target folders" >
<delete includeEmptyDirs="true" failonerror="false" verbose="true" >
<fileset dir="${target}" defaultexcludes="false"/>
</delete>
</target>
<target name="compile-main" depends="init" description="Compiles the main source" >
<javac debug="true"
srcdir="${src-main}"
destdir="${target-classes}"
includeantruntime="false">
</javac>
</target>
<target name="compile-test" depends="compile-main" description="Compiles the test source" >
<javac debug="true"
debugLevel="source"
srcdir="${src-test}"
destdir="${target-test-classes}"
includeantruntime="true">
<classpath>
<pathelement location="${target-classes}"/>
<path refid="test.extlibs.class.path" />
</classpath>
</javac>
</target>
<target name="test" depends="compile-test" description="Runs the tests">
<echo>Running the junit tests...</echo>
<junit printsummary="yes" haltonfailure="true" showoutput="true" >
<classpath>
<pathelement location="${src-main}"/>
<pathelement location="${target-classes}"/>
<pathelement location="${target-test-classes}"/>
<path refid="test.extlibs.class.path" />
</classpath>
<batchtest fork="yes" todir="${target-test-reports}" >
<fileset dir="${src-test}">
<include name="**/*Test*.java"/>
</fileset>
<formatter type="xml"/>
<formatter type="plain" usefile="false" />
</batchtest>
</junit>
</target>
<target name="package" depends="test" description="Packages the main classes into a jar" >
<buildnumber />
<jar jarfile="${target}/library.jar" basedir="${target-classes}"/>
</target>
<!-- USAGE: ant deploy-app -->
<target name="deploy-lib" depends="package">
</target>
</project>
Console Output:
test:
[echo] Running the junit tests...
[junit] Running src.DocumentDBTests.DocumentDBv1Test
[junit] Testsuite: src.DocumentDBTests.DocumentDBv1Test
[junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
[junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
[junit]
[junit] Caused an ERROR
[junit] src.DocumentDBTests.DocumentDBv1Test
[junit] java.lang.ClassNotFoundException: src.DocumentDBTests.DocumentDBv1Te
st
[junit] at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
[junit] at java.security.AccessController.doPrivileged(Native Method)
[junit] at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
[junit] at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
[junit] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
[junit] at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
[junit] at java.lang.Class.forName0(Native Method)
[junit] at java.lang.Class.forName(Class.java:169)
[junit]
I think the problem is that you are pointing junit to the source files and not the complied class files. Also, the fileset is including *Test*.java when it should be including *Test*.class
Try replacing your batchtest element with this:
<batchtest fork="yes" todir="${target-test-reports}" >
<fileset dir="${target-test-classes}">
<include name="**/*Test*.class"/>
</fileset>
<formatter type="xml"/>
<formatter type="plain" usefile="false" />
</batchtest>

How do I set the Java library path from a Java task?

Is it possible to specify a library path in a java task? Like the equivalent of:
java -Djava.library.path=somedir Whatever
<propertyset> and <syspropertyset> should be what you are looking for
See also this thread for instance.
You can set them one by one within your java ant task:
<sysproperty key="test.classes.dir"
value="${build.classes.dir}"/>
tedious... or you can pass them down as a block of Ant properties:
<syspropertyset>
<propertyref prefix="test."/>
</syspropertyset>
You can reference external system properties:
<propertyset id="proxy.settings">
<propertyref prefix="http."/>
<propertyref prefix="https."/>
<propertyref prefix="socks."/>
</propertyset>
and then use them within your java ant task: This propertyset can be used on demand; when passed down to a new process, all current ant properties that match the given prefixes are passed down:
<java>
<!--copy all proxy settings from the running JVM-->
<syspropertyset refid="proxy.settings"/>
...
</java>
I completely missed the fact you were trying to pass java.library.path property!
As mentioned in this thread:
if you try to set its value outside of the java task, Ant ignores it. So I put all properties except for that one in my syspropertyset and it works as expected.
meaning:
<property name="java.library.path" location="${dist}"/>
<propertyset id="java.props">
<propertyref name="java.library.path"/>
</propertyset>
<target name="debug">
<java>
<syspropertyset refid="java.props"/>
</java>
</target>
will not work, but the following should:
<target name="debug">
<java>
<sysproperty key="java.library.path" path="${dist}"/>
</java>
</target>
(although you might try that with the "fork" attribute set to true if it does not work)
(Note: you cannot modify its value though)
For JUnit ant task set your java.library.path in section <junit>
<target name="test" depends="build-test">
<junit printsummary="yes" fork="true">
<sysproperty key="java.library.path"
path="path/where/your/library/is/located"/>
<!-- ... -->
</junit>
</target>
See ant manual, page JUnit, section <sysproperty> for more details.
The rest of this answer are details for beginners.
1. Load your library in your junit fixture
public class MyFeatureTest {
#Before
public void load_library_xxxxx() {
System.loadLibrary("library_name_without_extension");
}
#Test
public void on_that_case_my_feature_does_this() {
// ...
}
}
2. Set the java.library.path in your ant script
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project default="build" name="xxxxxx">
<!-- ... -->
<property name="lib_dir" value="path/where/your/library/is/located"/>
<!-- ... -->
<target name="test" depends="build-test">
<mkdir dir="${test_report_dir}" />
<junit printsummary="yes" fork="true">
<sysproperty key="java.library.path" path="${lib_dir}"/>
<classpath>
<pathelement location="${antlr}" />
<!-- ... -->
</classpath>
<formatter type="xml" />
<formatter type="plain" />
<batchtest todir="${test_report_dir}">
<fileset dir="${test_src_dir}">
<include name="**/*Test.java" />
</fileset>
</batchtest>
</junit>
</target>
</project>
3. Use ant option -v to check java.library.path
Search a line like [junit] '-Djava.library.path= within your ant output to check the presence and value of java.library.path. The expression [...] represent text that has been removed for clarity.
> ant test -v
[...]
test:
[mkdir] Skipping /home/user/my/dir/report because it already exists.
[junit] Implicitly adding /usr/share/ant/lib/junit.jar:[...] to CLASSPATH
[junit] Executing '/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java' with arguments:
[junit] '-Djava.library.path=/home/user/my/project/path/where/your/library/is/located'
[junit] '-classpath'
[junit] '/home/user/my/project/external/antlr.jar:[...]'
[junit] 'org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner'
[junit] 'com.example.myproject.myfeature.MyFeatureTest'
[junit] 'skipNonTests=false'
[junit] 'filtertrace=true'
[junit] 'haltOnError=false'
[junit] 'haltOnFailure=false'
[junit] 'formatter=org.apache.tools.ant.taskdefs.optional.junit.SummaryJUnitResultFormatter'
[junit] 'showoutput=false'
[junit] 'outputtoformatters=true'
[junit] 'logfailedtests=true'
[junit] 'threadid=0'
[junit] 'logtestlistenerevents=false'
[junit] 'formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,/home/user/my/dir/report/TEST-com.example.myproject.myfeature.MyFeatureTest.xml'
[junit] 'formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter,/home/user/my/dir/report/TEST-com.example.myproject.myfeature.MyFeatureTest.txt'
[junit] 'crashfile=/home/user/my/project/junitvmwatcher4952613017772370651.properties'
[junit] 'propsfile=/home/user/my/project/junit3999929381398716397.properties'
[junit]
[junit] The ' characters around the executable and arguments are
[junit] not part of the command.
[...]
I've managed to get it to work using the environment variable ANT_OPTS. I would like to see this done from a task if it's possible.

Categories