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.
Technorati Tags: ant, maven, conversion
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.
Technorati Tags: ant, maven, conversion
HOW-TO: Merge sub-items from parent POM to child POM in a Maven plugin configuration
Cross-Posted from my buildchimp blog: I just ran into a bug report about this, so I thought it might be a good idea to post about it. The bug report detailed a case where the following configurations were not being merged correctly: Parent POM: configuration items itemone/item itemtwo/item /items /configuration Child POM: configuration items itemthree/item /items /configuration Expected result, according to MNG-2591: configuration items itemone/item itemtwo/item itemthree/item /items /configuration By default, Maven would simply replace the parent's items sub-elements with those from the child, resulting in only one item: three. This is mainly because Maven treats all plugin configuration as XML DOM content, without any idea of what makes up a list of related items, and what is just complex configuration. Moreover, sometimes you want to override the entire list instead of merely appending to it…it's a difficult balance to strike. However, Maven …
HOW-TO: Merge sub-items from parent POM to child POM in a Maven plugin configuration
Cross-Posted from my buildchimp blog:
I just ran into a bug report about this, so I thought it might be a good idea to post about it. The bug report detailed a case where the following configurations were not being merged correctly:
Parent POM:
<configuration>
<items>
<item>one</item>
<item>two</item>
</items>
</configuration>
Child POM:
<configuration>
<items>
<item>three</item>
</items>
</configuration>
Expected result, according to MNG-2591:
<configuration>
<items>
<item>one</item>
<item>two</item>
<item>three</item>
</items>
</configuration>
By default, Maven would simply replace the parent’s <items> sub-elements with those from the child, resulting in only one item: three. This is mainly because Maven treats all plugin configuration as XML DOM content, without any idea of what makes up a list of related items, and what is just complex configuration. Moreover, sometimes you want to override the entire list instead of merely appending to it…it’s a difficult balance to strike. However, Maven does support a special attribute to control this behavior. Using the combine.children attribute with a value of append, you can tell Maven to treat the sub-items as a list, and combine them into a single, larger list during inheritance calculations.
As of Revision 545315 in Maven’s Subversion repository (in the latest trunk), things have changed subtly in this functionality, to render a more consistent and intuitive result. Given the same parent POM from above, and this child POM:
<configuration>
<items combine.children="append">
<item>three</item>
</items>
</configuration>
Maven versions prior to this new revision will render the following configuration:
<configuration>
<items>
<item>three</item>
<item>one</item>
<item>two</item>
</items>
</configuration>
…while the newest revision in Maven’s SVN repository will render this configuration:
<configuration>
<items>
<item>one</item>
<item>two</item>
<item>three</item>
</items>
</configuration>
Admittedly, this is a fairly arcane configuration trick. Hopefully, during the course of our 2.1.x work, we can find a simpler way to change configuration-merging behavior for plugins in Maven’s POM.