Trouble Executing Bash.exe From an Ant Buildfile in Eclipse - java

I've created an Ant buildfile and an associated Ant builder in my Eclipse project. The builder is executing correctly but I can't seem to pass the correct information to bash. I'm running cygwin on an XP Professional SP3 machine. I know the command works and have verified it from a cygwin terminal. I created a custom builder earlier with this command so I also know that it works from Eclipse.
Here is my build xml:
<?xml version="1.0" encoding="UTF-8"?>
<project name="BlazeLibrary.makejar" default="makejar" basedir=".">
<property name="bash" location="e:\cygwin\bin\bash.exe" />
<property name="workingdir" location="e:\cygwin\bin" />
<property name="cmdline" value="--login -c \"cd /cygdrive/c/dev/projects/droid/NDKTestApp && /cygdrive/c/dev/tools/droid/android-ndk-r4b/ndk-build"" />
<target name="nativeBuild" description="Build the native binaries using the Android NDK">
<exec dir="${workingdir}" executable="${bash}">
<arg value="${cmdline}" />
</exec>
</target>
</project>
The task runs fine but the output I indicates that the command line parameters are incorrect. Even though they are listed exactly as they should be (and verified by running from cmd prompt as well as the custom builder mentioned previously).
Here is the relevant part of the error message (the rest just vomits the help and is of no relevancy for this question):
nativeBuild:
[exec] /usr/bin/bash: --login -c "cd /cygdrive/c/dev/projects/droid/NDKTestApp && /cygdrive/c/dev/tools/droid/android-ndk-r4b/ndk-build": invalid option
[exec] Usage: /usr/bin/bash [GNU long option] [option] ... blah blah blah
I'll be the first to admit that I am an Ant noob so I'm probably missing something very obvious. I've searched but nothing really jumps out at me and the task seems to run correctly, just something funky about the command line. Thanks for any help in advance.

The immediate problem is that the ${cmdline} property is being passed to bash as a single argument - hence the very long 'invalid option'.
You could pass the command as an arg line instead:
<exec dir="${workingdir}" executable="${bash}">
<arg line="${cmdline}" />
</exec>
Or perhaps break it up into separate values. Note that you don't need the quots around the -c arg in that case:
<property name="cmdline" value="cd /cygdrive/ ..etc.. ndk-build" />
<exec dir="${workingdir}" executable="${bash}">
<arg value="--login" />
<arg value="-c" />
<arg value="${cmdline}" />
</exec>
More here.

You can still use the format in your initial post, just change your quotes around a bit, like this:
<!-- These properties hold the location of the android-ndk, for us to build our antive libs -->
<property name="bash" location="c:\cygwin\bin\bash.exe" />
<property name="workingdir" location="c:\cygwin\bin" />
<property name="cmdline" value="--login -c 'cd /path/to/project/files;/path/to/ndk_build/ndk-build;exit'" />
<target name="NDKBUILD" description="Build the native binaries using the Android NDK">
<exec dir="${workingdir}" executable="${bash}">
<arg line="${cmdline}" />
</exec>
</target>
Note the usage of " " to denote the XML string, but ' ' to denote command lines passed to cygwin/bash.
Also, when using this script in my android builder (heavily customised ant script with extensive source preprocessing) I ran into issues where the ant build was "Already In Progress".
To this end, I added an exit command to the end of the bash script, so the cygin bash process is always closed after being called.

Related

Executing a unix command in cygwin launched from ant in eclipse

I have an ant build for a java project that I would like to trigger from within eclipse, that in turn launches a cygwin window that executes a deployment script. Is it possible to implement this without calling a new command window from ant?
Use bash.exe as the executable (replacing or parameterizing cygwin directory as needed):
<project default="default">
<target name="default">
<exec executable="c:/cygwin/bin/bash.exe">
<arg value="-c"/>
<arg value="ls c:/"/>
</exec>
</target>
</project>

failure when trying to invoke an ANT target for several times

I am using ANT to precompile handblebars in build time. I follow the way here http://blog.selvakn.in/2012/05/precompiling-handlerbars-tempates-with.html. And for only one target, it works very well. But then I try to invoke the target twice like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><project basedir="." default="echoIt" name="precompile">
<property name="charset" value="utf-8"/>
<target name="echoIt">
</target>
<target name="precompile-templates0" depends="echoIt">
<property name="outputJS" value="../../jsp/jsp_1/js/templates0.js"/>
<property name="templatesPath" value="../../jsp/jsp_1/js/tmpl"/>
<java dir="${basedir}" failonerror="true" fork="true" jar="../../lib/js.jar">
<arg value="../../otherFiles/lib/rhino-handlebars-compiler.js"/>
<arg value="--handlebars"/>
<arg value="../../otherFiles/third-party/handlebars-v1.3.0.js"/>
<arg value="--templates"/>
<arg value="${templatesPath}"/>
<arg value="--output"/>
<arg value="${outputJS}"/>
</java>
<echo>Template Precompiled to web/js/compiled-templates.js</echo>
<echo> is now ready to compress....</echo>
</target>
<target name="precompile-templates1" depends="echoIt">
<property name="outputJS" value="../../jsp/jsp_2/js/templates1.js"/>
<property name="templatesPath" value="../../jsp/jsp_2/js/tmpl"/>
<echo> is now precompiling the second one </echo>
<java dir="${basedir}" failonerror="true" fork="true" jar="../../lib/js.jar">
<arg value="../../otherFiles/lib/rhino-handlebars-compiler.js"/>
<arg value="--handlebars"/>
<arg value="../../otherFiles/third-party/handlebars-v1.3.0.js"/>
<arg value="--templates"/>
<arg value="${templatesPath}"/>
<arg value="--output"/>
<arg value="${outputJS}"/>
</java>
<echo>Template Precompiled to web/js/compiled-templates.js</echo>
<echo> is now ready to compress....</echo>
</target></project>
The output on the console is like this:
Buildfile: F:\AffirmedNetworks\ServerAutomation\cache\subBuildTarget\precompileTarget.xml
echoIt:
precompile-templates0:
[echo] Template Precompiled to web/js/compiled-templates.js
[echo] is now ready to compress....
echoIt:
precompile-templates1:
[echo] is now precompiling the second one
[echo] Template Precompiled to web/js/compiled-templates.js
[echo] is now ready to compress....
BUILD SUCCESSFUL
Total time: 2 seconds
As you can see, the build is successful. However when I check the outputs in the expected directory, only a ‘templates0.js’ is generated in the path:jsp/jsp_1/js/. There is nothing in the path: jsp/jsp_2/js/. However, it should have on named 'templates1.js' in this folder. This is really weird. No errors occurred and the first on is generated successfully, but the second one disappeared. Can someone give me some help on this? Thanks!
the issue is in your re-use of the <property> task!
Properties are immutable: whoever sets a property first freezes it for the rest of the build; they are most definitely not variables. i.e. once you assign a value to an identifier using <property>, it cannot be changed. See HERE
although, you set the values to outputJS and templatesPath within both targets separately, maybe assuming/expecting local scope, that is not the case in ant.
reason: In general properties are of global scope, i.e. once they have been defined they are available for any task or target invoked subsequently
exception: it is not possible to set a property in a child build process created via the ant, antcall or subant tasks and make it available to the calling build process
therefore, the values for outputJS and templatesPath, as defined in the target precompile-templates0, are retained throughout the build.
to solve your issue, you may do either of the following:
change property names, for eg to outputJS1 and templatesPath1 in the target precompile-templates1
(if you're using Ant 1.8.0 or above) use the <local> task instead of the <property> task for declaring outputJS and templatesPath. See HERE for this.
use the <var> task of ant-contrib. See ant-contrib and var task.

How can i change an Ant grep to have unix style "or" in its regular expression?

I have the following code for grepping an xml file repo, in ant :
<echo message="Now checking xml test results for errors" />
<exec executable="grep" error="/dev/null">
<arg value="-r" />
<arg value="-m" />
<arg value="1" />
<arg value="-rl" />
<arg value="errors=\"[1-9]\"" />
<arg value="${reports.dir}" />
</exec>
<fail if="junit.failed" message="FAILING - unit tests failed." />
Im trying to replace :
<arg value="errors=\"[1-9]\"" />
with something along the lines of :
<arg value="errors|failures=\"[1-9]\"" />
So that both errors AND failures will be caught. How can I encode the grep correctly in my Ant XML to reflect this ? "**grep -r -m 1 -rl errors|failures=\"[1-9]\" ../reports/**" does not do the trick ( it results in a syntax issue, breaking the standard grep parser i guess )...
This is a guess, but you could try something along the lines of:
<arg value="-e" />
<arg value="errors=\"[1-9]\"" />
<arg value="-e" />
<arg value="failures=\"[1-9]\"" />
From man grep:
-e PATTERN, --regexp=PATTERN
Use PATTERN as the pattern; useful to protect patterns beginning with -.
You could do this in a platform-independent way using an Ant filterchain instead of executing grep.
The following example filters every file under report.dir for the regex, with a head filter to short-circuit when a single match is found. The result output is loaded into a property.
<target name="test">
<loadresource property="junit.failed">
<concat>
<fileset dir="${report.dir}">
<include name="**/*"/>
</fileset>
<filterchain>
<linecontainsregexp>
<regexp pattern="failures|errors=\"\d+\""/>
</linecontainsregexp>
<headfilter lines="1"/>
</filterchain>
</concat>
</loadresource>
<fail if="junit.failed" message="FAILING - unit tests failed"/>
</target>
One thing you cannot achieve using this technique is to get the names of matching files (which grep -l gives you) rather than the matching lines. However, you are not using the file names in your example.
Note also that the regex you are using in your grep will not find errors and failures greater than 9, e.g. errors="11" will not be found. The pattern in the example above does find these.
Pipe does not work for you because it is interpreted by shell as a shell's pipe instead of the regex element. To improve the situation you should put the parameter into quotes.
grep -r -m 1 -rl "errors|failures=\"[1-9]\"" ../reports/**"

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=

Use Ant for running program with command line arguments

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.

Categories

Resources