Mysterious Ant script - java

I have problem with my Ant script. I have to run junit test on ant run.
My current script looks like:
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="doc" location="doc"/>
<property name="dist" location="dest"/>
<property name="lib" location="lib"/>
<property name="app" value="${ant.project.name}.jar"/>
<presetdef name="javac">
<javac includeantruntime="false"/>
</presetdef>
<target name="clean">
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
<target name="compile" depends="clean" description="Compile">
<mkdir dir="${build}"/>
<javac srcdir="${src}"
destdir="${build}"
classpath="${lib}/junit-4.10.jar:${lib}/swing-layout-1.0.4.jar:${src}">
</javac>
<copy todir="${build}/checkers">
<fileset dir="${lib}">
<include name="resources/**" />
</fileset>
</copy>
</target>
<target name="run" depends="compile">
<echo>Running the junit tests...</echo>
<junit showoutput="no" fork="no">
<classpath>
<pathelement location="${build}"/>
<pathelement path="${build}:${lib}/junit-4.10.jar"/>
</classpath>
<formatter type="plain" usefile="false" />
<test name="checkers.CheckersTest"/>
</junit>
</target>
On my Linux box test runs fine and everything looks good. But on my Windows, Ant gives my nice:
java.lang.NoClassDefFoundError: junit/framework/TestListener
Ant in debug mode however told me that he loaded TestListener.class from suplied junit-4.10.jar file.

Try this answer http://youtrack.jetbrains.com/issue/TW-4882:
To fix the problem you should either use fork="true" attribute for
junit task (in this case classpath will be created correctly), or
to copy junit.jar to ANT_HOME/lib (to ensure correct class loading).
Here is also bug for this https://bugs.eclipse.org/bugs/show_bug.cgi?id=36198. Last comment says JUnit is available in Ant via the org.eclipse.ant.optional.junit fragment

Related

Ant java lang class not found exception

I am pretty new to Ant but, I have a general understanding. I just cannot get this to work.
<?xml version="1.0"?>
<project name="Ser321 Assignment 3 Java Movie Library with Ant build file and API support."
default="targets" basedir="."
xmlns:dn="antlib:org.apache.ant.dotnet"
xmlns="antlib:org.apache.tools.ant"
xmlns:cpptasks="antlib:net.sf.antcontrib.cpptasks">
<property name="src.dir" value="src"/>
<property name="lib.dir" value="lib" />
<property name="build" value="classes"/>
<property name="bin" value="bin"/>
<property name="obj" value="obj"/>
<property environment="env"/>
<property name="user" value="${env.USERNAME}"/>
<target name="targets">
<echo message="Targets are clean, prepare, build, execute, and targets"/>
</target>
<path id="compile.classpath">
<pathelement location="${build}"/>
</path>
<path id="external.classpath">
<pathelement location="${lib.dir}/json.jar"/>
</path>
<target name="prepare">
<mkdir dir="${build}" />
<mkdir dir="${bin}"/>
<mkdir dir="${obj}"/>
</target>
<target name="clean">
<delete dir="${build}" failonerror="false"/>
<delete dir="${bin}" failonerror="false"/>
<delete dir="${obj}" failonerror="false"/>
</target>
<target name="build" depends="prepare">
<javac srcdir="${src.dir}"
includeantruntime="false"
destdir="${build}">
<classpath refid="external.classpath"/>
</javac>
</target>
<target name="execute.jar" depends="build"
description="Run the program">
<java classname="Main" fork="yes">
<classpath refid="compile.classpath"/>
</java>
</target>
</project>
This gives me my classes folder with movie as the next folder and then in there, I have my 3 classes. However, it keeps saying class not found and I have no idea what I am doing wrong.
Figured it out. I am an airhead sometimes.
<target name="execute.jar" depends="build"
description="Run the program">
<java classname="movie.Main" fork="yes"> //added movie.main instead of Main
<classpath refid="compile.classpath"/>
</java>

Run multiple JUnit tests with Ant

probably this is a very basic question but I am new to java, so please bear with me.
I am trying to run java task in ant and I want to know if there is any way to get all the name of the classes inside a folder in ant?
This is the build.xml file
<project default='run-test' basedir=".">
<property name="src" value="src"/>
<property name="test" value="test"/>
<property name="build" value="build"/>
<property name="build-classes" value="build/classes"/>
<property name="build-test-classes" value="build/test/classes"/>
<property name="junit4" value="/usr/share/java/junit4.jar"/>
<target name="init">
<mkdir dir="${build-classes}"/>
<mkdir dir="${build-test-classes}"/>
</target>
<target name="compile" depends="init">
<javac includeantruntime="false"
srcdir="${src}"
destdir="${build-classes}"/>
</target>
<target name="compile-test" depends="compile">
<javac includeantruntime="false"
classpath="${junit4}:${build-classes}"
srcdir="${test}"
destdir="${build-test-classes}"/>
</target>
<target name="run-test" depends="compile-test">
<java classpath="${junit4}:${build-classes}:${build-test-classes}"
classname="org.junit.runner.JUnitCore"
args="myclass.MyClassTest"/> <---This is my problem
</target>
<target name="clean">
<delete dir="${build}"/>
</target>
</project>
I have to manually mention the name of the class in the arguments.
Is there any way where I can only mention the folder and all the class names will be taken up as arguments for the javatask automatically?
Ant ships with a task for running JUnit tests.
In the run-test target in your example, replace the <java> task with the following:
<junit>
<formatter type="plain" usefile="false"/>
<classpath>
<pathelement location="${junit4}"/>
<pathelement location="${build-classes}"/>
<pathelement location="${build-test-classes}"/>
</classpath>
<batchtest>
<fileset dir="${build-test-classes}">
<include name="**/*.class"/>
</fileset>
</batchtest>
</junit>

Ant does not work as I expect in Eclipse

I am new to ANT and to use it, I simply created a new java project in Eclipse that just print the word Welcome in the screen. I ran the program using Eclipse and "Welcome" was successfully printed on the screen. This is my program
public class welcome {
public static void main(String[] args)
{
System.out.println("Welcome!!!");
}
}
Then I just followed the usual way to build ANT file using Eclipse so I used Export feature and choose ANT buildfile.
This the buildfile I have got:
<?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="test">
<property environment="env"/>
<property name="ECLIPSE_HOME" value="../../../../usr/lib/eclipse"/>
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.7"/>
<property name="source" value="1.7"/>
<path id="test.classpath">
<pathelement location="bin"/>
</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" includeantruntime="false" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="test.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"/>
</target>
<target name="welcome">
<java classname="welcome" failonerror="true" fork="yes">
<classpath refid="test.classpath"/>
</java>
</target>
</project>
when I ran the program as Ant, it only gives me a message that build successful! without printing the "Welcome" word on screen!
This is the output
> Buildfile: /home/name/workspace/test/build.xml
> build-subprojects: init: build-project:
> [echo] test: /home/name/workspace/test/build.xml build: BUILD SUCCESSFUL Total time: 376 milliseconds
The default target of your ant file is "build" which will create a jar file of your project (which can be then executed later). If you want to run your project via ant, change the target to "welcome" (see the end of your ant file). That should execute the program as you expected.
Apache Ant is a Java library and command-line tool whose mission is to
drive processes described in build files as targets and extension
points dependent upon each other. The main known usage of Ant is the
build of Java applications
Also class names first letter should be CAPITALIZED ...
More or less this is how your ant should look like, but i still dont understand why you want to use ANT for whatever you are trying to do here.
<project name="Welcome" basedir="." default="main">
<property name="src.dir" value="src"/>
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="jar.dir" value="${build.dir}/jar"/>
<property name="main-class" value="(packagename).(class name)"/>
<target name="clean">
<delete dir="${build.dir}"/>
</target>
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}" destdir="${classes.dir}"/>
</target>
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
</jar>
</target>
<target name="run" depends="jar">
<java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/>
</target>
<target name="clean-build" depends="clean,jar"/>
<target name="main" depends="clean,run"/>

Making Java step in Ant script fail the build

Please excuse if the question is dumb, I'm only 2nd day on Ant and Java hacking together some CI solution with next to no knowledge of Ant or Java.
So I wish a build to fail if (my) java program run as a step within the build decides that the build must fail.
I thought of just throwing an unhandled exception in the Java program or using System.exit() to shut down the JVM but they seem quite nasty.
Is there a nice way of ant failing the build if a java step decides it should?
For the <java> task, there is an attribute failonerror. If you set it to yes (or true), the build will fail if the process returned anything else than 0.
The problem is that for returning some value from a java call, this call must System.exit(value). For it to not kill your ant, you also need to provide fork=true to run in a new JVM.
So, the java call could look like this:
<java jar="..."
fork="yes"
failonerror="yes">
</java>
Of course, you could also have your Java program implement the Ant Task API and load/call it as a proper ant task. Then it can itself decide what to do (and will be more configurable, too).
The Ant manual shows a built-in task named Fail which you can configure with specific conditions to make the build fail.
<fail message="Files are missing.">
<condition>
<not>
<resourcecount count="2">
<fileset id="fs" dir="." includes="one.txt,two.txt"/>
</resourcecount>
</not>
</condition>
</fail>
You might want to look into that one.
Ant ought to be straightforward. It does fail a build if a particular step does not succeed. I think the behavior you want is already built-in.
As for your custom step, my advice would be to find a way to do that outside of Ant for now while you get the rest of the CI flow working. Better to make that much progress rather than falling into a hole over one detail.
It might help if you describe what your program is doing. Perhaps there's a better way to accomplish what you need.
UPDATE: I don't think you should head down this path. The tests you run with CC should be unit tests. If you have to package and deploy the application to test, I'd call those integration tests. Run those separately as part of your QA step, not the build.
You're doing the right thing with Selenium; I like your rigor and effort. But I'd recommend running just the unit tests with CC, package and deploy the app to a QA server, then run your Selenium tests as JUnits. They're scripted and fast.
I also wonder about the wisdom of using Selenium to check for widget placements in the UI. That seems brittle to me; best left to a human.
Here's a generic Ant build that I re-use often. Feel free to use it as reference. Keep telling yourself "This ought to be simple." IF it gets too hard, you're doing it wrong.
<?xml version="1.0" encoding="UTF-8"?>
<project name="xslt-converter" basedir="." default="package">
<property name="version" value="1.6"/>
<property name="haltonfailure" value="no"/>
<property name="out" value="out"/>
<property name="production.src" value="src"/>
<property name="production.lib" value="lib"/>
<property name="production.resources" value="config"/>
<property name="production.classes" value="${out}/production/${ant.project.name}"/>
<property name="test.src" value="test"/>
<property name="test.lib" value="lib"/>
<property name="test.resources" value="config"/>
<property name="test.classes" value="${out}/test/${ant.project.name}"/>
<property name="exploded" value="out/exploded/${ant.project.name}"/>
<property name="exploded.classes" value="${exploded}/WEB-INF/classes"/>
<property name="exploded.lib" value="${exploded}/WEB-INF/lib"/>
<property name="reports.out" value="${out}/reports"/>
<property name="junit.out" value="${reports.out}/junit"/>
<property name="testng.out" value="${reports.out}/testng"/>
<path id="production.class.path">
<pathelement location="${production.classes}"/>
<pathelement location="${production.resources}"/>
<fileset dir="${production.lib}">
<include name="**/*.jar"/>
<exclude name="**/junit*.jar"/>
<exclude name="**/*test*.jar"/>
</fileset>
</path>
<path id="test.class.path">
<path refid="production.class.path"/>
<pathelement location="${test.classes}"/>
<pathelement location="${test.resources}"/>
<fileset dir="${test.lib}">
<include name="**/junit*.jar"/>
<include name="**/*test*.jar"/>
</fileset>
</path>
<path id="testng.class.path">
<fileset dir="${test.lib}">
<include name="**/testng*.jar"/>
</fileset>
</path>
<available file="${out}" property="outputExists"/>
<target name="clean" description="remove all generated artifacts" if="outputExists">
<delete dir="${out}" includeEmptyDirs="true"/>
<delete dir="${reports.out}" includeEmptyDirs="true"/>
</target>
<target name="create" description="create the output directories" unless="outputExists">
<mkdir dir="${production.classes}"/>
<mkdir dir="${test.classes}"/>
<mkdir dir="${reports.out}"/>
<mkdir dir="${junit.out}"/>
<mkdir dir="${testng.out}"/>
<mkdir dir="${exploded.classes}"/>
<mkdir dir="${exploded.lib}"/>
</target>
<target name="compile" description="compile all .java source files" depends="create">
<!-- Debug output
<property name="production.class.path" refid="production.class.path"/>
<echo message="${production.class.path}"/>
-->
<javac srcdir="src" destdir="${out}/production/${ant.project.name}" debug="on" source="${version}">
<classpath refid="production.class.path"/>
<include name="**/*.java"/>
<exclude name="**/*Test.java"/>
</javac>
<javac srcdir="${test.src}" destdir="${out}/test/${ant.project.name}" debug="on" source="${version}">
<classpath refid="test.class.path"/>
<include name="**/*Test.java"/>
</javac>
</target>
<target name="junit-test" description="run all junit tests" depends="compile">
<!-- Debug output
<property name="test.class.path" refid="test.class.path"/>
<echo message="${test.class.path}"/>
-->
<junit printsummary="yes" haltonfailure="${haltonfailure}">
<classpath refid="test.class.path"/>
<formatter type="xml"/>
<batchtest fork="yes" todir="${junit.out}">
<fileset dir="${test.src}">
<include name="**/*Test.java"/>
</fileset>
</batchtest>
</junit>
<junitreport todir="${junit.out}">
<fileset dir="${junit.out}">
<include name="TEST-*.xml"/>
</fileset>
<report todir="${junit.out}" format="frames"/>
</junitreport>
</target>
<taskdef resource="testngtasks" classpathref="testng.class.path"/>
<target name="testng-test" description="run all testng tests" depends="compile">
<!-- Debug output
<property name="test.class.path" refid="test.class.path"/>
<echo message="${test.class.path}"/>
-->
<testng classpathref="test.class.path" outputDir="${testng.out}" haltOnFailure="${haltonfailure}" verbose="2" parallel="methods" threadcount="50">
<classfileset dir="${out}/test/${ant.project.name}" includes="**/*.class"/>
</testng>
</target>
<target name="exploded" description="create exploded deployment" depends="testng-test">
<copy todir="${exploded.classes}">
<fileset dir="${production.classes}"/>
</copy>
<copy todir="${exploded.lib}">
<fileset dir="${production.lib}"/>
</copy>
</target>
<target name="package" description="create package file" depends="exploded">
<jar destfile="${out}/${ant.project.name}.jar" basedir="${production.classes}" includes="**/*.class"/>
</target>
</project>

Ant+Junit works on first run and never again

Hey guys I've been trying all day to get an ant file to automatically build my project. The file (appended below) was on a web page I found and is pretty thorough.
My problem is that it works as long as I don't run the "clean" target. Once the I run the "clean" target the "test" target ceases to work. I get NoClassFound errors on all test classes. Even though it worked earlier.
I'm working on a Macbook (10.5.8) using the latest version of eclipse. This error occurs running the file from eclipse and from a terminal using Ant version 1.7.1
I modified the file slightly to adapt it to my file structure which is as follows:
src/
packageA.packageB/
ClassA.java
...
ClassN.java
unittests/
packageA.packageB/
AllClassTests.java
ClassATest.java
...
ClassNTest.java
lib/
junit-4.7.jar
The ant file is:
<project name="SampleJUnitTests" default="dist" basedir=".">
<description>
DataTypes Build File
</description>
<!-- set global properties for this build -->
<property name="project_name" value="DataTypes"/>
<property name="src" location="src"/>
<property name="build" location="bin"/>
<property name="dist" location="dist"/>
<property name="lib" location="lib"/>
<property name="reports" location="reports"/>
<property name="tests" location="unittests"/>
<property name="tmp" location="tmp_file"/>
<!-- the names of various distributable files -->
<property name="jar_name" value="${project_name}.jar"/>
<property name="war_name" value="${project_name}.war"/>
<!-- top level targets -->
<target name="compile" depends="init" description="compile the source code " >
<javac srcdir="${src}" destdir="${build}">
<classpath>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
</javac>
</target>
<target name="dist" depends="compile" description="generate the distributable files " >
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/${jar_name}" basedir="${build}"/>
</target>
<target name="clean" description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
<delete dir="${reports}"/>
<delete dir="${tmp}"/>
</target>
<target name="run-tests" depends="compile" description="run your test suite" >
<junit printsummary="yes" haltonfailure="no" showoutput="yes" tempdir="${tmp}">
<classpath>
<pathelement path="${build}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
<batchtest fork="yes" todir="${reports}/raw/">
<formatter type="xml"/>
<fileset dir="${tests}">
<include name="**/*.java"/>
<exclude name="**/All*Tests.java"/>
</fileset>
</batchtest>
</junit>
</target>
<target name ="test" depends="run-tests">
<junitreport todir="${reports}">
<fileset dir="${reports}/raw/">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${reports}\html\"/>
</junitreport>
</target>
<target name ="run" depends="" description="if this project can be run, run it" >
</target>
<!-- supporting targets -->
<target name="init" description="initialize the build environment" >
<!-- Create the time stamp -->
<tstamp/>
<!-- Create directory structures -->
<mkdir dir="${build}"/>
<mkdir dir="${lib}"/>
<mkdir dir="${dist}/lib"/>
<mkdir dir="${reports}"/>
<mkdir dir="${reports}/raw/"/>
<mkdir dir="${reports}/html/"/>
<mkdir dir="${tmp}"/>
</target>
<target name="all" depends="clean, test">
</target>
I give up and hope that someone can shine a light on my problem.
Thanks a lot!
You haven't got any Ant target which builds the test classes. You could do this as part of the compile target if you wanted:
<target name="compile" depends="init" description="compile the source code " >
<javac srcdir="${src}" destdir="${build}">
<classpath>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
</javac>
<javac srcdir="${tests}" destdir="${build}">
<classpath>
<pathelement path="${build}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
</javac>
</target>

Categories