can't overwrite reference with ant task using nested reference element - ant

I have a main build file with a path declaration
<path id="path.app.src">
<pathelement location="myfolder/src"/>
</path>
Then i call a task in sub file with <ant>
<ant antfile="subbuild.xml" inheritAll="false" inheritRefs="false">
<reference refid="path.app.src"/>
</ant>
in subbuild.xml i have:
<path id="subpath.app.src">
<pathelement location=".. some locations .."/>
<path refid="path.app.src" />
</path>
In my understanding the call to <ant> with a nested should overwrite path.app.src in subbuild.xml.
But i get an error like: subbuild.xml:xx: Reference path.app.src not found.
Am i doing something wrong ? is it a bug in ant ?
I'm using Apache Ant version 1.7.0 compiled on December 13 2006
Thanks,
Lionel

in fact it seems to have the right behavior now, but i can't explain what i did wrong the first time.
here is the code sample:
build.xml
<?xml version="1.0"?>
<project name="test" default="build" basedir=".">
<path id="mainpath">
<pathelement location="my/main/path"/>
</path>
<target name="build">
<ant antfile="subbuild.xml" target="test">
<reference refid="mainpath" torefid="globalpathid"/>
<reference refid="mainpath" torefid="localtotargetpathid"/>
</ant>
</target>
</project>
subbuild.xml
<?xml version="1.0"?>
<project name="subbuild">
<path id="globalpathid">
<pathelement location="my/sub/location"/>
</path>
<target name="test">
<path id="localtotargetpathid">
<pathelement location="my/target/location"/>
</path>
<property name="p.localtotargetpathid" refid="localtotargetpathid" />
<echo>p.localtotargetpathid: ${p.localtotargetpathid}</echo>
<property name="p.globalpathid" refid="globalpathid" />
<echo>p.globalpathid: ${p.globalpathid}</echo>
</target>
</project>
here is the console log:
$ ant
Buildfile: build.xml
build:
[ant] Parent project doesn't contain any reference 'mainpath'
test:
[echo] p.localtotargetpathid: d:\my\target\location
[echo] p.globalpathid: d:\my\main\path
BUILD SUCCESSFUL
Total time: 0 seconds
we can see globalpathid has been override but not localtotargetpathid, which is the behvior mentioned in the spec.
still I can't explain the first message ...

I think you have an incomplete declaration here in the subbuild file of refid path.app.src.
<path id="subpath.app.src">
<pathelement location=".. some locations .."/>
<path refid="path.app.src" /> <=======
</path>
It should not have the 2nd nested path element () since there is no location associated with it. The way you wrote the main build file to overwrite no reference //other than// this refid looks good to me.

Related

ANT - Converting a String to Path with location attribute

I have the following ANT script that gives me a list of websphere libraries at runtime based on the websphere root directory. I need to convert the resulting string into separate path location elements
My current script is
<?xml version="1.0" encoding="UTF-8"?>
<project name="TestPath" basedir="." default="print-dirset">
<target name="init" description="Define websphere libraries">
<property name="compile.lib.dir" value="C:\Software\WAS85" />
</target>
<target name="print-dirset" depends="init" description="">
<path id="websphere.libs">
<dirset dir="${compile.lib.dir}">
<include name="*" />
</dirset>
</path>
<property name="websphere.libs.list" refid="websphere.libs" />
<echo message="websphere.libs.list: ${websphere.libs.list}" />
<pathconvert property="websphere.libs.convert" pathsep="${file.separator}*${path.separator}">
<path path="${websphere.libs.list}" />
</pathconvert>
<echo message="websphere.libs.convert: ${websphere.libs.convert}" />
</target>
</project>
which outputs a string like below
[echo] websphere.libs.list: C:\Software\WAS85\Scheduler;C:\Software\WAS85\UDDIReg;C:\Software\WAS85\bin;C:\Software\WAS85\configuration;....C:\Software\WAS85\web;C:\Software\WAS85\wlp
[echo] websphere.libs.convert: C:\Software\WAS85\Scheduler\*;C:\Software\WAS85\UDDIReg\*;C:\Software\WAS85\bin\*;C:\Software\WAS85\configuration\*;...C:\Software\WAS85\web\*;C:\Software\WAS85\wlp
I would like to translate the second string above into a structure like below
<path id="websphere.classpath">
<pathelement location="C:\Software\WAS85\Scheduler\*" />
<pathelement location="C:\Software\WAS85\UDDIReg\*" />
<pathelement location="C:\Software\WAS85\bin\*" />
<pathelement location="C:\Software\WAS85\configuration\*" />
......
<pathelement location="C:\Software\WAS85\web\*" />
<pathelement location="C:\Software\WAS85\wlp\*" />
</path>
The last element in the conversion also needs to add the '\*' part which is not in the original string.
which can then be used with a structure like
<path id="compile.classpath">
<path refid="ext.classpath"/>
<path refid="websphere.classpath"/>
<path refid="module.compile.classpath"/>
</path>
The purpose of the above attempt is to reduce the length of classpath by using wildcard classpath provided by JDK 1.6 and which is available in ANT starting ANT 1.8.2. I am using ANT 1.8.4.
I am not an expert in ANT, I can just get by, by looking at examples.
Is there a way to achieve what I am trying to do? How can I do it? Any example would be very helpful.
If all of your dependencies reside in C:\Software\WAS85, you can use fileset to catch all of your dependencies:
<fileset dir="${compile.lib.dir}" id="compile.files">
<include name="**/*.java"/>
<!-- include name="**/*.jar" /-->
</fileset>
You can then use to refer to this fileset as compile.files elsewhere in your build.xml.
I was able to get the wildcard part to work by using the fork="yes" and executable="path-to-my-executable" attributes in the javac task.
I do not want to mark the question answered, because my basic question was about converting the string. But since the answer received didn't talk about that and also didn't mention how to get wildcard classpath working, and the purpose of my question was to get the wildcard classpath working, i have noted it here for whoever is trying to get that to work
I still need some help in converting the semi-colon separated string to construct like below
<path id="websphere.classpath">
<pathelement location="C:\Software\WAS85\Scheduler\*" />
<pathelement location="C:\Software\WAS85\UDDIReg\*" />
<pathelement location="C:\Software\WAS85\bin\*" />
<pathelement location="C:\Software\WAS85\configuration\*" />
......
<pathelement location="C:\Software\WAS85\web\*" />
<pathelement location="C:\Software\WAS85\wlp\*" />
</path>
Update:
I wrote a custom ANT task to get the wildcard classpath working

Build.xml issue

Selenium - ANT -TestNG
I have written a build.xml, where it produces a error stating " classname attribute of taskdef element is undefined "
Here is my build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name ="AutomationScripts" default="test" basedir=".">
<echo message ="Testing selenium server... Plz wait"/>
<target name="startServer">
<echo message ="Start selenium server... Plz wait"/>
<java jar="..\lib\selenium-server-standalone-2.19.0.jar" fork="true">
<jvmarg value="-Dhttp.proxyHost=192.168.0.200"/>
<jvmarg value="-Dhttp.proxyPort=3128"/> </java>
<echo message ="Started selenium server"/>
</target>
<target name="test" depends="startServer">
<echo message="Test run. Please wait"/>
<mkdir dir="out" />
<java classname="RosettastoneMain" classpath="..\AutomationScripts\bin"
dir="C:\Program Files\Java\jdk1.6.0_11\bin">
<classpath>
<fileset dir="..\AutomationScripts\lib" includes="*.*"/>
</classpatha></java>
<taskdef name="testng" classpath="org.testng.TestNG"> ---------> It produces
error in this stmt
<classpath>
<pathelement location="../lib/testng-6.2.jar"/>
</classpath>
</taskdef>
<property name="testng.output.dir" value="testngOutput"/>
<path id="classes">
<fileset dir="../lib">
<include name="*.jar"/>
</fileset>
<pathelement location="${bin.dir}"/>
</path>
<mkdir dir="${testng.output.dir}"/>
<testng outputdir="${testng.output.dir}" classpathref="classes">
<xmlfileset dir="." includes="testng.xml"/>
</testng> </target>
<target name="stopServer">
<echo message="stop selenium server. Plz wait"/>
<get taskname="selenium-shutdown"
src="http://localhost:4444/selenium-server-standalone-2.0rc2/driver/?cmd=shutDown"
dest="./out/sever.stop.status.txt" ignoreerrors="true"/>
</target>
</project>
Can any one help me out
thanks in advance
You need to specify the class implementing the data type in the 'classname' attribute.
According to the Ant taskdef documentation (and more specifically typedef), this task has two required attributes - 'name' and 'classname', unless 'file' or 'resource' have been specified. The attribute 'classpath' only defines the locations where the class specified in 'classname' can be found.

Ant path convert

Good afternoon
I am running ant to process some code now I have path "com/source/project" in properties but I need to pass "com.source.project" to my java code is there anyway I can convert "/" to "." using ant command
thanks
PropertyRegex task works for you, but you need to install ant-contrib.
<project>
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="./ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<property name="path" value="com/source/project"/>
<echo message="Path=${path}"/>
<propertyregex property="java.package.name"
input="${path}"
regexp="/"
replace="."
global="true"
defaultValue="${path}" />
<echo message="package=${java.package.name}"/>
</project>
Here's some complete project that uses the Ant Plugin Flaka. I also had to replace the ${path.separator} with '.' to start some java classes. See the comments starting with ';'
<project xmlns:fl="antlib:it.haefelinger.flaka">
<fl:install-property-handler/>
<property name="srcroot" value="path/to/srcrootdir"/>
<property name="classroot" value="path/to/classrootdir"/>
<!-- determine all main classes -->
<fileset dir="${srcroot}" includes="**/*.java" id="mainclasses">
<contains text="public static void main"/>
</fileset>
<!-- iterate over those main classes and
call the corresponding classfile -->
<fl:for var="file" in="split('${toString:mainclasses}', ';')">
<fl:let>
; strip the .java Extension
file = replace(file, '', '.java')
; replace fileseparator with '.'
; on Windows you have to use the following line
; replace(file, '\.', '${file.separator}${file.separator}')
file = replace(file, '\.', '${file.separator}')
</fl:let>
<fl:echo>
starting => #{file} in ${classroot}
</fl:echo>
<java classname="#{file}">
<classpath>
<!--
when using a fileset you'll get a
java.util.zip.ZipException because you're
referencing classfiles and no jars
therefore you have to use
pathelement and location
-->
<pathelement location="${classroot}"/>
</classpath>
</java>
</fl:for>
</project>

path definition not recognized in ant

I defined a path in a file called unittest.xml in the following way(line 26):
<path id="tasks.path">
<pathelement location="${publish.home}/INSIDE/UnitTest/testinganttasks.jar"/>
</path>
next I tried to use the path in the following way:
<classpath>
<path refid="tasks.path" />
</classpath>
in a taskdef tag.
when I run my ant code, it does everything well until I get the following error:
BUILD FAILED unittest.xml:296: The
following error occurred while
executing this line: unittest.xml:281:
Reference tasks.path not found.
How can I resolve this issue?
You should see this example at http://ant.apache.org/manual/using.html#references
<project ... >
<path id="project.class.path">
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</path>
<target ... >
<rmic ...>
<classpath refid="project.class.path"/>
</rmic>
</target>
<target ... >
<javac ...>
<classpath refid="project.class.path"/>
</javac>
</target>
</project>
I think your problem is that in classpath you should not nest path element, but give id of the path for the classpath element itself.

Why cannot Ant taskdef cannot load a resource outside ./net

When declaring external ant tasks using taskdef, for instance ant-contrib, the proposed setup is to use the followin taskdef:
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="lib/ant-contrib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
This works when antcontrib.properties is located in net/sf/antcontrib relative to the build.xml file.
But when I put it in lib/net/sf/antcontrib and changes the taskdef into
<taskdef resource="lib/net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="lib/ant-contrib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
Ant is not able to find the properties file, it gives the error
[taskdef] Could not load definitions from resource
lib/net/sf/antcontrib/antcontrib.properties. It could not be found.
It seems like ant treats the lib directory separately and fails to load a taskdef resource from there.
As Alex said, you shouldn't need to unzip the jar. The <taskdef> can load antcontrib.properties directly out of the jar.
The error you got is because you changed the resource path, but the path to the file inside the compressed jar/zip is still the same. The taskdef isn't paying attention to the properties file you moved because the <classpath> you provided to <taskdef> tells it to only look in the jar.
Use antlib.xml resource:
Here is the taskdef definition that I use:
<property name="ant-contrib.jar" location="..."/>
<taskdef
resource="net/sf/antcontrib/antlib.xml"
uri="http://ant-contrib.sourceforge.net"
>
<classpath>
<pathelement location="${ant-contrib.jar}"/>
</classpath>
</taskdef>
You do not need to extract anything from the jar file. Also, uri attribute is optional if you do not want to use namespaces with antcontrib tasks.
To handle classpath for tasks definitions, I use a classpath ref in Ant, it's way easier. You can link either a directory containing classes, either a directory containing many .jar, either (of course) a single .jar.
For example :
<!-- Properties -->
<property name="lib" value="lib/" />
<property name="classes" value="bin/" />
<!-- Classpath definition -->
<path id="runtime-classpath" >
<pathelement location="${bin}" />
<fileset dir="${lib}">
<include name="*.jar"/>
</fileset>
</path>
<!-- Taskdefs definitions -->
<taskdef name="myTask" classname="org.stackoverflow.tasks.MyTask" classpathref="runtime-classpath" />
<!-- Tasks -->
<target name="test" description="Test Action">
<myTask parameter1="value" />
</target>

Resources