Maven Archetypes Project Templating

generation
code
development
maven
java
project
tool
automation
cli
build
Archetype is a Maven project templating toolkit. An archetype is defined as an original pattern or model from which all other things of the same kind are made. Archetype will help authors create Maven project templates for users, and provides users with the means to generate parameterized versions of those project templates. Using archetypes provides a great way to enable developers quickly in a way consistent with best practices employed by your project or organization.
Author

Mariusz S. Jurgielewicz

Published

March 6, 2020

Intro

I am developer and I like DRY. If there is any task you have to do more than once you should probably automate it. starting a new project, it can be tedious and time-consuming to start over and over again from scratch. You can use Spring Initializr to boostrap your new application or even better without leaving the shell Spring Boot CLI. You will get nice clean project with the latest versions of dependencies but what if you need to use specific internal libraries or configuration files? Wouldn’t be nice to have project template and generate new one by answersing few simple questions? Project generation (scaffolding) was made popular by the Ruby on Rails framework and now we got many generators included in popular frameworks or standalone but if you are already using Maven as you your build tool don’t look any further.

Maven Archetypes

Archetype is a Maven project templating toolkit. An archetype is defined as an original pattern or model from which all other things of the same kind are made. Archetype will help authors create Maven project templates for users, and provides users with the means to generate parameterized versions of those project templates. Using archetypes provides a great way to enable developers quickly in a way consistent with best practices employed by your project or organization.

Maven provides several archetype artifacts.

Creating a Maven Archetype

Creating archetype from scratch is possible but I would recomend pick some existing project and generate archetype from it.

mvn archetype:create-from-project

Generated source code can then be found under the target/generated-sources/archetype directory. When you type mvn install in this directory it will install archetype in our local Maven repository (${HOME}/.m2/repository). When archetype is used to generate new project it would create a copy of base project which is not particularly useful. When you start parametrizing your archetype things are getting more interesting.

Dynamic content

Maven Archetypes use Apache Velocity Engine for incorporating the dynamic content in genereted files. Any file in archetype resources is template but some files need to be escaped because they charcters are used by Velocity. For example XML, Java or Groovy files might use similar characters. You have to define special variable to escape them:

#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )

Example from Groovy Script or Jenkins config:

#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
${symbol_pound}!groovy

You can also apply variable substitution to file names. To inject a property into a file name, surround the property erty name with “__“.

archetype-root/src/main/resources/archetype-resources/src/main/java/__library-name__.java

Defining additional properties

The main properties that are used by the Velocity engine during a project’s file generation are groupId, artifactId, version and package. It is possible to define additional properties that must be valued before the file generation. These additional properties can be provided with default values, which enable not to ask the user for there values. Additional properties are defined in the /src/main/resources/META-INF/maven/archetype-metadata.xml file with:

<archetype-descriptor name="basic">
  <requiredProperties>
    <requiredProperty key="property-with-default">
      <defaultValue>default-value</defaultValue>
    </requiredProperty>
    <requiredProperty key="property-without-default"/>
  </requiredProperties>
...
</archetype-descriptor>

Defining specific filesets

The filesets contained in the /src/main/resources/META-INF/maven/archetype-metadata.xml file defines the way the project’s files located in the JAR file are used by the Archetype Plugin to generate a project. Filesets must define the directory where the files will be searched for which is also the directory where the project’s files will be generated.This provide a way to describe a large set of files to be selected for the generation process. Filesets can be filtered, which means the selected files will be used as Velocity templates. A fileset is defined in the archetype-metadata.xml with this fragment:

<fileSets>
    <fileSet filtered="true" packaged="true">
      <directory>src/test/java</directory>
      <includes>
        <include>**/*.java</include>
      </includes>
      <excludes>
        <exclude>AllTest.java</exclude>
      </excludes>
    </fileSet>
  </fileSets>

Sample archetype directory structure:

archetype-root
└── src
    └── main
        └── resources
            ├── META-INF
            │   └── maven
            └── archetype-resources
                └── src
                    └── main
                        ├── java
                        │   └── __packageInPathFormat__
                        │       └── __artifactPackage__
                        │           ├── config
                        │           ├── model
                        │           └── rest
                        └── resources
                            └── config

Installing the Archetype

You can install the archetype by invoking this command:

mvn install

Create a project using archetype

You can create a Maven project through the generate goal and existing archetype.

mvn archetype:generate -DarchetypeGroupId=org.example -DarchetypeArtifactId=msg-archetype-spring-boot2-quickstart -DarchetypeVersion=0.1.0-SNAPSHOT  -DgroupId=org.example  -DartifactId=msg-v1-test-rest

Run the project

$ mvn spring-boot:run

Test on the browser

http://localhost:8080/v1/test/status

Full list of available archetypes can be generated using mvn archetype:generate :