Sonatype Blog

Abstraction-Addicted Ant

I've been staring at quite a few Ant scripts lately, trying to find patterns that I can convert to Maven plugin configurations. The one thing that stands out apart from the general gunkiness of Ant scripts is that Ant - at least in its older versions - forces you to the extremes of abstraction for the sake of reuse.

Reuse in [legacy] Ant seems to be all about one of two approaches: using XML entities to "import" script snippets directly into your build, and calling Ant scripts from other Ant scripts. The former looks a lot like the JSP @include directive, where the scripts importing these fragments have to have a similar property structure and such if you want the resulting script to be sane. The latter forces you to enumerate exactly which properties you will push down to the delegate script, and which ones you'll extract once it's done its thing. All of this makes for a true nightmare, if you need to trace and learn a build script. Properties magically appear in some places, and are defined with no apparent purpose in others. Oh, and the names of these properties? They get boiled down the the least-common-denominator of meaning, so their names no longer give any clear indication of what they're for or where they're defined/used.

I'd honestly forgotten about this aspect of Ant. I know some will argue that the newer versions allow macros and such that avoid the need for magic/useless (depending on which way you look at them) properties. But the hard fact is there are millions of lines of legacy Ant script out there, and much of it doesn't take full advantage of such elegant features. And, since I am doing a conversion here, why not convert to a system where the "macros" are binary artifacts maintained by a community, and where the entire configuration for the build is distilled into a single, easy-to-read file that's (at least, usually) unpolluted with build commands? Why go on using ad-hoc measures to stitch together builds that are in themselves patchwork quilts consisting of numerous factored-out build-script snippets with a system that would seem to have no consistent, standard mechanism for accessing them in a distributed environment?

The consequences of such an environment are plain, and have been realized by many people. I've heard it referred to as the Inner Platform Effect, where you now have an entire software platform for running builds, and it needs the same care and feeding - maintenance, testing, architecture - that your business software needs. This is where Maven shines, because it provides a standard access mechanism to plenty of binary, third-party plugins that are (at least to some extent) tested. This means that, instead of importing or delegating to another script or macro in your build script, you supply only high-level configuration for prefabricated, standard, binary build steps to consume. No code, just configuration.

Looking at this stuff again, I'm beginning to realize how cushy my life in Maven world has been.