Efficient Creation of Eclipse Modules with Maven Archetype
Maven Archetype is a project templating toolkit that provides developers with the means to generate parameterized versions of built-in or custom scaffolding artefacts. Recently I applied it to our Xiliary P2 repository to achieve automation of Eclipse module stubs creation.
As it worked out well enough, I thought it might be worth while to share my experiences in this post.
Maven Archetype
Maven Archetype allows programmers to setup scaffolding quickly and consistent with respect to conventions and best practices prescribed by a project or organization. It comes with set of predefined templates to ease generation of commonly used structures.
For a list of default archetypes provided by Maven please refer to Introduction to Archetypes, section Provided Archetypes.
Generation of a web-app project stub for example can be based on the archetype maven-archetype-webapp:
mvn archetype:generate \ -DgroupId=com.codeaffine \ -DartifactId=com.codeaffine.webapp \ -Dversion=1.0-SNAPSHOT \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DarchetypeArtifactId=maven-archetype-webapp \ -DarchetypeVersion=1.0 \ -DinteractiveMode=false
The parameters groupId, artifactId and version are used to create a project root folder containing an appropriate configured project object model definition (pom.xml
). Whereas the archetypeXXX
arguments specify which template to employ. Based on the web-app archetype Maven provides a pom that sets the build lifecycle packaging
attribute to war
and produces the following directory and file structure:
com.codeaffine.webapp |-- pom.xml `-- src `-- main |-- resources `-- webapp |-- WEB-INF | `-- web.xml `-- index.jsp
If you happen to work with the Maven Integration for Eclipse you can select the New Project wizard for Maven projects to generate an eclipse project derived from a particular archetype:
The selection shown by the image creates the same structure as in the command line example above. Additionally it provides Eclipse project specific files and settings and imports the generated project automatically into the workspace of the IDE.
Custom Archetype Creation
While the predefined templates are good for a quick-start, they are obviously not sufficient to employ project or organization specific conventions. The Eclipse IDE for example allows to configure all kind of settings in files located within the generated scaffolding structure. Hence it would be helpful to include such presets in a custom archetype.
Luckily Maven Archetype facilitates the creation of custom template definitions as explained in the online documentation Guide to Creating Archetypes. However instead of building up the archetype from scratch, I found it more efficient to use the create-from-project option as described by Dirk Reinemann.
I was able to do this because I already had a couple of Eclipse plug-ins, fragments and features I could use as prototypes.
I found a tycho-eclipse-plugin-archetype definition at GitHub providing a template for generating eclipse modules with test fragments and repository site in one step, which seems to provide a good quick start for eclipse plug-in development.
Create from Project
To create a Maven Archetype from a given project copy it to a working directory and remove all files that should not go into the archetype package. This project torso now provides all the files and the directory structure that make up the scaffolding.
Ensure that the root folder of the torso also contains a simple pom.xml
as explained in step one of the Guide to Creating Archetypes. After that navigate to the folder where the pom resides and execute the following command:
mvn archetype:create-from-project
This generates the archetype development structure stored in the subfolder target/generated-sources/archetype
. It contains a pom for the new archetype that is derived from the one which was placed in the root folder of the project torso. Furthermore there is a sub path src/main/resources/archetype-resources
that contains a copy of the scaffolding structure and resources.
The file src/main/resources/META-INF/maven/archetype-metadata.xml
is the ArchetypeDescriptor, which lists all the files that will be contained in newly created template and categorizes them, so they can be processed correctly by the generation mechanism.
Now it is possible to package the archetype and give it a first try to see if it works as expected so far. To do so navigate to the folder where the archetype’s pom resides and run:
mvn install
This makes the archetype available in your local repository. Using it for the first time is as easy as in the web-app example above and should look somewhat like the following snippet:
mvn archetype:generate \ -DarchetypeArtifactId=foo.artefactId \ -DarchetypeGroupId=foo.groupId \ -DarchetypeVersion=foo.version
If done properly Maven should now have created a project stub that basically looks the same as the one composed in the the project torso.
Adjustments
Unfortunately there is still more work to do. Eclipse plug-ins, fragments and features provide their own meta descriptors containing identifiers, version numbers, names and the like. And of course we expect those values to be reasonably prepopulated by the template processor.
Maven Archetypes handles this with properties which can be declared in the ArchetypeDescriptor (see above).
<requiredProperties> <requiredProperty key="identifier"></requiredProperty> </requiredProperties>
Now you can refer to this property in arbitrary resources of the archetype using the following syntax:
[...] Bundle-SymbolicName: ${identifier} [...]
Initialization of the property can be done by setting it as system parameter of the command line for example:
mvn archetype:generate \ -DarchetypeArtifactId=foo.artefactId \ -DarchetypeGroupId=foo.groupId \ -DarchetypeVersion=foo.version \ -Didentifier=foo.identifier \
Another problem for plug-ins and fragments is e.g. the empty or non existing source folder referred to by the .project
definition file. Maven ignores empty directories during template processing. But the following snippet shows how to configure the descriptor to create such a folders nevertheless:
<fileSets> <fileSet filtered="true" encoding="UTF-8"> <directory>src</directory> <includes> <include>**/*.java</include> </includes> </fileSet> [...]
For more details on descriptor configuration please refer to the online documentation.
Assembling the Pieces
Given this knowledge I was able to create Maven Archetype artefacts for plug-in, test fragment and feature definition stubs that match the Xiliary development presets. This means each stub comes with the specific settings for codeformatting, execution environment, compile error/warning preferences and the like out of the box.
For flexibility reasons I decided to go with three individual artefacts instead of one and wired them together using a little script. This is because most of the time I need to create all three stubs in one step. Although this renders the Eclipse New Project wizard unusable, it is not a big deal as the only benefit would be the automatic workspace import of the stubs.
The only manual tasks left are the registration of the new modules in the parent pom of the repository’s build definition and the addition af a new feature entry in the P2 related catagory.xml
.
Conclusion
This post gave an short introduction to Maven Archetype and showed how it can be used to automate Eclipse module creation. With the custom archetypes described above in place, it now takes about a minute to add a new feature definition with plug-in and test fragment to the workspace and build definition.
And being development and build ready within a minute isn’t that bad compared to the previous manual create, configure, copy and paste litany… So you want to have look at the archetype sources by yourself, the definitions are located in the com.codeaffine.xiliary.archetype
project of the Xiliary repository at GitHub.
Reference: | Efficient Creation of Eclipse Modules with Maven Archetype from our JCG partner Frank Appel at the Code Affine blog. |