Organizing Archetypes

Wilfred Springer

Maven archetypes are an excellent way of allowing people to create instances of a particular type of project without having them to know or worry about all of the peculiarities and details. (And the latest incarnations of the Maven Archtetype Plugin are actually way better than I realized: somewhere down the line, they introduced the ability to use Velocity templates for parameterizing the output. Nice!)

Since some of the dependencies of Preon are not in the central Maven repository yet, I decided to create an archetype of a Maven project, to make sure all of the external repositories are set correctly and preventing you from worrying about it. But then the question is: how do you keep all your archetypes organized? Generating a project from an archetype is pretty easy nowadays, but either the archetypes should be present on your user's system, or they should specify the location of a catalog file. However, that catalog file will have references to the version of your archetypes. How do you make sure these versions are correct? And how do you make sure your archetype catalog is available online, without having to manually deploy it over and over again?

I couldn't find a real policy for managing all of this, so here is what I did:

Organizing Archetypes

Module for Archetypes

First of all, I decided to have a module for all of my archetypes, as outlined in the picture above. Having a dedicated module that organizes all of my archetypes allows me to set specific policies for my archetypes, and it also allows me to keep my catalog file in a sensible location. (The catalog has references to all of the individual archetypes.)

Parameterized archetype-catalog.xml file

Now, I want my catalog of archetypes to have references to relevant versions of the archetypes. One way to get there is to carefully update the file by hand once a new version of the archetype is available. But that's also quite boring, and error-prone. So, what I did instead is keep the archetype-catalog.xml file in src/main/resources, and make sure the Maven Resources Plugin is kicking in to substitute variable references with relevant values.

<archetype-catalog>
  <archetypes>
    <archetype>
      <groupId>nl.flotsam.preon.archetypes</groupId>
      <artifactId>preon-simple-archetype</artifactId>
      <version>${project.version}</version>
      <repository>http://preon.flotsam.nl/archetypes</repository>
      <description>Simple Preon project, with dependencies to everything required.</description>
    </archetype>
  </archetypes>
</archetype-catalog>

Attaching catalog files

So, now we have catalog files that have correct version references, but it's still impossible to download them from a certain location. I started wondering about a solution, and first considered having them included as site resources. But then I realized I could also attach these files as new artifacts. That has a couple of interesting side effects, one of them being that they will also get uploaded to the Maven repository with every new deployment of my project. Just what I wanted. So, by adding a little configuration, I made sure the files were getting attached.

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>build-helper-maven-plugin</artifactId>
  <version>1.3</version>
  <inherited>false</inherited>
  <executions>
    <execution>
      <id>attach-artifacts</id>
      <phase>package</phase>
      <goals>
        <goal>attach-artifact</goal>
      </goals>
      <configuration>
        <artifacts>
          <artifact>
            <file>target/classes/archetype-catalog.xml</file>
            <type>xml</type>
            <classifier>catalog</classifier>
          </artifact>
        </artifacts>
      </configuration>
    </execution>
  </executions>
</plugin>

Panic: SNAPSHOT versions!

So far, everything works pretty smooth. But then a problem turns up: if you attach files, and you deploy them to a snapshot repository, then the version numbers will get a suffix making the version number unique for that particular build. That works fine with the usual artifacts, but not with the Maven Archetype Plugin. Remember that - although the archetype-catalog.xml file now has versions correctly generated by the Maven Resources Plugin - it will still have version references without the unique build suffix. However, the Maven Deploy Plugin will upload versions that include the unique build suffix.

In order to solve that, I replaced the distributionManagement section in the pom.xml file of the preon-archetypes module, and made sure that - for snapshotRepository settings - the uniqueVersion is set to false. This will drop the unique suffix. However, it will also mess up your snapshot repository. In order to keep it tidy, the archetypes are deployed to a dedicated repository: the archetypes repository.

Done?

With all of this work done, creating a project from one of the archetypes is pretty easy:

mvn -DarchetypeCatalog=http://preon.flotsam.nl/archetypes/nl/flotsam/preon/archetypes/preon-archetypes/1.1-SNAPSHOT/preon-archetypes-1.1-SNAPSHOT-catalog.xml archetype:generate

That's it. After that, you will able to select the specific archetype you want to instantiate, and Maven takes care of the rest.

Comments (0)

    Add a Comment