How to execute Ant build in command line - ant

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

Related

How can I depend on a parent target from a nested ant project?

Given a build.xml file:
<project name="main" default="build">
<target name="main.init"/>
<extension-point name="init.tasks" depends="main.init"/>
<target name="init" depends="init.tasks"/>
<extension-point name="build.tasks" depends="init"/>
<target name="build" depends="build.tasks"/>
<include file="subsystem1.xml"/>
<include file="subsystem2.xml"/>
</project>
And a subsystemX.xml with something like:
<project name="subsystemX">
<task name="init" extensionOf="init.tasks"/>
<task name="build" depends="init" extensionOf="build.tasks"/>
</project>
I can now say ant build and all subsystems will go through init and build as expected.
However I would also like to be able to say ant subsystem.build and build only that subsystem. The problem is that each subsystem's build depends on all other subsystems' init. In this case however only the subsystem.init will be executed, as ant just looks at subsystem.build's dependencies.
Ideally I would like to add the main init as a dependency to each subsystem's build task, but include blindly prepends "subsystem." to every task name and depends entry so that I don't seem to be able to reference anything outside.
How can I make subsystem.build depend on the main init task?
I'm using a workaround:
In build.xml, I add additional targets for each included file:
<target name="subsystem1.global.init" depends="main.init"/>
<target name="subsystem1.all.init" depends="init"/>
<include file="subsystem1.xml" as="subsystem1"/>
<target name="subststem2.global.init" depends="main.init"/>
<target name="subsystem2.all.init" depends="init"/>
<include file="subsystem2.xml" as="subsystem2"/>
Then in subsystemX.xml, I can depend on "global.init" and "all.init", e.g.
<project name="subsystemX">
<task name="init" depends="global.init" extensionOf="init.tasks" />
<task name="build" depends="init, all.init" extensionOf="build.tasks"/>
</project>
As you can see this does not scale well and I'm still hoping to find a better solution.

if else condition in ant task produces error

I have a scenario where i need to move a directory from one location to another. If the same directory exists in the destination folder i need to rename the directory name as oldname_1.
So i wrote a snippet as follows:
<target name="Move">
<IF>
<available file="${output.dir}" type="dir" />
<then>
<echo message="Directory exists" />
<rename src="${output.dir}" dest="${output.dir}_1"/>
<property name="newdirectory" value="${dest}"/>
</then>
<ELSE>
<echo message="Directory does not exist" />
</ELSE>
</IF>
<move file="${newdirectory}" todir="C:\reports" />
</target>
The error i am getting is :
Problem: failed to create task
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any / declarations have taken place.
As Ian Roberts has already mentioned, you need the Ant-Contrib jar, and then setup the <taskdef/> to point to this jar. I highly recommend putting it inside your project and checking it into your version control system. This way, when someone checks out your project, they already have the Ant-Contib.jar installed.
My standard is to put all optional jars required for the build (not jars required for compiling) in the directory ${basedir}/antlib, then put each optional jar in its own directory, so I would put ant-contrib-1.0b3.jar into ${basedir}/antlib/antcontrib.
Then I define the task this way:
<property name="antlib.dir" value="${basedir}/antlib"/>
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<fileset dir="${antlib.dir}/antcontrib"/>
</classpath>
</taskdef>
This way, if you update the jar file to a new version of the Ant-Contrib jar, you simply plug it into the directory. You don't have to update the build.xml.
Also note that I use net/sf/antcontrib/antlib.xml and not net/sf/antcontrib/antcontrib.properties. The XML file is what you should use. The directions for this are on the tasks page and differ from the ones on the main page under the installation directions. The reason is that the XML file has the correct definition for the <for> task, and the properties file does not.
However, there is another way to do if and unless in Ant 1.9.1 without the need for optional jar files. These are the new If and Unless entity attributes.
These can be placed in all tasks, or sub-entities, and can usually replace the Ant-Contrib if/else stuff:
<target name="move">
<available file="${output.dir}" type="dir"
property="output.dir.exists"/>
<echo message"Directory exists"
if:true="output.dir.exists"/>
<move file="${output.dir}" tofile="${output.dir}_1"
if:true="output.dir.exists"/>
<property name="newdirectory" value="${dest}"
if:true="output.dir.exists"/>
<echo message="Directory does not exists"
unless:true="output.dir.exists"/>
<move file="${newdirectory}" todir="C:\reports" />
</target>
Not so clean as your example. However, I would instead use the if= and unless= parameters on target names:
<target name="move.test">
<available file="${output.dir}" type="dir"
property="output.dir.exists"/>
</target>
<target name="move"
depends="move.test, move.exists, move.does.not exists">
<move file="${newdirectory}" todir="C:\reports" />
</target>
<target name="move.exists"
if="output.dir.exists">
<echo message="Directory exists" />
<move file="${output.dir}" tofile="${output.dir}_1"/>
<property name="newdirectory" value="${dest}"/>
</move.exists/>
<target name="move.does.not.exists"
unless="output.dir.exists"/>
<echo message="Directory does not exist" />
</target>
If you didn't echo everything, the structure would be a bit cleaner:
<target name="move.test">
<available file="${output.dir}" type="dir"
property="output.dir.exists"/>
</target>
<target name="move"
depends="move.test, backup">
<move file="${newdirectory}" todir="C:\reports" />
</target>
<target name="backup"
if="output.dir.exists">
<move file="${output.dir}" tofile="${output.dir}_1"/>
<property name="newdirectory" value="${dest}"/>
</move.exists/>
The if/else construct is not a native part of Ant out of the box, it is provided by the ant-contrib project, and you need to download a JAR and add the relevant <taskdef> to your build file. For example, if you download ant-contrib-1.0b3.jar and put it in a directory named build in the same directory as your build.xml, then you can say
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="build/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>

Ant build script not seeing refid

I have a build.xml file that includes a common.xml file that defines some refid values. However, my task cannot see the refid value. I have not been able to find a solution on the web and am looking for some help.
I call the genbeans target in the build.xml file. It fails on the xmlbean taskdef with the message Reference my_classpath_jars not found.
build.xml
----------------------------
[includes common.xml]
**my_classpath_jars fails to be seen at this point - defined in common.xml**
<taskdef name="xmlbean" classname="org.apache.xmlbeans.impl.tool.XMLBean">
<classpath refid="my_classpath_jars"/>
</taskdef>
<!-- Generate the XMLBeans java code from our source XSD file(s) -->
<target name="genbeans" description="Generate XML Bean files" depends="build_my_jar_cpath">
<mkdir dir="${lib}"/>
<xmlbean destfile="${lib}/${appname}Beans.jar" failonerror="true">
<classpath refid="my_classpath_jars"/>
<fileset dir="src/XSD Files" includes="*.xsd, *.wsdl"/>
</xmlbean>
</target>
common.xml
-----------------------------
<target name="build_my_jar_cpath">
<path id="my_classpath_jars">
<fileset dir="${jardir}" includes="**/*.jar" />
</path>
<pathconvert pathsep="${path.separator}" property="myjar.clpath" refid="my_classpath_jars"/>
</target>
When in doubt, use the ant -d switch when calling your target. You'll see a ton of output. Save it to a file and parse through it.
Do that, and the first thing you'll notice in the output is that it's defining your taskdefbefore you have defined your my_classpath_jars. That my_classpath_jars refid is only set when you call that greenbeans target. Your <taskdef> is executed before any of your targets are called.
Either take the definition of my_classpath_jars out of the target greenbeans, or put your <taskdef> in there.

How to compile a .drl file through an ant build script

I am new to Drools. I want to know if it is possible to compile a .drl file using some kind of a command that can be entered in the windows command line (shell/cmd). I looked through the binaries that come with the drools distribution but I am unable to figure out a way to compile a .drl file.
The reason I am interested in such a command is that I want to write an ant build file which will compile my java classes and rules and create a jar. This jar should be self sufficient, i.e running the jar from the command line should run the main program, which passes facts in the session causing the rules that operate on these facts to automatically be executed.
The DroolsCompilerAntTask used to be the way to do this. It would take all your various rule files and compile them into a serialized file. It appears to have some bugs in 5.3 though which I am currently trying to work out. In the meantime, here is an illustrative build file that can be used for creating an executable JAR based on Drools. The build will fail if the rules cannot be compiled.
<project name="DroolsProto" default="dist" basedir=".">
<property name="build.src" location="src"/>
<property name="build.target" location="target"/>
<property name="build.dist" location="dist"/>
<property name="build.artifact" value="droolsproto"/>
<property name="one-jar.dist.dir" value="~/Work/Data/Misc/OneJar"/>
<property name="one-jar.version" value="0.97"/>
<property name="one-jar.ant.jar" value="${one-jar.dist.dir}/one-jar-ant-task-${one-jar.version}.jar"/>
<path id="build.lib.path">
<fileset dir="${build.src}/lib">
<include name="**/*.jar"/>
</fileset>
</path>
<taskdef name="one-jar" classname="com.simontuffs.onejar.ant.OneJarTask"
classpath="${one-jar.ant.jar}" onerror="report"/>
<taskdef name="droolscompiler" classname="org.drools.contrib.DroolsCompilerAntTask">
<classpath refid="build.lib.path"/>
</taskdef>
<target name="clean">
<delete dir="${build.target}"/>
<delete dir="${build.dist}"/>
</target>
<target name="init">
<tstamp/>
<mkdir dir="${build.target}"/>
<mkdir dir="${build.dist}"/>
</target>
<target name="compile" depends="init">
<mkdir dir="${build.target}/classes"/>
<javac srcdir="${build.src}/main/java" destdir="${build.target}/classes">
<classpath refid="build.lib.path"/>
<include name="**/*.java"/>
<exclude name="**/*Test.java"/>
</javac>
</target>
<target name="verify-rules">
<droolscompiler srcDir="${build.src}/main/resources" toFile="${build.target}/classes/foo.foo">
<classpath refid="build.lib.path"/>
</droolscompiler>
</target>
<target name="verify-resources" depends="verify-rules"/>
<target name="bundle-resources" depends="verify-resources">
<copy todir="${build.target}/classes">
<fileset dir="${build.src}/main/resources"/>
</copy>
</target>
<target name="dist" depends="compile, bundle-resources">
<one-jar destfile="${build.dist}/${build.artifact}.jar">
<manifest>
<attribute name="One-Jar-Main-Class" value="org.drools.examples.HelloWorldExample"/>
</manifest>
<main>
<fileset dir="${build.target}/classes"/>
</main>
<lib>
<fileset dir="${build.src}/lib">
<include name="**/*.jar"/>
</fileset>
</lib>
</one-jar>
</target>
</project>
Note that the build uses One-Jar in order to create the self-contained executable, you may wish to substitute this with your 'Super Jar™' tool of choice. There is also a DroolsVerifierAntTask which allegedly can check logical errors in your rules (as opposed to syntactical ones), but I have no hands on experience with it.
You can use something like this:
private static void compile(final String srcFile, final String destFile) throws IOException {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
URL src = FormChecker.class.getResource(srcFile);
Resource r = ResourceFactory.newInputStreamResource(src.openStream());
kbuilder.add(r, ResourceType.DRL);
if (kbuilder.hasErrors()) {
throw new IllegalStateException("Can not initialize Drools: " + kbuilder.getErrors().toString());
}
Collection<KnowledgePackage> kpackages = kbuilder.getKnowledgePackages();
File dest = new File(destFile);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(dest));
out.writeObject(kpackages);
out.close();
}
There's a drools-ant jar in the droolsjbpm-tools zip.

Making jUnit output info and compile to /build folder

I have the following Ant buildfile:
<?xml version="1.0"?>
<!-- the value of the default attr must be one of the targets. -->
<project name="Money" default="build-source" basedir=".">
<description>The Money project build file.</description>
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="junit" location="lib/junit-4.9b3.jar"/>
<path id="_classpath">
<pathelement path="${junit}"/>
<pathelement path="${build}"/>
</path>
<target name="prepare">
<mkdir dir="${build}"/>
</target>
<target name="build-source" depends="prepare"
description="compile the source ">
<javac srcdir="${src}" destdir="${build}">
<classpath refid="_classpath"/>
</javac>
</target>
<target name="run" depends="build-source">
<junit printsummary="on" showoutput="on">
<test name="money.MoneyTest"/>
<classpath refid="_classpath"/>
</junit>
</target>
</project>
It's pretty basic - I'm just trying to get this thing to run properly. What I don't get is: 1) Why does it output the compiled files to a /build/money directory? I want the output directory to be just /build, given this directory structure for my files:
build/
build.xml
lib/
src/
test/
2) When there are tests that don't pass, it says "Test money.MoneyTest FAILED". I'd like it to output info about the failure, expected / actual values, line number, etc.
I can't figure this out by staring at the buildfile above. Any advice?
It outputs the compiled files under build, creating a directory structure that corresponds to the layout of your packages.
Since you put your classes in the money package, the output will be under build/money. If you put your classes under a org.example.foo package, your output would be in the build/org/example/foo directory.
To have your .class files in build, you would have to use the default package.
Edit
I assume your source files have a package money; declaration, as in:
package money;
public class MoneyTest {
...
}
If you add a <formatter> element, detailed reports about test failures will be written to an output file (by default, named TEST-name). See also the Ant Junit Task Documentation.
<junit printsummary="withOutAndErr" showoutput="on">
<formatter type="plain"/>
<test name="money.MoneyTest"/>
<classpath refid="_classpath"/>
</junit>
I have not found a way to directly print the failed tests reports to standard output.

Resources