Ant-contrib : AntCallback always returns same value - ant

My problem is;
When I call an antcallback function more than one, It returns the same value always. Check out the following code :
<project name="AntCallBack" default="testFnc" basedir=".">
<taskdef resource="net/sf/antcontrib/antcontrib.properties" />
<target name="acbFnc" description="Sub Function" >
<echo message="[acbFnc] started"/>
<property name="out.file" value="${in.file}"/>
<echo message="[acbFnc] ended."/>
</target>
<target name="testFnc" description="Main" >
<antcallback target="acbFnc" return="out.file" >
<param name="in.file" value="TEST-1" />
</antcallback>
<echo message="CALL - 1 : out.file : ${out.file}" />
<antcallback target="acbFnc" return="out.file" >
<param name="in.file" value="TEST-2" />
</antcallback>
<echo message="CALL - 2 : out.file : ${out.file}" />
</target>
</project>
The result is :
$ /home/apache-ant-1.9.4/bin/ant -f AntCallBackTest.xml
Buildfile: AntCallBackTest.xml
testFnc:
acbFnc:
[echo] [acbFnc] started
[echo] [acbFnc] ended.
[echo] CALL - 1 : out.file : TEST-1
acbFnc:
[echo] [acbFnc] started
[echo] [acbFnc] ended.
[echo] CALL - 2 : out.file : TEST-1
BUILD SUCCESSFUL
Total time: 0 seconds
As you see I sent "param name="in.file" value="TEST-1" " in first call,
And I sent "param name="in.file" value="TEST-2" " in second call,
But It always returned the first value :
[echo] CALL - 1 : out.file : TEST-1
[echo] CALL - 2 : out.file : TEST-1
What am I doing wrong?
Thanks in advance

I found the solution :
I have to unset the variable before second call with :
<var name="out.file" unset="true"/>
I mean, it should be like this :
<target name="testFnc" description="Main" >
<antcallback target="acbFnc" return="out.file" >
<param name="in.file" value="TEST-1" />
</antcallback>
<echo message="CALL - 1 : out.file : ${out.file}" />
<var name="out.file" unset="true"/>
<antcallback target="acbFnc" return="out.file" >
<param name="in.file" value="TEST-2" />
</antcallback>
<echo message="CALL - 2 : out.file : ${out.file}" />
</target>

Related

How to display an ant patternset

I'm trying to display an ant patternset for debugging purposes. In my sample the patternset is displayed as dontcompile patternSet{ includes: [] excludes: [] }, no info from the excludesfile is shown.
I know the excludesfile is working because on Linux no windows sources are shown at the end.
build.xml
<project default="init" >
<condition property="osname" value="linux">
<os family="unix" />
</condition>
<!-- if it's not unix assume it's some kind of windows -->
<property name="osname" value="windows" />
<target name="init" >
<local name="dont_compile.os.present" />
<local name="dont_compile.present" />
<available file="dont_compile.${osname}.lst" property="dont_compile.os.present" />
<available file="dont_compile.lst" property="dont_compile.present" />
<echo>dont_compile.${osname}.lst ${dont_compile.os.present}${line.separator}dont_compile.lst ${dont_compile.present}</echo>
<patternset id="dontcompile">
<excludesfile name="dont_compile.${osname}.lst" if="dont_compile.os.present" />
<excludesfile name="dont_compile.lst" if="dont_compile.present" />
</patternset>
<fileset id="myfileset" dir=".">
<include name="**/*.source" />
<patternset refid="dontcompile" />
</fileset>
<loadfile property="os_contents" srcFile="dont_compile.${osname}.lst" />
<local name="ps.value" />
<property name="ps.value" refid="dontcompile" />
<echo>
dontcompile ${ps.value}"
os_contents ${os_contents}
${toString:myfileset}
</echo>
</target>
</project>
contents of dont_compile.linux.lst
windows.source
win/**
contents of my test directory
./build.xml
./dont_compile.linux.lst
./general.source
./linux.source
./windows.source
./win/sub.source
sample output
Buildfile: build.xml
init:
[echo] dont_compile.linux.lst true
[echo] dont_compile.lst ${dont_compile.present}
[echo]
[echo] dontcompile patternSet{ includes: [] excludes: [] }"
[echo] os_contents windows.source
[echo] win/sub.source
[echo]
[echo] general.source;linux.source
BUILD SUCCESSFUL
Total time: 0 seconds

Propertyregex to read a CSV line and assign fields to variables

I have a csv/txt file with below entries
abc,123
xyz,678
ijk,921
I'm trying to read the file through for loop and assign first element to var1, and second to var2
var1=abc
var2=123
I need to use these variables to perform some task and return back to the loop to read the next line of the file and assign new values.
Below is what I have, and I'm not able to assign the variable
<loadfile property="message" srcFile="test.txt" />
<target name="compile">
<for param="line" list="${message}" delimiter="${line.separator}">
<sequential>
<echo>#{line}</echo>
<propertyregex property="var1"
input="#line"
regexp="/^(.+?),(.+)/"
select="\1" />
<echo message="${var1}" />
</sequential>
</for>
</target>
Below is the output I get, showing no assignment of value to var1.
[echo] abc,123
[echo] ${var1}
[echo] xyz,678
[echo] ${var1}
[echo] ijk,921
[echo] ${var1}
You have a couple of errors, the below loop body works for me, see output at the end.
The first problem is that the #{line} parameter substitution syntax in the for loop uses an antcontrib macrodef, and the {} brakets are not optional - you had missed them out of the input="" attribute, whereas in the echo task you had included them.
The second problem is that you need not specify enclosing slashes /../ in the rexexp= attribute.
<echo>#{line}</echo>
<propertyregex property="var1"
override="yes"
input="#{line}"
regexp="^(.+?),(.+)"
select="\1"/>
<propertyregex property="var2"
override="yes"
input="#{line}"
regexp="^(.+?),(.+)"
select="\2"/>
<echo message="${var1},${var2}" />
Output:
[echo] abc,123
[echo] abc,123
[echo] xyz,678
[echo] xyz,678
[echo] ijk,921
[echo] ijk,921

Use Property value as a Key to read another value from Properties file

For Ant Script I have following myBuild.properties file
p.buildpath=c:\production\build
d.buildpath=c:\development\build
I wrote following build.xml:
<?xml version="1.0"?>
<project name="Test Project" default="info">
<property file="myBuild.properties"/>
<target name="info">
<input
message="Please enter the Server Name(p: production, d: development)?"
validargs="p,d"
addproperty="do.Server"
/>
<echo>Your Server type: ${do.Server} </echo>
<property name="myserv.buildpath" value="${do.Server}.buildpath" />
<property name="newProperty" value="${myserv.buildpath}" />
<echo>New Property Value: ${newProperty}</echo>
<!-- Following is an incorrect syntax -->
<echo>Build Path: ${${newProperty}}</echo>
</target>
</project>
When I run it using:
c:\>ant
I get following Output:
Buildfile: C:\build.xml
info:
[input] Please enter the Server Name(p: production, d: development)? (p, d)
p
[echo] Your Server type : p
[echo] New Property Value: p.buildpath
[echo] Build Path: ${${newProperty}}
BUILD SUCCESSFUL
Total time: 2 seconds
I want to echo the "Build Path" value same as p.buildpath value.
How is it possible to do in above case?
Taking the macrodef advice of Ant Faq you need no Ant addons like antcontrib, it's foolproof :
<project>
<macrodef name="cp_property">
<attribute name="name"/>
<attribute name="from"/>
<sequential>
<property name="#{name}" value="${#{from}}"/>
</sequential>
</macrodef>
<property file="myBuild.properties"/>
<input
message="Please enter the Server Name(p: production, d: development)?"
validargs="p,d"
addproperty="do.Server"
/>
<echo>Your Server type: ${do.Server}</echo>
<cp_property name="myserv.buildpath" from="${do.Server}.buildpath"/>
<echo>$${myserv.buildpath} : ${myserv.buildpath}</echo>
</project>
output :
[input] Please enter the Server Name(p: production, d: development)? (p, d)
p
[echo] Your Server type: p
[echo] ${myserv.buildpath} : c:/production/build
btw. Within your propertyfile you need to change your path separator to either unix style '/' (when on windows ant will handle it correctly) or double '\\' , otherwise with :
p.buildpath=c:\production\build
d.buildpath=c:\development\build
you'll get something like :
[input] Please enter the Server Name(p: production, d: development)? (p, d)
p
[echo] Your Server type: p
[echo] ${myserv.buildpath} : c:productionbuild
Also see https://stackoverflow.com/a/25681686/130683 for a very similar problem solved with Props antlib
You can do it without additional tools this way (edited/revised version):
<project name="Test Project" default="info">
<property file="myBuild.properties"/>
<target name="info">
<input
message="Please enter the Server Name(p: production, d: development)?"
validargs="p,d"
addproperty="do.Server"
/>
<echo>Your Server type: ${do.Server} </echo>
<property name="buildstage.production" value="p.buildpath" />
<property name="myserv.buildpath" value="${do.Server}.buildpath" />
<echo>New Property Value: ${myserv.buildpath}</echo>
<condition property="isProduction">
<equals arg1="${buildstage.production}" arg2="${myserv.buildpath}" />
</condition>
<antcall target="production" />
<antcall target="development" />
</target>
<target name="production" if="${isProduction}">
<echo>Build Path: ${p.buildpath}</echo>
</target>
<target name="development" unless="${isProduction}">
<echo>Build Path: ${d.buildpath}</echo>
</target>
</project>
Core idea is using a <conditional> task for a test on the selected property key and calling two tasks named production and development, where the first runs if the property isProduction is avaluated to true, the second if not (unlesss).
The condition is checked against a property named buildstage.production which is set to the property key p.buildpath as discriminator.
With "property key" I reference to the keys in the properties file. A hole bunch of "properties" here, could be confusing :)
By the way: you need to escape the backslashs in the property values as follows, otherwise they won't be echoed:
p.buildpath=c:\\production\\build
d.buildpath=c:\\development\\build
How it says in this post (http://ant.apache.org/faq#propertyvalue-as-name-for-property), without any external help, it's tricky.
With AntContrib (external task library) you can do <propertycopy name="prop" from="${anotherprop}"/>.
Anyway, there are other alternatives in the same post.
Hope it helps you.
There is a much simpler way that does not require macrodef or antcontrib:
<property name="a" value="Hello"/>
<property name="newProperty" value="a"/>
<loadresource property="b">
<propertyresource name="${newProperty}"/>
</loadresource>
<echo message="a='${a}'"/>
<echo message="b='${b}'"/>

Passing variables to arg in Ant Script

I've the following Ant command. I need to pass a variable {merged.folder} to the arg line. This value comes from a property file. But it is not resolving that variable. Is there any way to do this. Can you please help me?
<java fork="true" dir="${shrinksafe.util.path}/buildscripts" classname="org.mozilla.javascript.tools.shell.Main">
<arg line="releaseDir=${merged.folder}" />
<classpath>
<pathelement location="${shrinksafe.util.path}/shrinksafe/js.jar" />
<pathelement location="${shrinksafe.util.path}/shrinksafe/shrinksafe.jar" />
<pathelement path="${java.class.path}" />
</classpath>
</java>
I've checked this ant script based on your post:
<?xml version="1.0" encoding="UTF-8"?>
<project default="test_arg_path" basedir=".">
<property file="props.properties"/>
<target name="test_arg_path">
<java dir=".\build\classes" classname="Test">
<!-- <arg value="${argValue}"/>--> <!-- First variant -->
<arg line="releaseDir=${argValue} arg2Value" /> <!-- Second variant -->
</java>
</target>
</project>
Property file props.properties:
argValue=argVal
Test class source:
public class Test {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("args is empty");
}
System.out.println(Test.class + ", arg0: " + args[0]);
if (args.length > 1) {
System.out.println(Test.class + ", arg1: " + args[1]);
}
}
}
The output for first variant (using arg value):
class Test, arg0: argVal
The output for second variant (using arg line):
class Test, arg0: releaseDir=argVal
class Test, arg1: arg2Value
As you can see, the everything is OK with your script and it is correct. The problem, I think, in value setting of your variable merged.folder

How to start and stop jboss server using Ant task?

I need to stop, deploy my ear file and start Jboss server using the Ant tasks.
I am able to compile, build and deploy my J2EE application as an ear file into the JBoss server successfully using Ant tasks. We can see the redeployment of my application in the jboss console. I want to stop the server before deployment and start the server.
Is there any way to do this ?
Here how you start/stop JBoss app container including deploy an application :
<!-- Stop Jboss -->
<target name="stop-jboss" description="Stops back-end EJB container" >
<exec executable="${jboss.bin.dir}/shutdown.bat" spawn="true">
<arg line="-S" />
</exec>
<echo>+-----------------------------+</echo>
<echo>| J B O S S S T O P P E D |</echo>
<echo>+-----------------------------+</echo>
</target>
<!-- Start Jboss -->
<target name="start-jboss" description="Starts back-end EJB container" >
<exec executable="${jboss.bin.dir}/run.bat" spawn="true">
</exec>
<echo>+-----------------------------+</echo>
<echo>| J B O S S S T A R T E D |</echo>
<echo>+-----------------------------+</echo>
</target>
<!-- deploy target-->
<target name="deploy-war" description="deploy war file" depends="prepare">
<sequential>
<antcall target="stop-jboss" />
<war destfile="${file.name}" webxml="conf/web.xml">
<classes dir="bin" />
</war>
<antcall target="start-jboss" />
<echo>+----------------------------+</echo>
<echo>| W A R D E P L O Y E D |</echo>
<echo>+----------------------------+</echo>
</sequential>
</target>
Hope this is helpful :)
Cargo supports ANT and is designed to support several J2EE containers
The appropriate os independent answer would be something like this:
<property name="my.jboss.home" value="/path/to/jboss/install/dir" />
<property name="my.jboss.host" value="localhost" />
<property name="my.jboss.port" value="9999" />
<property name="my.jboss.name" value="my-jboss-instance" />
<property name="my.jboss.debugport" value="8787" />
<!-- supposedly this is built by a seperate task -->
<property name="my.deployment" value="${basedir}/build/deployment.ear" />
<!-- starting preset -->
<presetdef name="start-jboss-preset">
<java jar="${jboss.home}/jboss-modules.jar" fork="true" taskname="${jboss.name}">
<jvmarg value="-server" />
<jvmarg value="-Xms1024m" />
<jvmarg value="-Xmx1024m" />
<jvmarg value="-Dorg.jboss.boot.log.file=${jboss.home}/standalone/log/server.log" />
<jvmarg value="-Dlogging.configuration=file:${jboss.home}/standalone/configuration/logging.properties" />
<arg line="-mp ${jboss.home}/modules/ -jaxpmodule javax.xml.jaxp-provider org.jboss.as.standalone" />
<jvmarg value="-Djboss.home.dir=${jboss.home}" />
<arg value="-b=localhost" />
<arg value="-c=standalone-full.xml" />
<jvmarg value="-Djboss.node.name=${jboss.name}" />
</java>
</presetdef>
<!-- internal task to actually start jboss -->
<target name="start-jboss">
<start-jboss-preset />
</target>
<!-- internal task to start jboss in debug mode -->
<target name="start-jboss-debug">
<start-jboss-preset taskname="dbg:${jboss.name}:${jboss.debugport}">
<jvmarg value="-agentlib:jdwp=transport=dt_socket,address=${jboss.debugport},server=y,suspend=n" />
</start-jboss-preset>
</target>
<!-- preset to run jboss-cli, this can be used to push any command to a running
jboss instance -->
<presetdef name="jboss-cli">
<java jar="${jboss.home}/jboss-modules.jar" fork="true">
<arg line="-mp ${jboss.home}/modules org.jboss.as.cli" />
<arg value="--controller=${jboss.host}:${jboss.port}" />
<arg value="--connect" />
</java>
</presetdef>
<!-- the actual shut down command -->
<target name="exec-jboss">
<jboss-cli failonerror="true">
<arg value="${jboss.command}" />
</jboss-cli>
</target>
<!-- public targets with your properties set -->
<target name="start" description="starts jboss instance">
<antcall target="start-jboss">
<param name="jboss.home" value="${my.jboss.home}" />
<param name="jboss.name" value="${my.jboss.name}" />
</antcall>
</target>
<target name="debug" description="starts jboss instance in debugmode">
<antcall target="start-jboss-debug">
<param name="jboss.home" value="${my.jboss.home}" />
<param name="jboss.name" value="${my.jboss.name}" />
<param name="jboss.debugport" value="${my.jboss.debugport}" />
</antcall>
</target>
<target name="stop" description="stops jboss instance">
<antcall target="exec-jboss">
<param name="jboss.home" value="${my.jboss.home}" />
<param name="jboss.host" value="${my.jboss.host}" />
<param name="jboss.port" value="${my.jboss.port}" />
<param name="jboss.command" value="shutdown" />
</antcall>
</target>
<!-- a dependent build / package task should be present -->
<target name="deploy" description="deploys to a running jboss instance">
<antcall target="exec-jboss">
<param name="jboss.home" value="${my.jboss.home}" />
<param name="jboss.host" value="${my.jboss.host}" />
<param name="jboss.port" value="${my.jboss.port}" />
<param name="jboss.command" value="deploy ${my.deployment}" />
</antcall>
</target>

Resources