Sonatype

Previous: Chapter 7
Next: Chapter 8

Using

Archetypes are a simple and useful way to bootstrap new development across your organization, and urge your developers to follow a similar project pattern. Archetypes are a template of a Maven project used to generate skeleton layout for projects of any desired type in a consistent way.

The default archetype is called quickstart, and generates a simple project with some "Hello World" Java code and a unit test. Running the archetype:create goal as so:

mvn archetype:create -DgroupId=com.mycompany -DartifactId=my-proj 

This will yield a project with the following project structure:

my-proj
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- com
    |           `-- mycompany
    |               `-- App.java
    `-- test
        `-- java
            `-- com
                `-- mycompany
                    `-- AppTest.java

The archetype that generates this simple project is outlined by two mechanisms: the META-INF/maven/archetype.xml resource definition file, and the archetype resources under the src/main/resources/archetype-resources directory.

maven-quickstart-archetype
|-- pom.xml
`-- src
    `-- main
        `-- resources
            |-- META-INF
            |   `-- maven
            |       `-- archetype.xml
            `-- archetype-resources
                |-- pom.xml
                `-- src
                    |-- main
                    |   `-- java
                    |       `-- App.java
                    `-- test
                        `-- java
                            `-- AppTest.java

There are other archetypes available by default from Maven Central Repository. Check out the list at http://repo1.maven.org/maven2/org/apache/maven/archetypes. At the time of the writing of this book, the list is:

Creating Your Own Archetypes

The easiest way to start creating archetypes is with the org.apache.maven.archetypes:maven-archetype-archetype.

mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes \
                     -DarchetypeArtifactId=maven-archetype-archetype \
                     -DarchetypeVersion=1.0 \
                     -DgroupId=com.mycompany \
                     -DartifactId=my-archetype

It will generate a simple archetype that is built to generate a simple project - of the same vein as the maven-quickstart-archetype shown in the beginning of this article, under the directory of the artifactId defined.

By default an archetype cannot overwrite a project. A useful construct for converting your existing non-Maven projects to Maven is to create a simple archetype with a pom construct of your design. Let's create a simple archetype that will be run over non-Maven projects to give them a pom.xml file with a custom MANIFEST.MF file.

Let us begin by removing the extraneous files under the src/main/resources/archetype-resources/src directory, leaving us just with a pom.xml and create a file src/main/resources/archetype-resources/src/main/resources/META-INF/MANIFEST.MF. This will leave the following project structure:

my-archetype
|-- pom.xml
`-- src
    `-- main
        `-- resources
            |-- META-INF
            |   `-- maven
            |       `-- archetype.xml
            `-- archetype-resources
                |-- pom.xml
                `-- src
                                  `-- main
                        `-- resources
                            `-- META-INF
                                `-- MANIFEST.MF

Alter the src/main/resources/archetype-resources/pom.xml to be a project which contains a base MANIFEST.MF file to be packaged into a jar with extra entries. Since most - if not every - non-Maven project places its source code in a directory other than Maven's default src/main/java, we are also setting the sourceDirectory build element to another directory, src. Set this directory to whatever your legacy project structure requires.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>${groupId}</groupId>
  <artifactId>${artifactId}</artifactId>
  <version>${version}</version>
  <name>Project - ${artifactId}</name>
  <url>http://mycompany.com</url>

  <build>
    <sourceDirectory>src</sourceDirectory>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <excludes>
          <exclude>**/MANIFEST.MF</exclude>
        </excludes>
      </resource>
    </resources>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
            <manifestEntries>
              <Built-By>${user.name}</Built-By>
              <Project-Name>${project.name}</Project-Name>
            </manifestEntries>
          </archive>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Fill the src/main/resources/archetype-resources/src/main/resources/META-INF/MANIFEST.MF file with whatever valid manifest values you wish. Mine contains:

Manifest-Version: 1.1
Created-By: Apache Maven 2
Company-Name: My Company

Now we need to set the src/main/resources/META-INF/maven/archetype.xml descritor to bundle up our MANIFEST.MF file as a resource, and to allow us to run our archetype over the top of an existing one via the allowPartial element. By default the archetype:create goal will not allow the creation of an archetype when a project with the same artifactId already exists in the current directory.

<archetype>
  <id>my-archetype</id>
  <allowPartial>true</allowPartial>
  <resources>
    <resource>src/main/resources/META-INF/MANIFEST.MF</resource>
  </resources>
</archetype>

Like any other Maven project, you can install it by running in the base directory:

mvn install

Which builds and installs the archetype to your local repository. To test our new archetype, run the following command, which will generate a new project with the pom.xml and MANIFEST.MF files. If you run the same command again, it will work - only because we set allowPartial to true.

mvn archetype:create -DarchetypeGroupId=com.mycompany \
                     -DarchetypeArtifactId=my-archetype \
                     -DarchetypeVersion=1.0-SNAPSHOT
                     -DgroupId=com.mycompany \
                     -DartifactId=my-project \

Viola! You can now outfit your legacy projects with a shiny-new Maven 2 complient version.

Summary

Archetypes are an excellent way to get started on a project quickly - as well as keep many developers in sync regarding project layout or required files such as licenses or READMEs.


Previous: Chapter 7
Next: Chapter 8