Java task cannot find classpath - ant

I have a small program that displays some database tables. The program has a class with a main() method. I have an ant script that builds and runs the program.
The ant script is able to build the program and runs its tests but not run it. When i run it I get the following error:
[java] Could not find com.my.MyProgram. Make sure you have it in your classpath
[java] at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:138)
The issue here is that my java task target is not finding my classpath. I have printed my classpath and it has all the necessary jars and classes.
Here is part of my build.xml:
<path id="classpath">
<pathelement location="${build.src}" />
<pathelement location="${build.test}" />
<fileset dir="${lib}">
<include name="**/*.jar"/>
</fileset>
</path>
<target name="run" depends="compile">
<java classname="MyProgram" fork="false">
<classpath refid="classpath"/>
</java>
</target>
Does anyone know why the run task cannot find my classpath?

Related

Ant - Junit - eclipse - build.xml - java.lang.ClassNotFoundException error

I am new to Ant and getting java.lang.ClassNotFoundException. when running my Junit from eclipse / Ant build.xml, However, when running my unit test from eclipse by itself my test passes with no issue. There should be something wrong with my classpath which i cannot figure out.
My envrmnts are:
Java_home: C:/Program Files/Java/jdk1.7.0_25
Ant_home: C:/Users/Armen/javaFolder/apache-ant-1.9.2/bin
JUnit_home: C:/Users/Armen/javaFolder/apache-ant-1.9.2/bin/junit-4.10.jar
My Build.xml
<property name="junitLocation">C:/Users/Armen/javaFolder/apache-ant-1.9.2/bin/junit-4.10.jar</property>
<property name="antLocation2">C:/Users/Armen/JavaFolder/apache-ant-1.9.2.jar</property>
<property name="testCode">C:/Users/Armen/workspace/MockingObjects/test/demo</property>
<property name="srcCode">C:/Users/Armen/workspace/MockingObjects/src/demo</property>
<target name="compile" depends="clean">
<javac includeantruntime="false" srcdir="./src" destdir="./staging" ></javac>
</target>
<target name="run" depends="compile, unitTest">
<java classname="demo.AccountService"><classpath path="./staging"></classpath></java>
</target>
<target name="unitTest" depends="compile">
<junit printsummary="true" showoutput="true" haltonfailure="false" fork="yes">
<formatter type="plain" usefile="true"/>
<test name="demo.TestAccountService" outfile="./result" ></test>
<classpath>
<pathelement location="${junitLocation}"/>
<pathelement location="${antLocation}"/>
<pathelement location="${testCode}" />
<pathelement location="${srcCode}"/>
</classpath>
</junit>
</target>
<target name="clean">
<delete dir="staging"></delete>
<mkdir dir="./staging"/>
</target>
enter image description here
You don't have any step in your build script to compile the unit tests, and when you tell JUnit to run, you also don't include the compiled classes in the classpath - only the source files.
There are therefore 2 things you need to do:
Add an additional build step similar to the following
<target name="test-compile" depends="compile">
<javac includeantruntime="false" srcdir="./test" destdir="./test-classes" />
</target>
then change your current unitTest target to depend on test-compile rather than compile.
Tell JUnit where your classes are, not your source code. Change your testCode and srcCode properties to
<property name="testCode">C:/Users/Armen/workspace/MockingObjects/test-classes</property>
<property name="srcCode">C:/Users/Armen/workspace/MockingObjects/staging</property>
Note From your compile and run steps, it isn't clear if your code is properly structured in Java Packages or, if it is in packages, that you understand how these work. I've made the assumption that your code is in a package of demo and therefore stripped that part of the path out of your compiled class locations.

How to execute Ant build in command line

I have an Ant build file, and I try to execute it in the command line with the following command:
$ C:\Program Files (x86)\.....>ant -f C:\Silk4J\Automation\iControlSilk4J\build.xml
But nothing happens, and the result is:
BUILD SUCCESSFUL
Total time: 0 seconds
My environment variable is correct.
What is the problem? Here is my build file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- WARNING: Eclipse auto-generated file.
Any modifications will be overwritten.
To include a user specific buildfile here, simply create one in the same
directory with the processing instruction <?eclipse.ant.import?>
as the first entry and export the buildfile again. -->
<project basedir="." default="build" name="iControlSilk4J">
<property environment="env"/>
<property name="ECLIPSE_HOME" value="../../../Program Files (x86)/Silk/SilkTest/eclipse"/>
<property name="junit.output.dir" value="junit"/>
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.6"/>
<property name="source" value="1.6"/>
<path id="Silk Test JTF 13.5.0 Library.libraryclasspath">
<pathelement location="../../../Program Files (x86)/Silk/SilkTest/ng/JTF/silktest-jtf-nodeps.jar"/>
</path>
<path id="JUnit 4.libraryclasspath">
<pathelement location="${ECLIPSE_HOME}/plugins/org.junit_4.8.2.v4_8_2_v20110321-1705/junit.jar"/>
<pathelement location="${ECLIPSE_HOME}/plugins/org.hamcrest.core_1.1.0.v20090501071000.jar"/>
</path>
<path id="iControlSilk4J.classpath">
<pathelement location="bin"/>
<pathelement location="lib/apache-log4j.jar"/>
<pathelement location="lib/commons-io-2.4.jar"/>
<pathelement location="lib/commons-lang3-3.1.jar"/>
<pathelement location="lib/junit.jar"/>
<pathelement location="lib/org.hamcrest.core_1.1.0.v20090501071000.jar"/>
<pathelement location="lib/silktest-jtf-nodeps.jar"/>
<path refid="Silk Test JTF 13.5.0 Library.libraryclasspath"/>
<path refid="JUnit 4.libraryclasspath"/>
<pathelement location="../../../Users/Admin/Desktop/java-mail-1.4.4.jar"/>
<pathelement location="../../../Users/Admin/Desktop/javax.activation.jar"/>
<pathelement location="lib/joda-time-2.3.jar"/>
</path>
<target name="init">
<mkdir dir="bin"/>
<copy includeemptydirs="false" todir="bin">
<fileset dir="src">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="bin"/>
</target>
<target depends="clean" name="cleanall"/>
<target depends="build-subprojects,build-project" name="build"/>
<target name="build-subprojects"/>
<target depends="init" name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="iControlSilk4J.classpath"/>
</javac>
</target>
<target description="Build all projects which reference this project. Useful to propagate changes." name="build-refprojects"/>
<target description="copy Eclipse compiler jars to ant lib directory" name="init-eclipse-compiler">
<copy todir="${ant.library.dir}">
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</copy>
<unzip dest="${ant.library.dir}">
<patternset includes="jdtCompilerAdapter.jar"/>
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</unzip>
</target>
<target description="compile project with Eclipse compiler" name="build-eclipse-compiler">
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
<antcall target="build"/>
...
Go to the Ant website and download. This way, you have a copy of Ant outside of Eclipse. I recommend to put it under the C:\ant directory. This way, it doesn't have any spaces in the directory names. In your System Control Panel, set the Environment Variable ANT_HOME to this directory, then pre-pend to the System PATHvariable, %ANT_HOME%\bin. This way, you don't have to put in the whole directory name.
Assuming you did the above, try this:
C:\> cd \Silk4J\Automation\iControlSilk4J
C:\Silk4J\Automation\iControlSilk4J> ant -d build
This will do several things:
It will eliminate the possibility that the problem is with Eclipe's version of Ant.
It is way easier to type
Since you're executing the build.xml in the directory where it exists, you don't end up with the possibility that your Ant build can't locate a particular directory.
The -d will print out a lot of output, so you might want to capture it, or set your terminal buffer to something like 99999, and run cls first to clear out the buffer. This way, you'll capture all of the output from the beginning in the terminal buffer.
Let's see how Ant should be executing. You didn't specify any targets to execute, so Ant should be taking the default build target. Here it is:
<target depends="build-subprojects,build-project" name="build"/>
The build target does nothing itself. However, it depends upon two other targets, so these will be called first:
The first target is build-subprojects:
<target name="build-subprojects"/>
This does nothing at all. It doesn't even have a dependency.
The next target specified is build-project does have code:
<target depends="init" name="build-project">
This target does contain tasks, and some dependent targets. Before build-project executes, it will first run the init target:
<target name="init">
<mkdir dir="bin"/>
<copy includeemptydirs="false" todir="bin">
<fileset dir="src">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
This target creates a directory called bin, then copies all files under the src tree with the suffix *.java over to the bin directory. The includeemptydirs mean that directories without non-java code will not be created.
Ant uses a scheme to do minimal work. For example, if the bin directory is created, the <mkdir/> task is not executed. Also, if a file was previously copied, or there are no non-Java files in your src directory tree, the <copy/> task won't run. However, the init target will still be executed.
Next, we go back to our previous build-project target:
<target depends="init" name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="iControlSilk4J.classpath"/>
</javac>
</target>
Look at this line:
<echo message="${ant.project.name}: ${ant.file}"/>
That should have always executed. Did your output print:
[echo] iControlSilk4J: C:\Silk4J\Automation\iControlSilk4J\build.xml
Maybe you didn't realize that was from your build.
After that, it runs the <javac/> task. That is, if there's any files to actually compile. Again, Ant tries to avoid work it doesn't have to do. If all of the *.java files have previously been compiled, the <javac/> task won't execute.
And, that's the end of the build. Your build might not have done anything simply because there was nothing to do. You can try running the clean task, and then build:
C:\Silk4J\Automation\iControlSilk4J> ant -d clean build
However, Ant usually prints the target being executed. You should have seen this:
init:
build-subprojects:
build-projects:
[echo] iControlSilk4J: C:\Silk4J\Automation\iControlSilk4J\build.xml
build:
Build Successful
Note that the targets are all printed out in order they're executed, and the tasks are printed out as they are executed. However, if there's nothing to compile, or nothing to copy, then you won't see these tasks being executed. Does this look like your output? If so, it could be there's nothing to do.
If the bin directory already exists, <mkdir/> isn't going to execute.
If there are no non-Java files in src, or they have already been copied into bin, the <copy/> task won't execute.
If there are no Java file in your src directory, or they have already been compiled, the <java/> task won't run.
If you look at the output from the -d debug, you'll see Ant looking at a task, then explaining why a particular task wasn't executed. Plus, the debug option will explain how Ant decides what tasks to execute.
See if that helps.
Try running all targets individually to check that all are running correct
run ant target name to run a target individually
e.g. ant build-project
Also the default target you specified is
project basedir="." default="build" name="iControlSilk4J"
This will only execute build-subprojects,build-project and init
is it still actual?
As I can see you wrote <target depends="build-subprojects,build-project" name="build"/>, then you wrote <target name="build-subprojects"/> (it does nothing). Could it be a reason?
Does this <echo message="${ant.project.name}: ${ant.file}"/> print appropriate message? If no then target is not running.
Take a look at the next link http://www.sqaforums.com/showflat.php?Number=623277

No output from Checkstyle in ANT

I am not using an automated build tool. Just Checkstyle 5.5 and ANT 1.8.
I am trying to have Checkstyle run in my ANT script. The ANT script executes without error, but doesn't seem to call Checkstyle. I get no output except ANT reports BUILD SUCCESSFUL.
Here is my ant script:
<project name="ccu" xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
<target name="checkstyle" description="Generates a report of code convention violations.">
<cs:checkstyle config="custom_check.xml">
<fileset dir="src" casesensitive="yes">
<include name="**/*.java"/>
</fileset>
<!--
<fileset dir="src" includes="**\*.java"/>
-->
</cs:checkstyle>
</target>
</project>
what am i missing?
It was a classpath problem. For some reason I needed to direct the ANT classpath to the class files not the jar.
My final script looks like this:
<project name="ccu" xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
<taskdef resource="checkstyletask.properties">
<classpath>
<pathelement location="C:\myClasses\bin"/>
<pathelement location="C:\checkstyle-5.5\checkstyle-5.5-all.jar"/>
</classpath>
</taskdef>
<checkstyle config="custom_check.xml">
<fileset dir="src" includes="**/*.java"/>
</checkstyle>
</project>

Cobertura - Code Coverage Instrumentation

I am trying some code-coverage analysis for first time and I was working on getting cobertura using ANT. My questions might be silly, but thought of asking here. I have the following in my ANT scripts. While reading over through cobertura the next step was instrumentation. What is code coverage instrumentation?
<target name="cobertura" depends="checkstyle">
<property name="cobertura.dir" location="C:\\Softwares- packages\\Corbetura\\cobertura-1.9.4.1" />
<path id ="cobertura.classpath">
<fileset dir="${cobertura.dir}">
<include name="cobertura.jar"/>
<include name="lib/**/*.jar"/>
</fileset>
</path>
<taskdef resource="tasks.properties" classpathref="cobertura.classpath"/>
</target>
cobertura modifies your class files so that it can compute the coverage. I typically 'instrument' a copy of the jar files that I use for executing tests and use a copy that hasn't been instrument as my build artifact.
Here is the build file I used when I first set up cobertura via ant:
The cobertura-instrument target instruments my code and writes the instrumented classes to a separate directory like you said.
The junit target compiles the test, then instruments the tests, then runs the tests, then produces the report. These steps are all done by declaring dependent targets to the junit one.
<path id="cobertura.classpath">
<fileset dir="${cobertura.dir}">
<include name="cobertura.jar" />
<include name="lib/**/*.jar" />
</fileset>
</path>
<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
<!-- Delete an existing coburtura datafile -->
<delete file="${cobertura.datafile}"/>
<antcall target="cobertura.clean"/>
<!-- Instrument the code with cobertura to test for coverage -->
<cobertura-instrument todir="${cobertura.instrumented.classes}" datafile="${cobertura.datafile}">
<fileset dir="${build.dir}/classes/">
<include name="**/*.class"/>
</fileset>
</cobertura-instrument>
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
<fileset dir="${tests.src.dir}">
<include name="**/*.java" />
</fileset>
I believe you're looking for the "cobertura-instrument" task. See here

Simple ant build script that supports src/ and test/?

Currently I use an IDE for all my builds and unit tests. Now I have a need to use ant. I found a few simple ant build.xml scripts but they didn't support a separate Junit test/ dir. My projects are structured as follows:
src/
com/foo/
com/bar/
test/ -- Mirror of src/, with all *Test.java files.
com/foo/
com/bar/
lib/ -- All Java libs, including junit 4.
How can a construct a small ant script that builds my src/ and test/ Java classes then runs all my JUnit tests?
I define <path> elements for each target.
This is an excerpt from my build file, you'll have to adapt some paths and properties, but you can get the idea:
<path id="src.path">
<pathelement path="src/"/>
</path>
<path id="compile.path">
<path refid="src.path"/>
<fileset dir="lib/">
<include name="**/*.jar"/>
</fileset>
</path>
<path id="unit.test.path">
<path refid="compile.path"/>
<pathelement path="test/"/>
</path>
<target name="compile">
<javac destdir="bin">
<src path="src"/>
<classpath refid="compile.path"/>
</javac>
</target>
<target name="compileUnitTests" depends="compile">
<javac srcdir="test/" destdir="bin">
<classpath refid="unit.test.path"/>
</javac>
</target>
<target name="runUnitTests" depends="compileUnitTests">
<junit printsummary="yes" haltonfailure="no">
<jvmarg value="-Dfile.encoding=UTF-8"/>
<classpath refid="unit.test.path"/>
<formatter type="xml"/>
<batchtest fork="yes" todir="${this.report}">
<fileset dir="test">
<include name="${test.pattern}"/>
<exclude name="**/AllTests.class"/>
<exclude name="**/*$*.class"/>
</fileset>
</batchtest>
</junit>
</target>
And if you need to refine this to your needs, as cotton.m says, go read the ant task docs. Using ant with your specific directory structure does require some knowledge of the tool, don't expect you'll easily find ready-made examples that just work with your exact requirements.
I don't understand the question. Are you asking how to set the default target? Select which target to run when executing or do you just not know how to write build.xml files? It's not that hard really. See http://ant.apache.org/manual/tutorial-HelloWorldWithAnt.html and http://ant.apache.org/manual/

Resources