An archetype in Maven is a template (predefined package structure, resources, configuration files, source files, etc…) which can be used to start the development of a new application.
Amongst various benefits I like the possibility to provide the developers with a set of resources and classes (implementations!) which are going to be needed in the new project. This speeds up the project-setup time and facilitates the adoption of best practises employed within the team.
BTW Maven has few out-of-the-box archetypes (quickstart application, web application, mojo plugin), plus you can find a variety of archetype for lots of frameworks/technology (Struts2, Spring, GWT, etc…).
Here is a list of available archetypes (docs.codehaus.org).
Create a new archetype
The following sections go through the steps of creating a Maven archetype for a web application based on Struts2, Spring and Hibernate (and set of other utilities).
Define folder structure
my-archetype
|-- pom.xml
`-- src
`-- main
`-- resources
`-- archetype-resources
|-- pom.xml
`-- src
|-- main
| `-- java
| `-- {Java source here}
| `-- resources
| `-- webapp
`-- test
`-- java
| `-- {Junit tests here}
|-- META-INF
| `-- maven
| `--archetype-metadata.xml
- pom.xml (root folder) defines the properties (groupId, artifactId, version) of the archetype
- pom.xml (archetype-resources folder) is the pom.xml for the project to be created. Typically in this you would set all required dependencies (Struts2, Spring, Hibernate, etc..) and plugins
- archetype.xml is the archetype descriptor which defines what the archetype includes
Understanding archetype-metadata.xml
This is the key element of the archetype: in this file you define the which files are created when running the archetype as well as other important metadata.
The <requiredProperties> tag defines properties which require a value in order to run the archetype (Maven will prompt upon execution of the archetype).
<requiredProperties>
<requiredProperty key="groupId">
<defaultValue>com.mycompany</defaultValue>
</requiredProperty>
<requiredProperty key="artifactId"/>
<requiredProperty key="package"/>
</requiredProperties>
The <fileSets> tag identifies which files (Java source, xml, properties) will be included in the newly generated project.
<fileSets>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
....
The filtered=true attribute is required to ensure the files are parsed during the execution (omit in case of binary content such as images).
GroupId and ArtifactId variables
Make sure you use the ${groupId} and ${artifactId} variables in your source and in the pom.xml. Those are very convenient as they are replaced (during the creation of the project) with the values set at the command line.
Similarly using ${package} is useful to parameterised the package of the project:
package ${package}.action;
Escaping symbols
Sometimes you don’t need to replace a variable or maybe you have special characters ($) which need to be in the source (using any ant scripting inn your pom?). To escape it just add at the top of the page the following:
#set($dollar = '$')
Renaming files
Files & folder containing __artifactId__ are replaced by the property value corresponding to the artifactId.
__artifactId__.properties -> becomes for instance myapp.properties
Usage
To generate a project using the archetype run:
mvn archetype:generate -DarchetypeRepository={internal repository}
-DarchetypeGroupId={archetype groupId}
-DarchetypeArtifactId={archetype artifactId}
-DarchetypeVersion=1.0.0 -DgroupId=it.mycompany.myapp
-DartifactId=myapp -Dpackage=it.mycompany -Dversion=1.0.0
Sample
Download the complete sample.