Annoyances with the maven archetype plugin

Grumpy MavenFirst of all, I have to state that I’m quite fond of maven. I simply cannot imagine doing any Java enterprise software development without it and its ecosystem (Jenkins, Nexus, Sonar, etcetera.). Maven really is an invaluable tool. However, every once in a while I find that some of the basic plug-ins can prove to be a real source of headaches. E.g., I can’t recall the number of times that I cursed the release plug-in. But today the culprit turned out to be the archetype plug-in.

At the office we tend to create a lot of projects that are very similar and complex in layout and contain a lot of plumbing files, mostly spring configuration and some property files. Getting started with one of these projects can take up to a days worth of work. Therefore, I’ve wanted to create a maven archetype. So next time around, we can be up and running in a matter of minutes instead of hours.

So to get started creating my archetype I issued the command mvn archetype:create-from-project from an already existing project. This resulted in the basic set up for my archetype inside the target/generated-sources archetype folder. So after copying the archetype directory to a new location so it could serve as the basis for my new archetype, it now was time to fiddle with the details to get the archetype exactly as I wanted it to be. For the most part it was relatively smooth sailing. I did, however, run into some rather mind-boggling issues.

Required properties

In the maven archetype descriptor – archetype-metadata.xml – it is possible to define default values for the main properties groupId, artifactId, version, and package. It is also possible to define additional properties that will be used for the file generation. Since we wanted a default package and version number for our newly created projects, I decided to take advantage of using default values for my properties. So I went ahead and specified a defaultValue for the groupId and package, like such:

What I did find out was that if a default value is provided the user is never asked to enter the value. Leaving out the defaultValue from the piece of XML will result in the user always being asked to enter a value. But what I was looking for was a way of asking the user to enter a value or press the enter key to accept the suggested default value. In other words, I wanted the user to be able to override the default value. But alas, the archetype plug-in doesn’t provide for this scenario.

Empty folder

When using a template for a new project one would imagine the folder structure for the new project to be laid out – even if the folders are empty. So I imagined that defining a fileSet in the archetype descriptor pointing to my src/main/java folder for example, would suffice:

Unfortunately, the archetype plug-in only generates folders if they contain at least one file. For instance, suppose I’ve got a file called Example.java inside the folder src/main/java/com/mycompany/example and an empty folder src/main/com/mycompany/utils. After creating a new project using mvn archetype:generate the former will be present but the latter will not. The only way to make sure that an empty folder will wind up in the project is by explicitly adding an extra fileSet in the descriptor file for each and every (sub)folder:

Archetype catalogue

So after having overcome the first two astonishments, my archetype was finally finished. And after thorough testing on my developer machine using mvn:update-local-catalog, I released it into our corporate Nexus repository.

But to my complete disbelief my co-workers were unable to use the archetype. How could this be? The archetype-catalog.xml in Nexus was correctly updated. Also, all our Maven’s settings.xml files were pointing to our Nexus instance.
Well, after some further investigation I found that the archetype plug-in insists on going straight to the maven central repository located at http://repo1.maven.org/maven2, completely bypassing our Nexus repository.
After consulting Google some more, I found two possible workarounds:

  1. From the command line add an additional argument specifying the catalogue location, e.g.: mvn archetype:generate -DarchetypeCatalog=http://path/to/nexus/content/groups/public/archetype-catalog.xml
  2. Add the archetypeCatalog property in your maven’s settings.xml:

Leave a Reply

Your email address will not be published. Required fields are marked *

two × one =