Creating a Custom Maven Archetype in 5 Simple Steps

Last Updated:  July 14, 2022 | Published: October 28, 2019

Manually creating a new Maven project is cumbersome. Most companies have a set of shared libraries (e.g., security, encryption, or payment) and pre-defined configurations they need for each project. Copy and pasting these files over and over is a tedious task. With Maven, we have the option to build project templating toolkits with so-called Maven Archetypes. This blog post will teach you how to create your own Maven Archetype in 5 simple steps.

As an example for this blog post, we create a minimal Jakarta EE 8 with Java 11 Maven Archetype.

Maven Archetype Project Setup

Creating a custom Maven Archetype is simple.

To create a Maven Archetype, we use – who guessed – Maven. This Maven project requires the following setup:

Compared to everyday Maven projects (e.g., a Spring Boot microservice), this project setup is a bit different.

First, the packaging type is maven-archetype. While our day-to-day Java services are packaged as a war or jar files, we use the packaging maven-archetype for creating a custom archetype.

Next, we don't need any dependency or plugin but a Maven extension: archetype-packaging. This extension will build our final archetype later on.

Defining Our Project Template

The main goal of our archetype is to scaffold a new Maven project with common resource files, Java classes, and dependencies.

We define the raw template Maven project as part of src/main/resources/archetype-resources.

Within this folder, we specify the target project like a usual Maven project. Here we have to set up the folder structure of our target project and include all files we want.

For our Jakarta EE 8 project, this might look like the following:

Folder structure for Maven project

We can add any file we like and are not limited to Java classes, e.g., a Dockerfile, .gitignore, .editorconfig, etc.

To instruct Maven on which files to include in the archetype, we need to create a archetype-metadata.xml file within src/main/resources/META-INF/maven:

Each fileSet describes a set of files or directories we want to include within our Maven Archetype.

The attribute filtered defines whether or not Maven should replace placeholders inside the file. Those placeholders let us define dynamic text inside our files, e.g., the package name of a Java class.

For a detailed explanation of the available elements and attributes in this archetype meta file, have a look at the official documentation.

Adding Placeholders for Our Files

To make the resulting project and its files more dynamic, we can add placeholders to our files.

Once we use the archetype, we will specify the groupId, artifactId and version of our project. These values can be injected into any file we like as the following:

For our demo archetype, we also use these variables to prepare a Dockerfile and bash script:

Please note that this variable replacement only takes place for files or directories we marked as filtered in the archetype-metadata.xml file.

Similarly, if our archetype contains pre-constructed Java classes, we might want to place them in the correct package structure. We can achieve this by setting the packaged attribute in archetype-metadata.xml to true and use ${package} placeholder:

If placeholders and the packaging option are not enough, we can add an archetype-post-generate.groovy script within src/main/resources/META-INF.

This file gets executed after Maven successfully creates a new project out of our archetype. With this file, we can do any customization to the resulting project you want.

As an example, we'll use this file to mark the bash script as an executable file:

Publish Our Maven Archetype

Now we are ready to publish the Maven Archetype. For a company's internal archetype, we might choose our internal artifact manager.

We can also publish it to the Sonatype Nexus Repository Manager to make it available for everyone.

For a first local demo, we can publish the archetype to our local Maven repository first:

This will install the archetype in our local repository (~/.m2/repository).

Using the Archetype to Bootstrap Projects Faster

Finally, we can now make use of the archetype. Maven offers a plugin for this, which we can use with the following command:

The users of our Maven Archetype just need to specify the correct groupId and artifactId, that's all.

The source code for this Maven Archetype is available on GitHub.

Furthermore, I maintain a set of custom Maven archetypes that you can use as a source of inspiration (they are all published to Sonatype). There you'll also find a blueprint on how to use GitHub Actions to automate the Sonatype Nexus Repository OSS release part.

Have fun creating your own Maven Archetype,

Philip

>