Ant goodies : extracting info from Eclipse .classpath

IMPORTANT UPDATE: Please note that ‘antclipse’ is now part of the ant-contrib at Sourceforge, under Apache licence.

Original blogpost:

I hate duplicating information manually – besides, it’s a known fact that duplication is classic code smell that tells you to refactor. This time it’s not Java code, but something somewhat different : Ant used in Eclipse context. The issue here is that .classpath files generated by Eclipse have important information which is usually duplicated by hand in the build.xml script. SO many times I’ve changed libraries in my project in Eclipse just to discover that Ant task was broken…

There surely are some workarounds like the task written by Tom Davies but unfortunately:

- It’s an Eclipse plugin. I want to be able to build my project standalone, we don’t need no stinkin’ plugin. - I’s rather old and with a Nazi style checking of tags so it pukes on my 3.0M3 complaining about a certain attribute of type “con” in the .classpath file (lesson learned: don’t be picky about tags and attributes names, if you want the plugin to work with future versions of the software which produced the XML document, especially when you do not have a schema or DTD to rely on) - It’s Friday evening, dark weather outside, I’m alone in the house and the TV is broken (and even if it worked, there’s nothing to see on TV anyway). Boys and girls, let’s write an Ant task !

From the documentation, it appears that writing an Ant task should be an easy task :) . And yes, it is, once you go past all the little idiosyncracies. Like mandatory “to” string in a RegexpPatternMapper, although all you want to do is matching, not replacing. Like having completely different mechanisms for Path and FileSet (I’ve always thought a Path is a “dumbed down” FileSet, but I was completely wrong, a fileset is somewhat “smarter” but it only has a single directory).

The result is here, and everything you have to do is to download and put the antclipse.jar (7kB) in your ant/lib library and you’re set (just remember to refresh Ant classpath if you’re launching Ant from Eclipse).

What does it do ? Well, it creates classpaths or filesets based on your current .classpath file generated by Eclipse, according to the following parameters :

Attribute

Description

Required

produce

This parameter tells the task wether to produce a “classpath” or a “fileset” (multiple filesets, as a matter of fact).

Yes

idcontainer

The refid which will serve to identify the deliverables. When multiple filesets are produces, their refid is a concatenation between this value and something else (usually obtained from a path). Default “antclipse”

No

includelibs

Boolean, whether to include or not the project libraries. Default is true.

No

includesource

Boolean, whether to include or not the project source directories. Default is false.

No

includeoutput

Boolean, whether to include or not the project output directories. Default is false.

No

verbose

Boolean, telling the app to throw some info during each step. Default is false.

No

includes

A regexp for files to include. It is taken into account only when producing a classpath, doesn’t work on source or output files. It is a real regexp, not a “*” expression.

No

excludes

A regexp for files to exclude. It is taken into account only when producing a classpath, doesn’t work on source or output files. It is a real regexp, not a “*” expression.

No

Classpath creation is simple, it just produces a classpath that you can subsequently retrieve by its refid. The filesets are a little trickier, because the task is producing a fileset per directory in the case of sources and another separate fileset for the output file. Which is not necessarily bad, since the content of each directory usually serves a different purpose. Now, in order to avoit conflicting refids each fileset has a name composed by the idcontainer, followed by a dash and postfixed by the path. Supposing that your output path is bin/classes and the idcontainer is default, the task will create a fileset with refid antclipse-bin/classes. The fileset will include all the files contained in your output directory, but without the trailing path bin/classes (as you usually strip it when creating the distribution jar). If you have two source directories, called src and test, you’ll be provided with two filesets, with refids like antclipse-src and antclipse-test.

However, you don’t have to code manually the path since some properties are created as a “byproduct” each time you execute the task. Their name is idref postfixed by “outpath” and “srcpath” (in the case of the source, you’ll find the location of the first source directory).

A pretty self-explanatory Ant script follows (“xml” is a forbidden file type on jroller, so just copy paste it into your favourite text editor). Note that nothing is hardcoded, it’s an adaptable Ant script which should work in any Eclipse project.

Created with Colorer-take5 Library. Type ‘ant’<?xml version=”1.0”?> The newly created classpath is ${cpcontent}

TODOS : make “includes” and “excludes” to work on the source and output filesets, find an elegant solution to this multiple fileset/directories issues, and most important make it work with files referenced in other projects.

I am aware that the task is very far from being perfect, so just download it if you’re interested, try to use it, try to break it, and tell me what you think and how it can be improved. Also, if you’re interested in the source, just send me an email, but be aware that it’s Friday evening beer-induced source code, nothing to be proud of… It was only tested it with Ant 1.5.x so YMMV. I assume no responsibility if you use it a production environment.

Comments

Tags