my ant was stoped when execute "<exec excultable="c:\myExe.exe"/>",the result code is just "<message priority="error"><![CDATA[Result: 128]]></message>".I don't know what's meaning of that.
I've tried to search some info like: error code 128---no such exe file,but I havn't.
some one could help me to explain what's the meaning?
Thanks
Oh sorry.
More info:
<macrodef name="gtest-layer-macro">
<attribute name="execfile"/>
<attribute name="layerpath" default=""/>
<attribute name="outputDir" default="${basedir}/${reports}/gtest"/>
<attribute name="reportfile" default="#{outputDir}/gtest_report.xml"/>
<sequential>
<check-layer-path layerpath="#{layerpath}"/>
<if>
<and>
<length string="#{execfile}" when="gt" length="0" trim="true"/>
<available file="#{execfile}"/>
</and>
<then>
<var name="##report.dir##" unset="true"/>
<dirname property="##report.dir##" file="#{reportfile}"/>
<mkdir dir="${##report.dir##}"/>
<exec executable="#{execfile}">
<arg value="--gtest_output="xml:#{reportfile}""/>
</exec>
</then>
</if>
</sequential>
</macrodef>
When I run the <exec>, there’s "error Result:128".
The “#{execfile}” is a gtest.exe file(a exe file to test a module),it could run correctly when I double-click it,it could print the unit test result in the console;Run in the CMD with “--gtest_output="xml:#{reportfile}"” is also could print the unit test result in the console,and output a unit test report(a .xml file).And I have changed another .exe instead of the “gtest.exe”,it’s right too.
So,I don’t know where I’m wrong.
An [exec] Result:128 is a process that can't be found/doesn't exist. At least this is what I've found out from my Ant target to kill any remaining processes at the end of certain tests. I get that result when the process I want to kill isn't running. My build log output looks like this;
[shutdown.server] exec
[13:45:33][exec] ERROR: The process "firefox.exe" not found.
[13:45:34][exec] Result: 128
So if that result is from the execution of your .exe then I'd check the path to ensure the exe is available.
Related
I have a piece of code in my ant build.xml
<retry retrycount="10" retrydelay="30000">
<exec executable="${env.M2_HOME}/bin/mvn.cmd" output="#{log}" failonerror="true" resultproperty="res" timeout="#{timeoutmillis}" errorproperty="error">
...
</exec>
</retry>
<echo message="${res}"/>
I retry my cmd task if if fails once upto 10 times. But even if it were to succeed after retrying a few turns, the value returned in res is 1 even though it is a build success. I expect it to be 0 as if it was SUCCESS.
Properties in Ant are immutable (they're not variables), so even if your exec task eventually succeeds, the result property will have already been set to whatever it got from the first run.
You can get past this by creating a sequential block and using the local task inside it to control your property scope.
<retry retrycount="10">
<sequential>
<local name="do.fail" />
<input addproperty="do.fail" validargs="y,n" message="fail?" />
<fail>
<condition>
<equals arg1="${do.fail}" arg2="y" />
</condition>
</fail>
</sequential>
</retry>
Running the above example will prompt the user until "n" is provided as input (or 10 retries).
This is not a direct answer to the question I asked. But taking into consideration what CAustin and jdpjamesp said, I'm reading the content of my output log to see whether the command failed or not.
The cmd will return 1 even if it passed after some n number of failures. But the output log in case of mvn will have "BUILD SUCCESS" only if the command passes at the end. So searching for this string works for me. The log should not be appended after every time though.
So I implemented this-
<property name="pass.string" value="BUILD SUCCESS" />
<resourcecount property="pass.string.count">
<fileset id="matches" file="#{log}">
<contains text="${pass.string}" />
</fileset>
</resourcecount>
<if>
<equals arg1="${pass.string.count}" arg2="0" />
<then>
..
</then>
<else>
..
</else>
</if>
I am calling one target(targetCalled) from some other target(targetCaller), as follows:
<target depends="local.init"
description="creating application jar file of the classes dir"
name="run_check_server_client_jar_gen">
<antcall target="run_check_server_client_jar_callExec"/>
<if>
<isset property="result"/>
<then>
<echo>Result: ${result}</echo>
</then>
<else>
<echo>Propert result is not set yet !! </echo>
</else>
</if>
</target>
Now I call one exec from targetCalled as follows:
<target depends="local.init"
description="Running check for all classes in
client jar should also be present in server jar"
name="run_check_server_client_jar_callExec">
<exec executable="/bin/bash" resultproperty="${result}" failonerror="false">
<arg value="count_client_server_inner_classes.sh"/>
<arg value="gjf1common_client_classes.jar"/>
<arg value="gjf1common_classes.jar"/>
</exec>
<if>
<isset property="result"/>
<then>
<echo>Inside::Result: ${result}</echo>
</then>
<else>
<echo>Inside::Property result is not set yet !!!! </echo>
</else>
</if>
</target>
In my count_client_server_inner_classes.sh, i am exiting the status as:
exit "$result"
it is giving me ": numeric argument required"
i want that executable should return me a string, is that possible ??
I want to use this returned value in my targetCalled and targetCaller.
but when i am echoing the result property.. it is giving me 255.
Can anybody points out where i am going wrong ?
Ant isn't a scripting language. It's not a very good way to describe a build - but it's an awful scripting language. Trying to script in ant with pseudo-function calls and if/else like this is going to suck. In generally, stay away from if/else - if you find you need them you likely want to reevaluate your tool choice. Avoid antcall at all costs - it spins up a new jvm and makes for some crazy spaghetti - use depends to control the execution flow between targets.
To answer one of your question - the result property is always going to be the exit code, in the case of bash it's always goign to be an int 0-255.
The interesting part is in the bash script... post that. It's returning 255, which is a special code - means it's out of range. I suspect you're having it return a string?
You could simplify the whole mess by simply failing on error:
<target name="run-check-server-client-jar-gen" depends="local-init"
description="creating application jar file of the classes dir">
<exec executable="/bin/bash" failonerror="true">
<arg value="count_client_server_inner_classes.sh"/>
<arg value="gjf1common_client_classes.jar"/>
<arg value="gjf1common_classes.jar"/>
</exec>
</target>
If you really must give custom error status you can set the result property as you where and then you could:
<target name="run-check-server-client-jar-gen" depends="local-init"
description="creating application jar file of the classes dir">
<exec executable="/bin/bash" resultproperty="${return.code}">
<arg value="count_client_server_inner_classes.sh"/>
<arg value="gjf1common_client_classes.jar"/>
<arg value="gjf1common_classes.jar"/>
</exec>
<fail message="crazy shell script madness terminated abnormally.">
<condition>
<isfailure code="${return.code}"/>
</condition>
</fail>
</target>
I admit I didn't actually run the snippets above, you may have to massage a bit, but I'm pretty sure they'll go.
another editorial note on style: targets generally use - rather than _ or . to delimit word, where properties use .
i have an ant script as shown below:
<project name="nightly_build" default="main" basedir="checkout">
<target name="init">
<exec executable="C:/Work/Searchversion.exe"/>
<property file="initial.properties"/>
<property file="C:/Work/lastestbuild.properties"/>
<tstamp>
<format property="suffix" pattern="yyyyMMddHHmmss"/>
</tstamp>
</target>
<target name="main" depends="init">
<exec executable="C:/Program Files/True Blue Software/SnapshotCM/wco.exe">
<arg line='-h sinsscm01.sin.ds.net -S"/mobile/6.70_Extensions/6.70.102/ANT_SASE_RELEASE_${Version_Number}" /'/>
</exec>
</target>
</project>
i created the above script to replicate a command: wco -h sinsscm01.sin.ds.net -S"/mobile/6.70_Extensions/6.70.102/ANT_SASE_RELEASE_6.70.102.014" /
and 6.70.102.014 is found inside latestbuild.properties file in the form of:
Version_Number = 6.70.102.014
and this latestbuild.properties file is obtained when i execute C:/Work/Searchversion.exe
but when i execute this ant script using cruisecontrol, in my log file,
[Thread-24] INFO ScriptRunner - [exec] Cannot open snapshot 'sinsscm01.sin.ds.jdsu.net:/mobile/6.70_Extensions/6.70.102/ANT_SASE_RELEASE_${Version_Number}': No such snapshot
where ${Version_Number} should have been 6.70.102.014
How do i tackle this issue?
EDIT 1:
after trial and error and substituting with a built in property ${ant.version}, i realise that my property file could be loaded in correctly over here. can anyone point out my mistake? i dont see anything wrong though
EDIT 2:
Just additional infomation... This is actually a delegate ant script for cruisecontrol(used to perform nightly build). Here is my config.xml file for per minute build:
<cruisecontrol>
<project name="dms" buildafterfailed="true">
<listeners>
<currentbuildstatuslistener file = "logs/dms/status.txt"/>
</listeners>
<bootstrappers>
</bootstrappers>
<modificationset quietperiod="60">
<alwaysbuild/>
</modificationset>
<schedule interval="60">
<ant buildfile="nightly_build.xml" target="main"/>
</schedule>
<log dir="logs/dms">
<merge dir="checkout/dms/build/test-results" />
</log>
<publishers>
</publishers>
</project>
</cruisecontrol>
should properties file be loaded in config.xml?
Try breaking your arguments to wco.exe into separate child elements like this:
<exec executable="C:/Program Files/True Blue Software/SnapshotCM/wco.exe">
<arg value="-h" />
<arg value="sinsscm01.sin.ds.net" />
<arg value="-S" />
<arg value="/mobile/6.70_Extensions/6.70.102/ANT_SASE_RELEASE_${Version_Number}" />
<arg value="/" />
</exec>
I think ant isn't expanding ${Version_Number} because it is inside ' "..." ' in the version you posted.
As mentioned in the docs for <exec> you should avoid use of the <arg line=...> form.
You could add assertions in your init target that the required properties file exists and that the property is defined. For example:
<property name="version.file" value="C:/Work/lastestbuild.properties"/>
<available file="${version.file}" property="version.file.available"/>
<fail unless="version.file.available" message="file [${version.file}] is not available"/>
<property file="${version.file}"/>
<fail unless="version" message="property [version] is not defined"/>
<echo message="version: ${version}"/>
I think that will help you spot that the file does not exist.
I took a look at your other question about this script you're putting together. In the code which writes the version number to file, you use filename latestbuild.properties:
TextWriter latest = new StreamWriter("C:\\Work\\latestbuild.properties");
In your Ant script, you are loading a different filename lastestbuild.properties.
Unless you've fixed it since then, that will be your problem. (If you modified your external script to take the filename as a parameter, and defined the filename once as an Ant property - as in my sample above - it would help you avoid this kind of problem.)
Regarding your discovery that you need to wait for your external script before continuing in Ant, take a look at the Sleep task.
<target name="CheckState">
<exec executable="${App.path}"/>
</target>
In this task, the executable will return a value which will indicate the state of my app. How could I get the value returned in the Ant build file. I will use this value to determine some behaviour.
Use the resultproperty and failonerror attributes of the exec task, e.g.:
<target name="CheckState">
<exec executable="${App.path}"
resultproperty="App.state"
failonerror="false"/>
<echo message="App state was: ${App.state}" />
</target>
Quoting from the exec task docs Errors and return codes:
By default the return code of an exec
is ignored; when you set
failonerror="true" then any return
code signaling failure (OS specific)
causes the build to fail.
Alternatively, you can set
resultproperty to the name of a
property and have it assigned to the
result code (barring immutability, of
course).
If the attempt to start the program
fails with an OS dependent error code,
then halts the build unless
failifexecutionfails is set to false.
You can use that to run a program if
it exists, but otherwise do nothing.
What do those error codes mean? Well,
they are OS dependent. On Windows
boxes you have to look at the
documentation; error code 2 means 'no
such program', which usually means it
is not on the path. Any time you see
such an error from any Ant task, it is
usually not an Ant bug, but some
configuration problem on your machine.
Here is a generic way to check the result and display the output of the execution only if the process returns a failure code.
<property
name="my.project.tmp.exec.output"
value="${tmp.dir}/exec-output.txt"/>
<target
name="my.project.my.task">
<exec
executable="${App.path}"
output="${my.project.tmp.exec.output}"
resultproperty="my.project.my.task.result"
failonerror="false"/>
<loadfile
srcfile="${my.project.tmp.exec.output}"
property="my.project.my.task.output"
/>
<fail message="ERROR: ${my.project.my.task.output}">
<condition>
<not>
<equals arg1="${my.project.my.task.result}" arg2="0"/>
</not>
</condition>
</fail>
<delete file="${my.project.tmp.exec.output}"/>
</target>
I need to execute an ant task for each line from a given file. Any ideas appreciated.
I have a properties file that defines processes that need to be run. This is all on a single line and comma separated, not multiple lines as you have specified. This answer shows how to iterate over a file.
env.start=webserver:localhost, dataserver:localhost
then in my ant file that handles application execution I have the following
<target name="start-all" description="Start all processes specified in target-info.properties:env.start">
<foreach list="${env.start}" trim="yes" param="process.and.host" target="-start-process"/>
</target>
<target name="-start-process">
<property name="colon.separated.pattern" value="([^:]*):([^:]*)"/>
<propertyregex property="process" input="${process.and.host}" regexp="${colon.separated.pattern}" select="\1"/>
<propertyregex property="host" input="${process.and.host}" regexp="${colon.separated.pattern}" select="\2"/>
<condition property="start.target" value="start-${process}" else="-start-process-ssh">
<equals arg1="${host}" arg2="localhost" trim="yes" casesensitive="no"/>
</condition>
<antcall target="${start.target}"/>
</target>
${start.target} then is executed for the processes defined in the env.start property for example
<target name="start-webserver" description="Start the webserver on this machine">
<echo>** Starting webserver **</echo>
<run-script dir="${project.base.dir}/apache-tomcat" script="${project.base.dir}/apache-tomcat/bin/startup" spawn="yes">
<args>
<env key="CATALINA_HOME" value="${project.base.dir}/apache-tomcat"/>
<env key="CATALINA_PID" value="${project.base.dir}/apache-tomcat/logs/pid_catalina"/>
</args>
</run-script>
</target>
<target name="start-dataserver" depends="decipher_caldb_password,check-event-seed,run-prestart-sql" description="Start the dataserver on this machine">
<run-calypso process="dataserver" class="calypsox.apps.startup.StartNOGUI" failonerror="yes"
args="-class com.calypso.apps.startup.StartDataServer"/>
</target>
I can start all the processes defined in env.start by running
ant -f run.xml start-all