I have a need to change our current ant based build system from a single 
monolithic build in which all utilities are part of the source tree of the 
webapp currently under development into several component builds.  This way 
other web applications can share the same exact utilities, or more specifically 
version X of each desired internal utility.  To my knowledge there is no 
combination of existing ant tasks (other than my custom task) that solve all of 
the problems involved in a nice clean manner.  Furthermore, I suspect most 
every large company using ant with multiple teams will eventually encounter the 
same problem set.

Componentizing the build solves the problem of sharing common libraries between 
development teams.  Unfortunately doing so also often causes the following 
problems:
1) Some teams will inevitable end up using rather outdated versions of a shared 
internal library.
2) Without an overall build system extending a utility can be rather cumbersome.

The general solution to potential problem 1 is to somehow increase the 
visibility of a particular team's use of an outdated version.  If upgrading to 
a new version is easy enough (i.e. just edit a property file) and a team is 
constantly reminded they are using an older version, they will likely tend to 
stay up to date.  Ideally the fact the team's code is using an old version will 
be reported by any continuous integration environment (i.e. cruise-control).

Potential problem 2 is referring to the typical scenario in which one is 
developing client code (a web application) to the internal utility when one 
discovers the utility isn't adequate.  In practice one is then often forced to 
make changes to the utility, release a new version of the utility, configure 
the client application to use the new version of the utility, see if the client 
application's need has been satisfied and if not repeat the above steps.  To 
alleviate such tediousness one obviously tries to construct an overall build 
environment that can compile/test/distribute the utility and then do the same 
for the client application.  In the event one is using such an overall build 
the utility distribution that is created is simply a temporary one and probably 
shouldn't represent an internal release.  (When one completes extending the 
utility one will most likely want to create an internal release.)

I found it very difficult to use the existing ant tasks to write an ant build 
system that componentized the build system yet still addressed potential 
problems 1 and 2.  To that end I wrote a custom ant task that searches for each 
desired utility and sets a class path reference with the results.  The task 
first searches an area intended for active build artifacts and failing that 
looks for the desired release version in a specified directory.  If a release 
version is being used, the task reports at warning level if a newer version 
exists.  If an active build artifact is being used for a particular utility 
then the task reports the fact at an info level.  As well as the above 
information, boundary cases indicating something is misconfigured result in 
BuildExceptions being thrown.

The custom task only implements the missing functionality.  It is still 
expected the user will use the existing ant tasks to complete his/her overall 
build environment.

Although only lightly documented the task is very thoroughly unit tested using 
the Ant extensions to junit.

The task is currently adequate for my needs and I do not have the time to 
submit it as a formal ant task.  That said it would be in my employer's best 
interest to have the ant team integrate it in as an official ant task (or just 
a related project).  To that end I believe I can get a formal legal release of 
the code under an open-source license if there is any interest.  The task is 
useful in its current form (after someone writes a bit more documentation) but 
could be made even more general than it is.

In case your wondering, I am intending to store our internal utility releases 
in CVS in the same directory structure as expected by the custom ant task.  
This will work fine for now, but at some future point may need to be done 
differently.

The class level javadoc is copied below:
/**
 * This ant task is intended to be used in determining
 * where to acquire jar files for a given internal
 * subproject.
 *
 * The search algorithm is as follows:
 *
 * Foreach subproject look in
 * activebuildlibdir for a subproject.category
 * directory.  If found look for any jars there
 * and add them to the path list.
 * If unsuccessful then look in
 * releasedir/subproject.category/subproject.desiredversion
 * If nothing is found, get mad and throw a BuildException.
 * If something is found see if the desired version
 * is the most current version available
 * in the releasedir/subproject.category directory.
 * If you have trouble parsing the name
 * of any subdirectory found
 * in releasedir/subproject.category throw a BuildException.
 * If the desired version is out of date
 * log it at warning level.
 *
 * An example usage is shown below:
 *      <property name="subproject.lib.dir" 
value="../subprojectactivebuildlib"/>
 *      <property name="release.dir" value="../internaltools"/>
 *      <property name="internal.core.category" value="core"/>
 *      <property name="internal.core.desiredversion" value="1_0_1"/>
 *      <property name="internal.db.category" value="db"/>
 *      <property name="internal.db.desiredversion" value="2_4_1"/>
 *
 *      <!--After the below target's execution the subproject.classpath
 *      can be used as a refid for the classpath argument of the javac
 *      ant task -->
 *      <target name="determine.subproject.classpaths">
 *      <findsubprojects
 *          classpathid="subproject.classpath"
 *          activebuildlibdir="${subproject.lib.dir}"
 *          releaselibdir="${release.dir}">
 *           <subproject
 *               category="${internal.core.category}"
 *               desiredversion="${internal.core.desiredversion}"/>
 *           <subproject
 *               category="${internal.db.category}"
 *               desiredversion="${internal.db.desiredversion}"/>
 *      </findsubprojects>
 *
 *      </target>
 *
 */

Please let me know if you, the reader, are interested in more.  (If you post 
back to the mailing list, please send me an email as anything from the ant-dev 
mailing list is automatically shuttled to its own directory and only 
occasionally read.)

James Carpenter
[EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to