How to invoke same target by passing different parameter values using antcall? - ant

How to invoke same target by passing different values to the parameter?
I wanted to invoke target using antcall.
Based on some falg i wanted to invoke a target by passing different values to the parameter using param.

Don't use antcall, better use macrodef (introduced with Ant 1.6) instead !!
I won't go into details, just search the web for 'antcall vs. macrodef' and similar..
See also Writing Better Ant Scripts: Techniques, Patterns and Antipatterns
Some snippet :
<project xmlns:if="ant:if">
<macrodef name="foobar">
<attribute name="foo"/>
<attribute name="verbose"/>
<sequential>
<echo>#{foo}</echo>
<echoproperties prefix="ant" if:true="#{verbose}"/>
</sequential>
</macrodef>
<!-- use foobar macrodef with different parameters (attribute values) -->
<foobar verbose="yes" foo="1. yada,yada"/>
<foobar verbose="no" foo="2. blabla.."/>
</project>
output :
[echo] 1. yada,yada
[echoproperties] #Ant properties
[echoproperties] #Thu Sep 18 09:31:05 CEST 2014
[echoproperties] ant.core.lib=C\:\\ant194\\lib\\ant.jar
[echoproperties] ant.file=C\:\\area51\\ant\\tryme.xml
[echoproperties] ant.home=C\:\\ant194
[echoproperties] ant.java.version=1.7
[echoproperties] ant.library.dir=C\:\\ant194\\lib
[echoproperties] ant.version=Apache Ant(TM) version 1.9.4 compiled on April 29 2014
[echo] 2. blabla..

Related

How to locate specific property in ANT if the xml property file provided to ant has repeating xml elements

I am trying to read a property file (xml) in ANT.
Following is the sample data.
<WebLogicDomain>
<Domain>MyDomain</Domain>
<Environment>DEV</Environment>
<Servers>
<Server id = '1'>
<Host>Host1</Host>
<Port>14100</Port>
<AliasName>adminserver</AliasName>
<IsAdmin>true</IsAdmin>
<AdminServerHost>adminHost</AdminServerHost>
<ClusterName>#NA</ClusterName>
<MinHeap>512MB</MinHeap>
<MaxHeap>2048MB</MaxHeap>
</Server>
<Server id = '2'>
<Host>Host2</Host>
<Port>14110</Port>
<AliasName>managedserver01</AliasName>
<IsAdmin>false</IsAdmin>
<AdminServerHost>adminHost</AdminServerHost>
<ClusterName>Cluster1</ClusterName>
<MinHeap>512MB</MinHeap>
<MaxHeap>2048MB</MaxHeap>
</Server>
</Servers>
</WebLogicDomain>
With this property file I can easily access Domain & Environment properties but How do I get specific Server Properties?
If I need to get ${WebLogicDomain.Servers.Server[1].Host} i.e Host present at index 1, how do I get that?
Follwoing doesn't work as expected.
<project name="SampleProject">
<xmlproperty file="buildproperties.xml" />
<target name="init">
<echo> ******** XML property file has been loaded. ******** </echo>
<echo> Domain name is : ${WebLogicDomain.Domain}</echo>
<echo> Environment is : ${WebLogicDomain.Environment}</echo>
<echo> First Server Details are : ${WebLogicDomain.Servers.Server[1].Host} </echo>
</target>
</project>
When I run the init target, I get following error.
init:
[echo] ******** XML property file has been loaded. ********
[echo] Domain name is : MyDomain
[echo] Environment is : DEV
[echo] First Server Details are : ${WebLogicDomain.Servers.Server[1].Host}
When Ant's xmlproperty task finds multiple elements with the same name in the same location, it saves them to a single property as a comma-delimited list. Try using the xmlproperty task to view all the properties that your build has loaded, along with corresponding nested elements. DOM information, unfortunately, is mostly lost. You can try to rely on the order in which the properties are listed, using regex to extract the relevant information, but this will almost certainly be awkward and unreliable.
<xmlproperty file="weblogic.xml" />
<echoproperties prefix="WebLogicDomain" />
Output:
[echoproperties] #Ant properties
[echoproperties] #Thu Feb 15 16:42:17 PST 2018
[echoproperties] WebLogicDomain.Domain=MyDomain
[echoproperties] WebLogicDomain.Environment=DEV
[echoproperties] WebLogicDomain.Servers.Server(id)=1,2
[echoproperties] WebLogicDomain.Servers.Server.AdminServerHost=adminHost,adminHost
[echoproperties] WebLogicDomain.Servers.Server.AliasName=adminserver,managedserver01
[echoproperties] WebLogicDomain.Servers.Server.ClusterName=\#NA,Cluster1
[echoproperties] WebLogicDomain.Servers.Server.Host=Host1,Host2
[echoproperties] WebLogicDomain.Servers.Server.IsAdmin=true,false
[echoproperties] WebLogicDomain.Servers.Server.MaxHeap=2048MB,2048MB
[echoproperties] WebLogicDomain.Servers.Server.MinHeap=512MB,512MB
[echoproperties] WebLogicDomain.Servers.Server.Port=14100,14110
If you really need to do XML parsing that is more complicated than basic string retrieval, there's a 3rd party plugin called XmlTask that can accomplish this. http://www.oopsconsultancy.com/software/xmltask/
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask">
<classpath location="lib/xmltask.jar"/>
</taskdef>
<target name="default">
<xmltask source="weblogic.xml">
<copy path="WebLogicDomain/Servers/Server[#id='1']/Host/text()" property="server.1.host"/>
</xmltask>
<echo message="${server.1.host}" />
</target>
Output:
[echo] Host1

Write "java -version" to a file using ant

I want to have a target in my script that records the user's java version in a file format. But for some reason the output to the command "java -version" cannot be recorded.
I tried running java -version > java.txt in terminal, which doesn't work either so I am guessing the result from java -version cannot be captured?
You can use the following exec task in your Ant build.xml:
<exec executable="java">
<arg value="-version"/>
<redirector output="java-version.txt" alwayslog="true"/>
</exec>
Simply use Ant builtin properties, see Ant Manual / Built-in Properties, f.e. :
<echoproperties prefix="java"/>
will print all Java properties.
There are 3 version related properties :
java.version
java.vm.specification.version
java.vm.version
So simply take the appropriate property:
<project>
<echo>
${java.version}
${java.vm.specification.version}
${java.vm.version}
</echo>
<!-- assuming you want ${java.version} -->
<echo file="foobar.txt">Java Version = ${java.version}</echo>
</project>
output :
[echo] 1.7.0_72
[echo] 1.7
[echo] 24.72-b04

build.xml to set date and time as file name

I want to set file name with date and time attached to it so I want to create file named as behat-20140913-195915.html however the example below sets the name as behat-yyyymmdd-hhiiss.html. Anyone know the solution to problem?
I followed this example
Note: These two don't work too: ${DSTAMP} ${TSTAMP}
<?xml version="1.0" encoding="UTF-8"?>
<project name="Sport" default="build-default" basedir=".">
<tstamp>
<format property="TODAY_MY" pattern="yyyymmdd-hhiiss" locale="en,UK" />
</tstamp>
<target name="build" description="Runs everything in order ..." depends="behat-bdd" />
<target name="behat">
<echo msg="Running Behat tests ..." />
<exec logoutput="true" checkreturn="true"
command="bin/behat -f progress --format html --out ${dir-report}/behat-${TODAY_MY}.html" dir="./" />
</target>
</project>
The tstamp task is documented in the ANT manual. It describes how the pattern format comes from the SimpleDateFormat object:
http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
I suggest trying the following:
Example
Buildfile: build.xml
build:
[echo] date: 20140913-203419
build.xml
<project name="demo" default="build">
<tstamp>
<format property="TODAY_MY" pattern="yyyyMMdd-HHmmss" locale="en,UK" />
</tstamp>
<target name="build">
<echo message="date: ${TODAY_MY}"/>
</target>
</project>
Software versions
$ ant -v
Apache Ant(TM) version 1.9.4 compiled on April 29 2014
$ java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

Ant & how to parse a properties file to echo back the values

I have a properties file that I want to echo out the values
<HSMKeys>
<Key domain="default" value="TestA" />
<Key domain="fixed" value="TestB" />
</HSMKeys>
as
[echo] domain=default value=TestA
[echo] domain=fixed value=TestB
How can I do this, ie loop over the properties file and have the two variables that would be in the echo.
I have tried the following
<for list="${HSMKeys.Key.domain}" param="domain">
<sequential>
<echo>domain=#{domain}</echo>
</sequential>
</for>
ie I can only get at one attribute value at a time, not both at once.
Thanks.
As #thekbb has stated this is not a properties file, however, ANT supports the parsing of XML files as properties.
<project name="demo" default="print">
<xmlproperty file="properties.xml"/>
<target name="print">
<echoproperties prefix="HSMKeys."/>
</target>
</project>
Produces the following output:
print:
[echoproperties] #Ant properties
[echoproperties] #Tue Dec 03 23:44:14 GMT 2013
[echoproperties] HSMKeys.Key=,
[echoproperties] HSMKeys.Key(domain)=default,fixed
[echoproperties] HSMKeys.Key(value)=TestA,TestB
May not be exactly what you need but has the advantage of not requiring additional jars like Ant-contrib.
That's not a properties file. Properties files are key/value pairs. How are you populating list?
a property file ant will understand will look like:
domain.default=TestA
domain.fixed=testB
I recommend avoiding ant-contrib at all costs... what are you really trying to do?
you could simply use echoproperties
<project name="test" default="echo" basedir=".">
<property file="build.properties" />
<target name="echo" >
<echoproperties prefix="domain."/>
</target>
</project>

Run ant task in different jvm

Our ant build is run using Java 1.7.0 for JAVA_HOME. This way javac and all other Java dependent targets use the correct Java by default.
But 1 ant target from an external supplier does not support (or rather has a bug) using Java 1.7.0. And unlike e.g. javac or a forked junit, this target does not support parameters to switch jvm.
Is it possible to run a specific ant target in a different jvm?
To make Jeanne Boyarsky's suggestion of using the exec Ant task concrete, the following example wraps the exec task in a macro to simplify calling targets with various JVMs. Notice that the JVM is set using the Ant environment variable JAVACMD.
Example Project
<?xml version="1.0" encoding="UTF-8"?>
<project name="run-target-with-specified-java-version" default="test">
<macrodef name="exec-target">
<attribute name="antfile" default="${ant.file}" />
<attribute name="target" />
<attribute name="jvm" default="${java.home}/bin/java" />
<sequential>
<exec executable="ant">
<env key="JAVACMD" value="#{jvm}" />
<arg line='-f "#{antfile}"' />
<arg line="#{target}" />
</exec>
</sequential>
</macrodef>
<target name="echo-java-version">
<echo message="Java version: ${java.version}" />
</target>
<target name="test">
<exec-target target="echo-java-version" />
<property name="java1.6"
location="/usr/lib/jvm/jdk1.6/bin/java" />
<exec-target target="echo-java-version" jvm="${java1.6}" />
</target>
</project>
Output
test:
[exec] Buildfile: /home/your/project/build.xml
[exec]
[exec] echo-java-version:
[exec] [echo] Java version: 1.7.0
[exec]
[exec] BUILD SUCCESSFUL
[exec] Total time: 0 seconds
[exec] Buildfile: /home/your/project/build.xml
[exec]
[exec] echo-java-version:
[exec] [echo] Java version: 1.6.0
[exec]
[exec] BUILD SUCCESSFUL
[exec] Total time: 0 seconds
BUILD SUCCESSFUL
Total time: 2 seconds
You can use the exec task to run the build file with that target defined to run as a parameter. It could be running in a different JVM since you can pass the JVM to that exec call.
Note that you'd have to refactor the target to rely on files for communication rather than setting properties. Since it would be in a different JVM, it obviously can't rely on memory.
You can run a target in a different JVM (we do it all the time). You just need to use fork:
<javac srcdir="${src}"
destdir="${build}"
fork="yes"
/>
But I sense you are aware of this, so how about running the external ANT task as it is, and rest of them (lets say you have 3 more javac tasks) in the JVM you want. This can be achieved by setting a property file. See javac task
It is possible to use different compilers. This can be specified by either setting the global build.compiler property, which will affect all tasks throughout the build
So this property will affect your 3 tasks and run them in the JVM you specified (say 1.7) and you can set the default JAVA_HOME to whatever your external library task needs.

Resources