The genesis for this new maven2 plugin grew out of the work my team mate, Kohsuke, has been doing in building release distro files for glassfish v3. He found that the maven-assembly-plugin was too inflexible to handle the complex set of tasks needed to create the glassfish nucleus, pe and other distribution bundle files. The assembly plugin tries to recreate what Ant already does well: zipping and unzipping files, moving files around, doing token replacement and so on. In other words, task-intensive requests. Also, the assembly plugin requires a declarative approach that ends up producing a large, single file of instructions. This can be harder to sustain than a modular collection of Ant build.xml files.
Instead of this approach, we considered using maven as an organizing framework that delegates all the subtasks to one or more Ant targets. Now, there is already a maven-antrun-plugin available, but it did not have all the features we needed:
- The plugin must have the ability to expose an API to an Ant task for resolving artifact dependencies.
- The plugin must also expose to resolve all artifact dependencies, including transitive ones.
- It must also be able to resolve dependency using just the artifactId.
- It must also be able to filter resolved dependencies.
The first two requirements enable an Ant task class to obtain a reference to an artifact. The third requirement means that the majority of the metadata to uniquely identify an artifact is in the pom.xml file. This minimizes redundant data that is needed in the Ant's build.xml file. These requirements were implemented in a maven-antrun-extended-plugin.
An example will help illustrate these ideas. Look at this line in the gfsvn/v3/distributions/nucleus-base/build.xml file:
<resolveArtifact artifactId="javadb" property="javadb.jar"/>
The task is basically asking "get me the artifact with id 'javadb' and store it as an Ant property with name javadb.jar". Under the covers, the ResolveArtifactTask class obtains a reference an ArtifactResolverWrapper class from the maven-antrun-extended-plugin using a ThreadLocal variable. The ResolveArtifactTask class then passes the artifactId to the Wrapper which resolves the dependency by reading the pom.xml file and by then using a maven ArtifactResolver. If no unique artifact is found, an IOException is thrown by the Wrapper. The ResolveArtifactTask then saves the artifact's file path as an Ant property. This property can then be used by other Ant tasks such as:
<unjar src="${javadb.jar}" dest="target"/>
There is also a second Ant task that is not currently used. Use case: let's say you need to find all dependencies, including transient ones, and save them in an Ant data structure for processing by other Ant tasks. Let's also say that you need to find only these artifacts that have packaging type "hk2-jar". The following set of tags will accomplish this:
<resolveAll artifactId="web-connector" pathId="artifactPath">
<packaging is="hk2-jar"/>
</resolveAll>
Since the above task has not yet been used, more testing is needed. Nonetheless, consider this a start at understanding its usage.
Well, that's it for an introduction. I do realize that this is not the 'standard' way of assembling a distro file using maven. So, consider this project as an alternative approach. Please try it and let me know what you think.
Until next time...