How to read and process stdout values in ant - exec? - java

To validate a file with an executable.
I have ant script target as:
<target name="xtest" depends="xyz" description="Additional check">
<exec executable="${xtest.exe}" failonerror="true" resultproperty="retVal">
<arg value="${inputfile.dat}" />
</exec>
<echo>Returned: ${retVal}</echo>
</target>
Output on console:
xtest:
[exec] Errors: 3
[exec] Warnings: 1
[exec] Infos: 0
[exec] Total: 4
[echo] Returned: 0
The exit code (${retVal}) of executable is 0 even if it detects error.
I want to terminate the process if Errors are more than 0.
How can I read first output line ([exec] Errors: 3) and parse the value which is 3 in above example and terminate the process?

Worked exactly with code below. Thanks!
<target name="xtest" depends="xyz" description="Additional check">
<exec executable="${xtest.exe}" failonerror="true" resultproperty="retVal" output="output.txt">
<arg value="${inputfile.dat}" />
</exec>
<echo>Returned: ${retVal}</echo>
<property file="output.txt" prefix="xtestoutput"/>
<fail>
<condition>
<not>
<equals arg1="${xtestoutput.Errors}" arg2="0" />
</not>
</condition>
</fail>
</target>

using resultproperty you can redirect output of your executable to a file.
Then, since the output matches property file format you can read that output file and use the properties in it like:
<target name="xtest" depends="xyz" description="Additional check">
<exec executable="${xtest.exe}" failonerror="true" resultproperty="retVal" output="output.txt">
<arg value="${inputfile.dat}" />
</exec>
<echo>Returned: ${retVal}</echo>
<property file="output.txt" prefix="xtestoutput"/>
<fail>
<condition>
<not>
<equals arg1="${xtestoutput.Errors}" arg2="0" />
</not>
</condition>
</fail>
</target>

Related

Conditional task execution in ANT Scripts

My requirement is pretty simple, I have an ANT task which is handling exceptions internally and not throwing any exception, instead it is throwing custom messages [these are not exceptions] to the console. A sample is shown below with the test "The workspace with the specified name does not exist".
My requirement here is, if there is any such message apart from "Build Successful", I should make sure my ANT script is failed so that it won't go further. But I am unable to do so as I don't know how do I read that custom message which was written to console.
I tried exploring on 'Record' task but I was unsuccessful as this log was written only to console and not to the file (don't know why). But even if it was written to a file I should ideally read each line of file to find out a particular text present or not.
Is there a simple way to try and read things from console which were executed before?
<target name="build">
<record name="test.txt" action="start" append="true" loglevel="verbose" />
<echo>Welcome to Apache Ant! Building the project in Cordys Middleware</echo>
<property environment="env"/>
<property name="bop.install.dir" value="${env.CORDYS_HOME}"/>
<exec executable="${bop.install.dir}/components/cws/scripts/linux/CWSPackage.sh" failonerror="true" resultproperty="output">
<env key="CLASSPATH" value="/opt/Cordys/Oracle_Jar/ojdbc6.jar"/>
<arg value="${ORG_NAME}"/>
<arg value="${WORKSPACE_NAME}"/>
<arg value="${PROJECT_NAME}"/>
</exec>
<echo>Finishing the build</echo>
<record name="test.txt" action="stop"/>
<echo>${output}</echo>
<fail>Something wrong here.</fail> <!-- I want to throw this error conditionally -->
</target>
What you're looking for is the exec task's outputproperty attribute.
You can do something like this:
<exec executable="${my.executable}" outputproperty="exec.output">
<arg value="${my.arg}" />
</exec>
<fail message="Invalid output from exec task">
<condition>
<contains string="${exec.output}" substring="The workspace with the specified string does not exist." />
</condition>
</fail>
Multiple conditions (any level of complexity in the boolean is allowed):
<fail message="Invalid output from exec task">
<condition>
<and>
<not>
<contains string="${exec.output}" substring="SUCCESS" />
</not>
<or>
<contains string="${exec.output}" substring="ERROR" />
<contains string="${exec.output}" substring="FAILED" />
<or>
</and>
</condition>
</fail>
Regex:
<fail message="Invalid output from exec task">
<condition>
<matches string="${exec.output}" pattern="The .* does not exist." />
</condition>
</fail>
<!-- * This is an ANT script to build the project in development environment.
Steps involved in this are
* Building the project
* Publishing the project
* Creating the package for the project
-->
<!--
Sample command to execute this
ant build -DORG_NAME=businessservices3 -DWORKSPACE_NAME=ConfigurationManagement -DPROJECT_NAME='ConfigurationManagement'
-->
<project name="Building Project" default="build">
<property file="${PROJECT}" />
<target name="build">
<echo>Welcome to Apache Ant! Building the project in Cordys Middleware</echo>
<property environment="env"/>
<property name="bop.install.dir" value="${env.CORDYS_HOME}"/>
<exec executable="${bop.install.dir}/components/cws/scripts/linux/CWSPackage.sh" outputproperty="exec.output">
<env key="CLASSPATH" value="/opt/Cordys/Oracle_Jar/ojdbc6.jar"/>
<arg value="${ORG_NAME}"/>
<arg value="${WORKSPACE_NAME}"/>
<arg value="${PROJECT_NAME}"/>
</exec>
<fail message="Build not successful for the project ${PROJECT_NAME}">
<condition>
<not>
<contains string="${exec.output}" substring="Operation completed successful" />
</not>
</condition>
</fail>
</target>
</project>
This worked for me after so much of trail and error methods.
Thanks Austin. Even though this is the ANT which is working, I would accept your answer only as this is a modified version of what you told :)

Execute play from Ant script

I'm looking for a way to run play dist through an Ant build script. I've looked into using the exec task but it is not working for me. Here is what I tried:
<target name="deploy">
<exec executable="play">
<arg value="dist" />
</exec>
</target>
I'm getting this error:
C:\Users\path\to\build.xml:39: Execute failed: java.io.IOException: Cannot run program "play": CreateProcess error=2, The system cannot find the file specified
Play is already in my Path environment variable and I can execute it from the command line by typing play so that isn't the problem. I'm not allowed to use absolute paths due to sysadmin constraints.
Any ideas?
Ended up manually searching for the Play executable and storing the property to use in the exec task:
<exec executable="where" outputproperty="play.dir" osfamily="windows">
<arg value="play.bat" />
</exec>
<exec executable="which" outputproperty="play.dir" osfamily="unix">
<arg value="play" />
</exec>
<exec executable="${play.dir}" dir=" ... ">
<arg value="dist" />
</exec>

Shell script isn't run by ant using exec tag if script is in a different directory

Here is the portion of my ant script that doesn't work properly.
<exec executable="/bin/bash">
<arg value="../libraries/android-mapviewballoons/android-mapviewballoons/mapimports.sh" />
<arg value="a"/>
</exec>
<exec executable="/bin/bash">
<arg value="mapimports.sh"/>
<arg value="a"/>
</exec>
The first script never runs, but the second script runs fine. No errors are returned. I've tried running both scripts manually and they work.
Does anyone know how I might debug this or make it work?
I got something similar running with:
<exec executable="bash" dir="./pathToScript/" >
<arg value="script.sh" />
<arg value="param" />
</exec>

Exception when trying to access webservice through axis2 in java

I am trying to generate web service client through axis2, but I am getting this error:
org.apache.axis.ConfigurationException: No service named Port is available
Could you please help me out, when this error comes, why and how to resolve that.
The question title and the actual question is different.
Could you please post how you are trying to generate the client through ant script or wsdl2java command, if so please paste ant content or command.
wdl2java Ex:-
%AXIS2_HOME%\bin\WSDL2Java -uri wsdlURL -p net.fmb.integrator.serviceprovider.unistream -d xmlbeans -s
AntScript:-
<target name="cleanWsdl2JavaOutDir" description="cleanWsdl2JavaOutDir">
<echo message=".......Cleaning the Previous SRC directory........"/>
<delete dir="${outputdir}"/>
<mkdir dir="${outputdir}"/>
</target>
<echo message=".............Processing wsdl2java................."/>
<target name="wsdl2java" depends="cleanWsdl2JavaOutDir">
<delete dir="output" />
<java classname="org.apache.axis2.wsdl.WSDL2Java" fork="true">
<classpath refid="axis.classpath"/>
<arg value="-d"/>
<arg value="xmlbeans"/>
<arg value="-uri"/>
<arg value="${wsdlFile}"/>
<arg value="-ss"/>
<arg value="-g"/>
<arg value="-sd"/>
<arg value="-o"/>
<arg file="${outputdir}"/>
<arg value="-p"/>
<arg value="${outputpkg}"/>
</java>
</target>

How to determine build architecture (32bit / 64bit) with ant?

We have inherited an ant build file but now need to deploy to both 32bit and 64bit systems.
The non-Java bits are done with GNUMakefiles where we just call "uname" to get the info. Is there a similar or even easier way to mimic this with ant?
Late to the party, but what the heck...
${os.arch} only tells you if the JVM is 32/64bit. You may be running the 32bit JVM on a 64bit OS. Try this:
<var name ="os.bitness" value ="unknown"/>
<if>
<os family="windows"/>
<then>
<exec dir="." executable="cmd" outputproperty="command.ouput">
<arg line="/c SET ProgramFiles(x86)"/>
</exec>
<if>
<contains string="${command.ouput}" substring="Program Files (x86)"/>
<then>
<var name ="os.bitness" value ="64"/>
</then>
<else>
<var name ="os.bitness" value ="32"/>
</else>
</if>
</then>
<elseif>
<os family="unix"/>
<then>
<exec dir="." executable="/bin/sh" outputproperty="command.ouput">
<arg line="/c uname -m"/>
</exec>
<if>
<contains string="${command.ouput}" substring="_64"/>
<then>
<var name ="os.bitness" value ="64"/>
</then>
<else>
<var name ="os.bitness" value ="32"/>
</else>
</if>
</then>
</elseif>
</if>
<echo>OS bitness: ${os.bitness}</echo>
EDIT:
As #GreenieMeanie pointed out, this requires the ant-contrib library from ant-contrib.sourceforge.net
you can get at the java system properties (http://java.sun.com/javase/6/docs/api/java/lang/System.html#getProperties()) from ant with ${os.arch}. other properties of interest might be os.name, os.version, sun.cpu.endian, and sun.arch.data.model.
Here is an answer that works (I tested on Kubuntu 64, Debian 32, Windows 2000 and Windows XP) without the need of external or optional ANT dependencies. It was based on #phatypus's answer.
<project name="FindArchitecture" default="check-architecture" basedir=".">
<!-- Properties set: unix-like (if it is unix or linux), x64 (if it is 64-bits),
register- size (32 or 64) -->
<target name="check-architecture" depends="check-family,check-register" >
<echo>Register size: ${register-size}</echo>
<echo>OS Family: ${os-family}</echo>
</target>
<target name="check-family" >
<condition property="os-family" value="unix" else="windows">
<os family="unix" />
</condition>
<condition property="unix">
<os family="unix" />
</condition>
</target>
<target name="check-register" depends="reg-unix,reg-windows">
</target>
<!-- Test under GNU/Linux -->
<target name="reg-unix" if="unix">
<exec dir="." executable="uname" outputproperty="result">
<arg line="-m"/>
</exec>
<!-- String ends in 64 -->
<condition property="x64">
<matches string="${result}" pattern="^.*64$"/>
</condition>
<condition property="register-size" value="64" else="32">
<isset property="x64"/>
</condition>
</target>
<!-- Test under MS/Windows-->
<target name="reg-windows" unless="unix">
<!-- 64 bit Windows versions have the variable "ProgramFiles(x86)" -->
<exec dir="." executable="cmd" outputproperty="result">
<arg line="/c SET ProgramFiles(x86)"/>
</exec>
<!-- String ends in "Program Files (x86)" -->
<condition property="x64">
<matches string="${result}" pattern="^.*=.*Program Files \(x86\)"/>
</condition>
<condition property="register-size" value="64" else="32">
<isset property="x64"/>
</condition>
</target>
</project>
You can just pass a parameter into the build file with the value you want. For example, if your target is dist:
ant -Dbuild.target=32 dist
or
ant -Dbuild.target=64 dist
and then in your Ant build script, take different actions depending on the value of the ${build.target} property (you can also use conditions to set a default value for the property if it is not set).
Or, you can check the value of the built-in system properties, such as ${os.arch}.
os.arch does not work very well, another approach is asking the JVM, for example:
~$ java -d32 test
Mon Jun 04 07:05:00 CEST 2007
~$ echo $?
0
~$ java -d64 test
Running a 64-bit JVM is not supported on this platform.
~$ echo $?
1
That'd have to be in a script or a wrapper.
BTW, the os.arch (arch property of the os tag) I got for 64-bit Linux was amd64.
Assuming you are using ANT for building Java Application, Why would you need to know if it is a 32 bit arch or 64-bit? We can always pass parameters to ant tasks. A cleaner way would be to programmaticaly emit the system properties file used by Ant before calling the actual build. There is this interesting post http://forums.sun.com/thread.jspa?threadID=5306174.

Categories

Resources