ANT - Converting a String to Path with location attribute - ant

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

Related

Ant and yuicompressor

I am trying to integrate yuicompressor with Ant to automate the minification of our CSS and JS files. However, I keep getting the following error message when I try to run build.xml:
BUILD FAILED
/Applications/MAMP/htdocs/zanadu-dev/build/build.xml:64: taskdef A class needed by class com.yahoo.platform.yui.compressor.YUICompressTask cannot be found: org/mozilla/javascript/EvaluatorException
using the classloader AntClassLoader[/usr/share/ant/lib/YUIAnt.jar:/usr/share/ant/lib/yuicompressor-2.4.6/build/yuicompressor-2.4.6.jar:/usr/share/ant/lib/yuicompressor-2.4.6/lib/rhino-1.6R7.jar]
Here is the code in my build.xml file:
<target name="minify" depends="build" description="Minifiy CSS and JS files">
<available file="${antlib.dir}/YUIAnt.jar" property="YUIANT_AVAILABLE" />
<fail unless="YUIANT_AVAILABLE" message="YUIAnt.jar not found" />
<taskdef name="yuicompress" classname="com.yahoo.platform.yui.compressor.YUICompressTask">
<classpath>
<pathelement path="${antlib.dir}/YUIAnt.jar" />
<pathelement path="${antlib.dir}/yuicompressor-2.4.6/build/yuicompressor-2.4.6.jar" />
<pathelement path="${antlib.dir}/yuicompressor-2.4.6/lib/rhino-1.6R7.jar" />
</classpath>
</taskdef>
<mkdir dir="${jsminify.dir}" />
<yuicompress linebreak="300" warn="false" munge="yes" preserveallsemicolons="true"
outputfolder="${jsmin.dir}">
<fileset dir="${js.dir}" >
<include name="**/*.js" />
</fileset>
</yuicompress>
<mkdir dir="${cssminify.dir}" />
<yuicompress linebreak="300" warn="false" munge="yes" preserveallsemicolons="true"
outputfolder="${cssmin.dir}">
<fileset dir="${css.dir}" >
<include name="**/*.css" />
</fileset>
</yuicompress>
</target>
I have tried following several online examples on this, but all seem to yield the same error message. Not sure exactly where I can find the EvaluatorException class that seems to be missing.
Any idea what I may be doing wrong?
Cheers!
Your taskdef is missing one lib.
<taskdef name="yuicompress" classname="com.yahoo.platform.yui.compressor.YUICompressTask">
<classpath>
<pathelement path="${antlib.dir}/YUIAnt.jar" />
<pathelement path="${antlib.dir}/yuicompressor-2.4.6.jar" />
<pathelement path="${antlib.dir}/rhino-1.6R7.jar" />
</classpath>
</taskdef>
EDIT:,
The problem is somehow related to the jar locations and Ant's class-loader, see this post
One workaround is to copy YUIAnt.jar, yuicompressor-2.4.6.jar and rhino-1.6R7.jar to one directory. Then use it like above. I've tried and it works.
if you use http://code.google.com/p/yui-compressor-ant-task/ for me solution was to use classname="net.noha.tools.ant.yuicompressor.tasks.YuiCompressorTask" instead of classname="com.yahoo.platform.yui.compressor.YUICompressTask"

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>

Get list of files from URL

I'll like to automate somehow keeping my Netbeans Daily build with what's available.
Basically is as follows:
Get file list from http://bits.netbeans.org/download/trunk/nightly/latest/zip/
Download file (let's say I'm interested in the java.zip)
Unzip
I have an ant script capable of doing 2 and 3. I need to figure out how to do the first. See below:
<?xml version="1.0" encoding="UTF-8"?>
<project name="Netbeans Daily Build" basedir=".">
<description>Updates the daily build</description>
<property name="zip.name" value="netbeans-6.9.1-201007282301-ml-javase.zip"/>
<property name="dist" value="Z:/Program Files/Netbeans 7.0/"/>
<property name="zip.url" value="http://bits.netbeans.org/download/trunk/nightly/latest/zip/"/>
<fileset id="ant-contrib-jar" dir="./">
<include name="ant-contrib-*.jar" />
</fileset>
<pathconvert property="ant-contrib-jar" refid="ant-contrib-jar" pathsep="," />
<basename property="ant-contrib-filename" file="${ant-contrib-jar}"/>
<property name="ant-contrib-loc" value="./${ant-contrib-filename}"/>
<available file="${ant-contrib-loc}" property="ant-contrib.present"/>
<fail unless="ant-contrib.present" message="The ant-contrib jar doesn't exist at: ${ant-contrib-loc}, can't build. Check your settings!" />
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="${ant-contrib-loc}"/>
</classpath>
</taskdef>
<!--Delete old copies of platforms-->
<delete>
<fileset dir="${dist}" includes="**/*.zip" excludes="${zip.name}"/>
</delete>
<available file="${zip.url}${zip.name}" property="file.exists"/>
<if>
<not>
<isset property="file.exists"/>
</not>
<then>
<get src="${zip.url}${zip.name}" dest="./" skipexisting="true" verbose="true"/>
<!--Only overwrite if newer
<unzip src="${dist}/${zip.name}" dest="${dist}" overwrite="false"/>-->
</then>
</if>
</project>
I need to somehow figure out the correct file name to download.
Doing everything in a batch file (without ant) is acceptable as well.
Thanks in advance!
How about you just check out the latest version using mercurial? This should tell you how: http://netbeans.org/community/sources/hg.html
Looks like there's a project for this. Looks like I'll be joining the team...
http://kenai.com/projects/nb-nightly-updater

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>

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

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.

Resources