Use Ant for running program with command line arguments - java

My program getting command line arguments. How can I pass it when I use Ant?

Extending Richard Cook's answer.
Here's the ant task to run any program (including, but not limited to Java programs):
<target name="run">
<exec executable="name-of-executable">
<arg value="${arg0}"/>
<arg value="${arg1}"/>
</exec>
</target>
Here's the task to run a Java program from a .jar file:
<target name="run-java">
<java jar="path for jar">
<arg value="${arg0}"/>
<arg value="${arg1}"/>
</java>
</target>
You can invoke either from the command line like this:
ant -Darg0=Hello -Darg1=World run
Make sure to use the -Darg syntax; if you ran this:
ant run arg0 arg1
then ant would try to run targets arg0 and arg1.

If you do not want to handle separate properties for each possible argument, I suggest you'd use:
<arg line="${args}"/>
You can check if the property is not set using a specific target with an unless attribute and inside do:
<input message="Type the desired command line arguments:" addProperty="args"/>
Putting it all together gives:
<target name="run" depends="compile, input-runargs" description="run the project">
<!-- You can use exec here, depending on your needs -->
<java classname="Main">
<arg line="${args}"/>
</java>
</target>
<target name="input-runargs" unless="args" description="prompts for command line arguments if necessary">
<input addProperty="args" message="Type the desired command line arguments:"/>
</target>
You can use it as follows:
ant
ant run
ant run -Dargs='--help'
The first two commands will prompt for the command-line arguments, whereas the latter won't.

The only effective mechanism for passing parameters into a build is to use Java properties:
ant -Done=1 -Dtwo=2
The following example demonstrates how you can check and ensure the expected parameters have been passed into the script
<project name="check" default="build">
<condition property="params.set">
<and>
<isset property="one"/>
<isset property="two"/>
</and>
</condition>
<target name="check">
<fail unless="params.set">
Must specify the parameters: one, two
</fail>
</target>
<target name="build" depends="check">
<echo>
one = ${one}
two = ${two}
</echo>
</target>
</project>

Can you be a bit more specific about what you're trying to do and how you're trying to do it?
If you're attempting to invoke the program using the <exec> task you might do the following:
<exec executable="name-of-executable">
<arg value="arg0"/>
<arg value="arg1"/>
</exec>

What I did in the end is make a batch file to extract the CLASSPATH from the ant file, then run java directly using this:
In my build.xml:
<target name="printclasspath">
<pathconvert property="classpathProp" refid="project.class.path"/>
<echo>${classpathProp}</echo>
</target>
In another script called 'run.sh':
export CLASSPATH=$(ant -q printclasspath | grep echo | cut -d \ -f 7):build
java "$#"
It's no longer cross-platform, but at least it's relatively easy to use, and one could provide a .bat file that does the same as the run.sh. It's a very short batch script. It's not like migrating the entire build to platform-specific batch files.
I think it's a shame there's not some option in ant whereby you could do something like:
ant -- arg1 arg2 arg3
mpirun uses this type of syntax; ssh also can use this syntax I think.

Related

Setting sys properties in ant taskdef

i have a taskdef pointing to a class
<taskdef name="configjar" classname="com.bea.alsb.tools.configjar.ant.ConfigJarTask" classpathref="configjar.path">
</taskdef>
Inside this i want to pass java system property. Like how we do in the java task
<java >
<sysproperty key="" value""/>
</java>
The problem is the jar is some library which I can't modify .I can't use a command to set in a build environment we have.
I know i can do this by setting ANT_OPTS,but can i do this from build.xml.How can i make this happen
Not sure it's exact way or not. But found a work around for this
<java classname="org.apache.tools.ant.launch.Launcher" fork="true" failonerror="true">
<sysproperty key="weblogic.home" value="${weblogic.home}"/>
<sysproperty key="osb.home" value="${osb.home}"/>
<arg value="test"/>
</java>
<target name="test">
<configjar debug="${task.debug}"
failonerror="${task.failonerror}"
errorProperty="${task.errorproperty}"
settingsFile="${settingsFile}" >
</configjar>
</target>
I have invoked ant using java command and set the two system properties as shown above.

Passing command line arguments to Java via ant build script

On running the following command:
ant targetname -Dk1=v1 -Dk2=v2
I want the command line parameters passed down to java, like java whatever -Dk1=v1 -Dk2=v2.
I need to access these parameters from Java code with System.getProperty or System.getenv.
What do I need to write in my ant build script to make this happen?
Or should I take some other approach altogether?
I'm not sure exactly how you want to pass these values, but there are several mechanisms:
Use <sysproperty> to pass system properties you need to set:
Use <arg> to pass command line arguments to your Java class
Use <jvmarg> to pass arguments to your Java command itself
If you fork your Java task, you can also set environment variables too. These are ignored if you don't fork the Java task
This:
$ foo=bar; java -Xlingc com.example.foo.bar -Dsys1=fu -Dsys2=barfu -arg1 -arg2 bar
Becomes:
<java classname="com.example.foo.bar"
fork="true">
<env key="foo" value="bar"/>
<sysproperty key="sys1" value="fu"/>
<sysproperty key="sys2" value="barfu"/>
<jvmarg value="-Xlingc"/>
<arg value="-arg1"/>
<arg value="-arg2"/>
<arg value="bar"/>
</java>
Hope that example helps
Not good in Ant Script but I do something like below :
<target name="execute">
<echo> Running MyClass ......... </echo>
<java classname="pkg.MyClass" classpathref="libs">
<arg value="val1" /> <!-- command line args -->
<arg value="val2" />
<arg value="val3" />
<env key="k1" value="v1" /> <!-- set environmental value -->
</java>
</target>
If you are using Eclipse, you will get suggestions in popup under java tag. I got few more like : <sysproperty/>, <syspropertyset></syspropertyset>, <jvmarg/>
Use the nested <arg> elements in your <java> task:
<java classname="test.Main">
<arg value="${k1}"/>
<arg value="${k2}"/>
<classpath>
<pathelement location="dist/test.jar"/>
<pathelement path="${java.class.path}"/>
</classpath>
</java>

Ant target to run Windows BAT including changing directory

I have a Windows BAT file that looks like this:
Z:
tool.exe c:\mypath\to\input c:\mypath\to\output \flag1 flag2
That is, tool.exe resides on a mapped network drive. The tool requires that the EXE is run from its own directory (Z: in this case).
The BAT works fine when run via double-click or in a CMD window.
I'd like to automate it through Ant. My attempt is here:
<target name="go">
<exec executable="cmd">
<arg value="/c"/>
<arg value="runtool.bat"/>
</exec>
</target>
It doesn't work. From this link and other research, I understand the following:
"Z:" is likely the equivalent of "cd Z:\"
there is no "cd.exe"... "cd" is interpreted by the Windows CMD shell, and not available via "cmd.exe"
That said, how to achieve the goal in Ant? in Java?
I'm open to writing my own Ant task, doing further network configuration of the directories, etc. (At the risk of making the question too broad, we are using Jenkins and open to ideas there as well.)
You have to specify the dir attribute on the exectask:
<exec executable="tool.exe" dir="z:">
<arg value="c:\mypath\to\input"/>
<arg value="c:\mypath\to\output"/>
<arg value="flag1"/>
<arg value="flag2"/>
</exec>
This worked for me:
<target name="go">
<property name="batFileDir" location="${basedir}/resources" />
<exec executable="cmd" dir="." spawn="false">
<arg line="/C start ${batFileDir}/runTool.bat"/>
</exec>
</target>
where the runTool.bat is as described in the question, and located in ~/resources.

Ant, NetBeans Platform project - how to pass command line arguments and access via System.getProperties?

All,
I have a NetBeans Platform project (not just a project I wrote in NetBeans, but one using the rich client framework provided by NetBeans). I can run the project via an ant run command. Now, I want to pass in an argument that will work its way through ant to be accessible via the System.getProperty method.
I understand that I need to use a <sysproperty> node to actually inject the key/value pair into the runtime environment, but for the life of me I cannot figure out how to get this to work with the convoluted build tree that NetBeans creates for you (build.xml depends on build-impl.xml, which in turn depends on ${harness.dir}/suite.xml, which in turn depends on ${harness.dir}/run.xml)
The simplest example I've found is
<target name="run" depends="compile">
<java classname="prop"
fork="true">
<sysproperty key="test.property"
value="blue"
/>
</java>
</target>
but the problem is that none of my xml files have an easily accessible <java> node like that. I think I've managed to trace the execution flow to where something is actually invoked (in ${harness.dir}/run.xml)
<target name="run" depends="-prepare-as-app,-prepare-as-platform">
<touch file="${cluster}/.lastModified"/> <!-- #138427 -->
<property name="run.args" value=""/>
<property name="run.args.ide" value=""/>
<property name="run.args.extra" value=""/>
<condition property="run.args.mac" value="-J-Xdock:name=${app.name}" else="">
<os family="mac"/>
</condition>
<exec osfamily="windows" executable="${run.exe}" failonerror="no" resultproperty="result.prop">
<arg value="--jdkhome"/>
<arg file="${run.jdkhome}"/>
<arg line="${run.args.common}"/>
<arg line="${run.args.prepared}"/>
<arg line="${run.args}"/>
<arg line="${run.args.ide}"/>
<arg line="${run.args.extra}"/>
</exec>
<exec osfamily="unix" dir="." executable="sh"
failonerror="no" resultproperty="result.prop">
<arg value="${run.sh}"/>
<arg value="--jdkhome"/>
<arg file="${run.jdkhome}"/>
<arg line="${run.args.common}"/>
<arg line="${run.args.prepared}"/>
<arg line="${run.args}"/>
<arg line="${run.args.ide}"/>
<arg line="${run.args.extra}"/>
<arg line="${run.args.mac}"/>
</exec>
<fail>
The application is already running within the test user directory.
You must shut it down before trying to run it again.
<condition>
<and>
<isset property="result.prop" />
<or>
<!-- unknown option exit code as returned from IDE by org.netbeans.api.sendopts.CommandLine -->
<equals arg1="${result.prop}" arg2="50346" />
<!-- unknown option exit code as returned from platform app by org.netbeans.CLIHandler -->
<equals arg1="${result.prop}" arg2="2" />
</or>
</and>
</condition>
</fail>
</target>
As you can see, there is no <java> node underneath which I can put my custom sysproperty. Furthermore, it seems like a very wrong thing to do to have to muck around with harness xml files to inject a property that only affects one of my projects, not all of them. So what's the correct way to ensure that a command line property I pass to ant run ends up within a NetBeans Platform project?
There is a folder etc in the distribution of your RCP app and in that folder is file yourapp.conf i think there is an answer you seek. For example from one of mine NB RCP app:
# ${HOME} will be replaced by user home directory according to platform
default_userdir="${HOME}/.${APPNAME}/dev"
default_mac_userdir="${HOME}/Library/Application Support/${APPNAME}/dev"
# options used by the launcher by default, can be overridden by explicit
# command line switches
default_options="--laf Metal --branding xmled -J-Xms24m -J-Xmx64m"
# for development purposes you may wish to append: -J-Dnetbeans.logger.console=true -J-ea
# default location of JDK/JRE, can be overridden by using --jdkhome <dir> switch
#jdkhome="/path/to/jdk"
# clusters' paths separated by path.separator (semicolon on Windows, colon on Unices)
#extra_clusters=

Ant macrodef compilation task

I have a compiler (and language) I am building that is normally invoked thus:
java -jar nc.jar \
-p some/referenced/package.nc \
-p framework.nc \
source1.ns source2.ns sourceN.ns \
-o output/package.nc
I'd like to include a task in my ANT build file that invokes the compiler to compile the standard library and all test cases, but specifying each separate compiler invocation as a <java> task is painful:
<target name="framework" depends="compiler" description="Build the n framework">
<!-- More compile steps -->
<java jar="nc.jar" fork="true">
<arg value="-p"/>
<arg path="../nframework/build/n.core.nc"/>
<arg path="../nframework/n/debug/DebugPrint.ns"/>
<arg path="../nframework/n/debug/Trace.ns"/>
<arg value="-o"/>
<arg path="../nframework/build/n.debug.nc"/>
</java>
<!-- More compile steps -->
</target>
I would like to create an ANT task of some sort that can simplify this into something like:
<target name="framework" depends="compiler" description="Build the n framework">
<!-- More compile steps -->
<nc output="../nframework/build/n.debug.nc">
<link-package path="../nframework/build/n.core.nc"/>
<src>
<fileset dir="../nframework/n/debug" includes="**/*.ns"/>
</src>
</nc>
<!-- More compile steps -->
</target>
To this end, I tried macrodef:
<macrodef name="nc">
<attribute name="output"/>
<element name="link-package"/>
<element name="src"/>
<sequential>
<java jar="nc.jar" fork="true">
<arg value="-p"/>
<!-- This doesn't do what I want -->
<link-package/>
<!-- Neither does this -->
<src/>
<arg value="-o"/>
<arg path="#{output}"/>
</java>
</sequential>
</macrodef>
I've tried several variations on the above, but each errors out with something like:
/home/jwarner/code/nlang/nc/build.xml:55: java doesn't support nested "fileset" element.
Is there a way to do this without extending ANT itself? Alternatively, would it be fairly easy to add an ant task to my compiler? I'm not terribly picky about the syntax of the final <nc> task.
I have had a similar problem in the past where the out-of-the-box Ant tasks didn't quite do what I wanted them to do. I found that it was very easy to write my own Ant task.
The documentation is concise but does a good job of explaining what you need to do.
http://ant.apache.org/manual/develop.html#writingowntask

Categories

Resources