Reputation: 309
I am writing a build file for its basic run, clean and compile properties. Here is what I have:
<?xml version="1.0" encoding="ISO-8859-1"?>
<project default="compile">
<description>
Compile and run the Java files for Lab7
</description>
<target name="prob1" depends='compile'>
<java classname='prob1'>
<classpath path='./'/>
<arg value='Gertrude'/>
<arg value='Justin'/>
</java>
</target>
<target name="prob2" depends='compile'>
<java classname='prob2'>
<classpath path='./'/>
<arg value='28'/>
</java>
</target>
<target name="prob3" depends='compile'>
<java classname='prob3'>
<classpath path='./'/>
<arg value='2000'/>
</java>
</target>
<target name="prob4" depends='compile'>
<java classname='prob4'>
<classpath path='./'/>
<arg value='2'/>
</java>
</target>
<target name="compile">
<javac srcdir='./' includeantruntime="false"/>
</target>
<target name="clean">
<delete>
<fileset dir="./">
<include name='*.class'/>
</fileset>
</delete>
</target>
</project>
I am trying to run each prob with different arguments one at a time. Like in prob1 i want to run it with the first name then again with the second name, how do I do this?
Upvotes: 4
Views: 1923
Reputation: 78021
As explained by @Moataz and @jheddings, the ANT macrodef is the best way to abstract these kinds of repetitive and parameterized actions.
The following working example also demonstrates some further refinements to your build, such as using properties to abstract the location of your projects files and the use of ANT paths to control runtime classpaths.
<project default="compile">
<description>
Example build file. Demonstrates the following
- Properties
- Build paths
- Running java programs using a macrodef
</description>
<property name="src.dir" location="src/main/java"/>
<property name="build.dir" location="build"/>
<property name="classes.dir" location="build/classes"/>
<path id="runtime.path">
<pathelement location="${classes.dir}"/>
</path>
<macrodef name="call-prog">
<attribute name="classname"/>
<attribute name="arg1"/>
<attribute name="arg2" default=""/>
<sequential>
<java classname='@{classname}' classpathref="runtime.path">
<arg value='@{arg1}'/>
<arg value='@{arg2}'/>
</java>
</sequential>
</macrodef>
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac destdir="${classes.dir}" srcdir='${src.dir}' includeantruntime="false"/>
</target>
<target name="clean">
<delete dir="${build.dir}"/>
</target>
<target name="prob1" depends='compile'>
<call-prog classname="org.demo.App" arg1="Justin" arg2="Gertrude"/>
</target>
<target name="prob2" depends='compile'>
<call-prog classname="org.demo.App" arg1="28"/>
</target>
..
..
</project>
Finally, when you've built up a store of common macodefs that you use in all your builds you can consider packaging them as an ANTlib. Best way to share build logic in ANT in my opinion. For this simple example it would be overkill.
Upvotes: 1
Reputation: 27573
You can do this using antcall
or macrodef
like so:
<target name="run-prob" depends="compile">
<fail unless="prob-class" />
<fail unless="prob-args" />
<java classname="${prob-class}">
<classpath path="./"/>
<arg line="${prob-args}"/>
</java>
</target>
<target name="prob1" depends="compile">
<antcall target="run-prob">
<param name="prob-class">prob1</param>
<param name="prob-args">justin gertrude</param>
</antcall>
</target>
<target name="prob2" depends="compile">
<prob class="prob2">
<arg value='28'/>
</prob>
</target>
<macrodef name="prob">
<attribute name="class" />
<element name="args" implicit="true" />
<sequential>
<java classname="@{class}">
<classpath path="./"/>
<args />
</java>
</sequential>
</macrodef>
The advantage of using antcall
is that you could execute calls from the command line, like so:
ant -Dprob-class=prob3 -Dprob-args=2000 run-prob
The advantage of using macrodef
is that is looks a bit cleaner and more obvious in the ant file. Of course, you could also mix the two methods and call the macro from your antcall
target or vice-versa.
Upvotes: -1
Reputation: 2519
Yes something like that is possible using antlib, which offers a wide range of functionalities like for loops, if conditions and macros. You can define a macro like
<macrodef name="call-cc">
<attribute name="target"/>
<attribute name="param1">
<attribute name="param2">
<element name="yourtask">
<java classname='$name'>
<classpath path='./'/>
<arg value='@{param1}'/>
<arg value='@{param2}'/>
</java>
</element>
</macrodef>
and then you can call it like this
<call-cc target="unittests" param1="bla" param2="blabla"/>
You can read about antlib in the manual
Upvotes: 2