What are the custom targets you all run when using ant to build project? - ant

I am thinking of running this custom targets to find out more about my project build status
- jalopy
- jdepend
- cvs tagdiff report
- custom task for NoUnit
- generate UML diagram. ESS-Model
What are your views?

I think that it's a great idea and use it myself. That way I'll never forget to run it.
I also keep the reports for a decent amount of time and eventually create a spreadsheet of "progress".
In your main ant task - call another task to do "whatever"
and
JDepend.xml ...
<target name="statsAll">
<!-- master file that describes where everything is -->
<property file="./ant/ant-global.properties" prefix="ant-global" />
<tstamp>
<format property="gen.time" pattern="yyyyMMdd_hh"/>
</tstamp>
<echo message="LOG:./ant/logs/jdepend.${version.FILETAG}.${gen.time}.rpt"/>
<!-- generate stats to see if we're improving -->
<jdepend
outputfile="./ant/logs/jdepend.${version.FILETAG}.${gen.time}.rpt" >
<exclude name="java.*"/>
<exclude name="javax.*"/>
<classespath>
<pathelement location="./jar" />
</classespath>
<classpath location="./jar" />
</jdepend>
</target>
<target name="doJDepend" depends="getVersion,statsAll">
<echo message="FTP'ing report"/>
<ftp verbose="yes" passive="yes" depends="yes"
remotedir="/videojet/metrics" server="xxxxx"
userid="xxxx" password="xxxxx"
binary="no"
systemTypeKey="UNIX">
<fileset dir="./ant/logs/" casesensitive="no">
<include name="**/jdepend.${version.FILETAG}*.rpt"/>
<exclude name="**/*.txt"/>
</fileset>
</ftp>
</target>
Magic build machine

I second the 'good idea' part, although for a project of reasonable size you might want to make it part of an automated build, like one of the CI Servers (Bamboo, Contiuum).
You might also consider a code coverage tool to see how your test coverage is going.
This will ensure the reports get run on a regular basis, could give you somewhere to publish them and won't slow down the developer's quick turnaround development cycle.

I also think some reports about your project are a good idea. My template-project for an ant-build-script (Antiplate) has at the moment the following reports: Junitreport, emma-report, PMD, CPD and Checkstyle. I'm thinking about including a JDepend-report.
At work we use these templates and using Hudson as continuous-integration-system. Hudson creates wonderful graphs for these reports and how the measures changed with the builds.

Related

In ant, how does one create and use a 'library' of targets?

To eliminate redundancy in my ant build.xml files, I decided out-factor the repeated targets into mytargets.xml file, publish it to to the artifact repository, and then import it in the following way:
<import>
<url url="http://mycompany.com/artifacts/mycompany.com/mytargets/1.2.3/mytargets-1.2.3.xml"/>
</import>
There are two things I don't like about this approach:
mytargets-1.2.3.xml never appears anywhere on the disk where I can easily look at it.
I absolutely need access to http://mycompany.com/artifacts in order to do anything in the project---it completely undermines offline work.
So, I tried creating a setup target to fetch a local copy of mytargets.xml and adjusted my <import> to use this local copy.
<import file="${basedir}/antlib/mytargets/mytargets.xml"/>
However, as you have probably guessed, I cannot even execute my setup my target after adjusting my <import> in this way because the file does not yet exist:
Buildfile: /home/me/myproject/build.xml
BUILD FAILED
/home/me/myproject/build.xml:265: Cannot find /home/me/myproject/antlib/mytargets/mytargets.xml imported from /home/me/myproject/build.xml
Adding optional="true" to the <import> only defers the problem to the first target that depends upon mytargets.xml.
I looked at https://ant.apache.org/manual/Types/antlib.html, but this approach does not appears to permit you to define a <target>.
So, how does someone share bits of ant XML across multiple projects? Am I already doing it the 'one true way'? Or, is there a better way?
If you're mainly just trying to avoid download the remote copy when you have a local copy already available, you can try something like this:
<condition property="mytargets.xml.available">
<available file="${basedir}/antlib/mytargets/mytargets.xml" />
</condition>
<target name="setup" unless="mytargets.xml.available">
<get
src="http://mycompany.com/artifacts/mycompany.com/mytargets/1.2.3/mytargets-1.2.3.xml"
dest="${basedir}/antlib/mytargets"
/>
</target>
<target name="main" depends="setup">
<import file="${basedir}/antlib/mytargets/mytargets.xml" />
...
</target>
So, it seems to me that <target> is inherently local and not intended for reuse. On the other hand, <macrodef> appears intended for reuse.
Here is the 'library', mymacros.xml:
<?xml version="1.0"?>
<antlib>
<macrodef name="mymacro">
...
</macrodef>
</antlib>
Here is the client, myproject/build.xml:
<?xml version="1.0"?>
<project name="myproject">
<target name="mytarget">
<mymacro/>
</target>
<taskdef file="mymacros.xml"/>
</project>
Unlike <import> and <include>, <taskdef> will not cause the build to fail immediately if mymacros.xml is missing, which gives you the opportunity to download it.

reorganize files inside a jar with ant

I am currently deploying an oracle adf project using ojdeploy. Unfortunately the packaging of the jar is not as it should be.
So I have images in the paths
lookAndFeel.jar/skins/lightsOff/images
lookAndFeel.jar/skins/lightsOn/images
which I need to merge with
lookAndFeel.jar/META-INF/adf/skins/lightsOff/images
lookAndFeel.jar/META-INF/adf/skins/lightsOn/images
Is there a way to do this with ant?
edit
I read Top 15 Ant Best Practices Point 13, where they state, that I should use zipfileset. But I was not able to do it that way, since my required files are already in the jar. The initial jar creation is done via ojdeploy therefor I don't have an influence on the initial structure of the jar.
I'm trying to understand what the issue is:
Did you create this jar?
Are you merging new data or moving it around?
As others have stated, you need to unjar, munge the results, and then jar it back up. No biggie:
<property name="target.dir" value="${basedir}/target"/>
<property name="work.dir" value="${target.dir}/work"/>
<property name="munge.dir" value="${work.dir}/munge"/>
<target name="munge.jar">
<unjar src="${jar.file}"
dest="${munge.dir}"/>
<here be dragons.../>
<delete file="${jar.file}"/>
<jar destfile="${jar.file}
basedir="${munge.dir}"/>
</target>
Not being 100% sure what you want, you'll have to fill out the <here be dragons.../> part. You'll move, rename, shuffle, delete, and add to your heart's content.
Another possibility is to use the <mapper/> sub-entity to reformat your jar as you unjar it.
<target name="munge.jar">
<unjar src="${jar.file}"
dest="${munge.dir}">
<mapper type="glob"
from="skins/**/*"
to="META-INF/adf/skins/**/*"/>
</unjar>
<delete file="${jar.file}"/>
<jar destfile="${jar.file}
basedir="${munge.dir}"/>
</target>
I haven't tested the above, but it'll give you an idea.

JaCoCo report looks correct but can not view source

I am new to JaCoCo and trying to figure out why the html report that I am generating is not linked with my source.
The coverage numbers look correct and I can browse down to each class and then each method but I can not see the source. I have tried many different things inside the sourcefiles tag but nothing is working. Has anyone else had this issue? Here is a snippet of my ant script:
...
<test name="test.fw.UITestSuite" todir="${logdir}"/>
</junit>
</jacoco:coverage>
<fail if="TestFailed" status="1" message="UI junit test failure detected"/>
<echo message="${src}"/>
<jacoco:report>
<executiondata>
<file file="jacoco.exec"/>
</executiondata>
<structure name="UI">
<classfiles>
<fileset dir="${build}/fw"/>
</classfiles>
<sourcefiles encoding="UTF-8">
<fileset dir="fw" includes="**./*.java"/>
</sourcefiles>
</structure>
<html destdir="report"/>
</jacoco:report>
</target>
...
Your fileset definition seems odd.
The include must be (the first . is misplaced):
includes="**/*.java
Try simply pointing it to the root of your src dir (there is no need for the includes)
<fileset dir="fw" />
But fw has to be the root of your sources, i.e. it contains the package folders like:
src
-org
-module
-MyClass1.java
-MyClass2.java
I’ve seen this break when using Scala-style package directory names, e.g.,
src/main/java/com.example.foo.bar/Foo.java
for fewer levels of nesting, faster autocompletion, &c., compared to the standard
src/main/java/com/example/foo/bar/Foo.java
Most tools support the first version just fine, but usually if you try it out and everything works fine, by the time you notice something like the jacoco reports not showing the source anymore, you’ve long forgotten the directory name change …

iajc and aspectpath

I'm a bit confused with the aspectpath option of the iajc compiler.
My project use AspectJ to weave metric code into an existing swing application.
All the application source are packaged this way:
com.xxx.yyy.myapp.*
We have put our aspect in a package inside the same project:
com.xxx.yyy.aop.*
The project is built with javac first and the outpout goes into ${classes.dir}.
Then we invoke iacj this way:
<iajc inpath="${classes.dir}"
destDir="${classes.dir}"
fork="true"
maxmem="${aspectj.maxmem}"
verbose="true"
showWeaveInfo="true"
debug="true"
source="1.6"
target="1.6">
<classpath refid="ajclasspath"/>
</iajc>
and
<path id="ajclasspath">
<path refid="classpath"/>
<pathelement location="${scm.home}/ant_libs/aspectjrt.jar"/>
</path>
With that said, do i need to specify an aspectpath in the iajc?
Regards
According to documentation similar to classpath, aspectpath contains read-only, binary aspect libraries that are woven into sources but not included in the output. In your case you include your aspects in output and they are in ${classes.dir} with normal classes.
So you don't have to specify aspectpath when you don't want to separate your aspects.

Is there an ANT task for watching a directory for changes?

It sounds a little far fetched to me, but is there an ANT task for watching a directory for changes and then running a particular ANT class when the directory changes?
If files can only be added to or changed in the watched directory, then you can use this simple OutOfDate task from antcontrib.
<property name="watched-dir.flagfile"
location="MUST be not in watched dir"/>
<outofdate>
<sourcefiles>
<fileset dir="watched-dir"/>
</sourcefiles>
<targetfiles>
<pathelement location="${watched-dir.flagfile}"/>
</targetfiles>
<sequential>
<!--Tasks when something changes go here-->
<touch file="${watched-dir.flagfile}"/>
</sequential>
</outofdate>
If files can disappear from the watched-dir, then you have more complicated problem, that you can solve by creating shadow directory structure of the watched dir and checking if its consistent with the watched-dir. This task is more complex, but I'll give you a script to create a shadow directory, as it is not straight forward:
<property name="TALK" value="true"/>
<property name="shadow-dir"
location="MUST be not in watched dir"/>
<touch
mkdirs="true"
verbose="${TALK}"
>
<fileset dir="watched-dir">
<patterns/>
<type type="file"/>
</fileset>
<!-- That's the tricky globmapper to make touch task work -->
<globmapper from="*" to="${shadow-dir}/*"/>
</touch>
<!--
Due to how touch task with mapped fileset is implemented, it
truncates file access times down to a milliseconds, so if you
would have used outofdate task on shadow dir it would always
show that something is out of date.
Because of that, touching all files in ${shadow-dir} again fixes
that chicken and egg problem.
-->
<touch verbose="${TALK}">
<fileset dir="${shadow-dir}"/>
</touch>
With shadow directory created, I'll leave the task of checking directory consistency as an exercise for the reader.
Yes there is an Ant Task that will do this:
https://github.com/chubbard/WatchTask
It requires 1.7+. It can watch any number of filesets, and invoke any target depending on which fileset it came from.
You might be able to use the Waitfor task to achieve what you want. It blocks until one or more conditions (such as the presence of a particular file) become true.
You can combine the apply task with a fileset selector
<apply executable="somecommand" parallel="false">
<srcfile/>
<fileset dir="${watch.dir}">
<modified/>
</fileset>
</apply>
The fileset will check the files against a stored MD5 checksum for changes. You'll need to put ANT into a loop in order to repeatedly run this check. this is easy to do in Unix:
while true
> do
> ant
> sleep 300
> done

Resources