< Java
Tip >

DEVELOPING A MAVEN ARCHETYPE FOR MICROSERVICES, PART 1

Harry Klerks
Maven archetypes make it possible to quickly and consistently generate Maven projects that adhere to fixed structures and contain particular content. Using archetypes typically pays back in situations where you create many Maven projects over time.

A good example of such a situation is working in a microservices architecture. We at Bongaro, after having created a number of microservices and repeating a fair bit of work for each and every one of them, decided it was time to create a Maven archetype that could give us a good start with every new microservice.

This series of articles describes the entire process, from idea to making the archetype available in the Maven Central artefact repository.

Although generating from an existing project is by far the simplest way to kickstart any new archetype, we will start from scratch for the sake of this article series.

Anatomy of a microservice

Here at Bongaro, we build microservices as Java EE enterprise applications with a fixed and constant set of modules and libraries. We build according to a Domain Driven Design (DDD) architecture.  For example, a microservice by the name of  microservice1 for a product by the name of product1 would result in the following set of Maven modules:

  • Name

    Type

    Description

  • product1-microservice1

    POM

    Root POM

  • microservice1-domain

    JAR

    Domain classes and interfaces for boundaries, repositories and factories.

  • microservice1-boundary

    EJB

    EJB implementations of the *boundary interfaces in the domain module.

  • microservice1-repository-jpa

    EJB

    EJB/JPA implementation of the *repository and *factory interfaces in the domain module.

  • microservice1-rest-api

    EAR

    Enterprise application.

  • microservice1-rest-api-client

    JAR

    Contains representations and other resources to be used by clients that will communicatie with this microservice in a RESTful manner.

  • microservice1-api-specs

    JAR

    Contains executable specifications in HTML and Java fixtures to instrument them, to be used by the Concordion 
    framework.

Anatomy of a Maven archetype

The contents of a Maven archetype project are fairly straightforward. There is a root POM (src/main/resources/archetype-resources/pom.xml), a descriptor file that describes all the contents of the archetype (src/main/resources/META-INF/maven/archetype-metadata.xml), and a set of files to be optionally manipulated and then copied out in the generation process (in folder src/main/resources/archetype-resources). That's it.

The initial POM looks like this:

<?xml version="1.0" encoding="UTF-8"?>

   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelversion>4.0.0</modelversion>

    <groupid>com.bongaro.platform</groupid>

    <artifactid>bongaro-microservice-archetype</artifactid>

    <version>2017.1.0-SNAPSHOT</version>

    <packaging>maven-archetype</packaging>

    <name>bongaro-microservice-archetype:${project.packaging}</name>

    <description>Bongaro Microservice Maven Archetype</description>

    <build></build>

        <extensions></extensions>

            <extension></extension>

                <groupid>org.apache.maven.archetype</groupid>

                <artifactid>archetype-packaging</artifactid>

                <version>2.4</version>

            

        

        <pluginmanagement></pluginmanagement>

            <plugins></plugins>

                <plugin></plugin>

                    <groupid>org.apache.maven.plugins</groupid>

                    <artifactid>maven-archetype-plugin</artifactid>

                    <version>2.4</version>

                

            

        

    

Note that the POM has a non-standard packaging type: maven-archetype. This is enabled by the extension that you see in the build section.

The initial archetype descriptor file

The archetype mechanism requires a descriptor file by the name of archetype-metadata.xml in the folder src/main/resources/META-INF/maven of our project. It looks like this initially:

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd"

                      name="bongaro-maven-archetype" partial="false">

The root element, archetype-descriptor, has two attributes. The name attribute contains the name of the archetype as it is presented to the user of this archetype and the partial attribute indicates if this is a partial archetype. The latter attribute defaults to false but is shown for completeness sake.

How to generate a new project from this archetype

mvn archetype:generate

When an archetype is run and you do not supply any command line parameters, the plugin will present a list of known archetypes from all configured artefact repositories, including your local one. The plugin then prompts you for the number of your choice, but it is probably easier to supply a groupID and artefact ID of the archetype, like this:

mvn archetype:generate -DarchetypeGroupId=com.bongaro.platform -DarchetypeArtifactId=bongaro-microservice-archetype

Either way, the plugin prompts you for the following 4 required property values:

Property

Value

groupId

The group ID of the generated project

artifactId

The artifact ID of the generated project

version

The version of the generated project, defaults to 1.0-SNAPSHOT

package

The version of the generated project, defaults to 1.0-The base package of the generated project, defaults to the groupId

When the plugin is run this way, the following error occurs:

[ERROR] ResourceManager : unable to find resource 'archetype-resources/pom.xml' in any resource loader.

That makes sense, since we have not specified any input yet. The minimum input required is a (root) POM for the generated project. Let's add the simplest possible root POM one in src/main/resources/archetype-resources/pom.xml

<?xml version="1.0" encoding="UTF-8"?>

     xmlns="http://maven.apache.org/POM/4.0.0"

    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelversion>4.0.0</modelversion>

    <groupid>${groupId}</groupid>

    <artifactid>${artifactId}</artifactid>

    <version>${version}</version>

    <packaging>pom</packaging>

Note the use of properties groupId, artifactId and version. These contain the values that we provided on the command line. When we run the plugin again, the build will succeed and generate a very simple project for us.

This concludes part 1 of this series. Thank you for reading this one. In part 2 we will start building the multi-module structure. See you then!

Read more in part 2 of this blog