Introduction to Maven

Posted in automation, development on October 2, 2017 by Adrian Wyssmann ‐ 5 min read

Maven is a tool to automate the building, distribution and dependency management of software artifacts in a project. It is one of many build systems but currently heavily used in the Java world.

The picture found in this post actually gives a nice overview of the evolution

build system evolution

POM - Project Object Model

Project Object Model or POM is the fundamental unit of work in Maven. It is an XML describing the project and it’s configuration. The default filename since Maven 2 is pom.xml which is also the one processed then calling mvn without specifying a file (parameter -f). Important to know that there exists a SuperPOM, which defines the defaults for maven and all other POMs extend the Super POM unless overridden in the project pom otherwise. Due to the fact that Maven uses XML language, a POM file for large projects grows quickly. Therefore it is good to understand Project-Inheritance on Maven andand to understand that you can split a single POM file into modules if necessary. Details to that you can find here: https://maven.apache.org/guides/mini/guide-multiple-modules.html

Lifecycles, Phases and Goals

Maven has clearly defined processes on how to build and distribute artifacts - it’s called Lifecycles. These lifecylces are default, clean and site. Each lifecycle consists of several phases whereas each phase represents a stage in the lifecycle. These phases are executed in a sequential order. The Lifecycle Reference shows the phases of the lifecycles in details incl. the order they will be executed.

We learned that the phase is a particular step in the build process. However, what is done during the respective phase is defined by binding a plugin goal to the phase. In Maven all work is done by plugins. Beside of some core plugins, there are a plenty of additional plugins - build or reporting - available. Checkout https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Plugins and  https://maven.apache.org/plugins/ for more details to plugins. Each plugin defines one or more goals of which each represents a capability of that plugin. The capability and the configuration parameters can be found for each plugin in the respective documentation. A plugin goal is usually assigned to a default phase, but within your POM file you could actually define the goal executed in another phase like this process-test-resources or even execute it several times (in different phases).

Mojo

Sooner or later you may struggle over the term Mojo.

A mojo is a Maven plain Old Java Object. Each mojo is an executable goal in Maven, and a plugin is a distribution of one or more related mojos.

Repositories

One important part of the build process is the dependency management and artifact storage. In order to build your project you may required other artifacts (packages, software, well usually jars in Java world) so they have to be pulled into your build environment from a specific location called repository. In addition you may also publish your software artifacts (which you build) into a repository so others can use them in their projects. https://maven.apache.org/guides/introduction/introduction-to-repositories.html gives a good overview about repositories and why you should use them instead of storing packages in the SCM. There are two types of repositories:

Local Repository

To avoid that one and the same artifact exist multiple times and that it has to be downloaded every time it is used (CI) Maven caches the artifacts in the local repository under <Maven Home>/repository e.g. /home/papanito/.m2/repositroy or C:\Users\papanito\.m2\repository. A user usually has nothing to do with the local repository except maybe cleanup if your disk space gets low. Though it may be sometimes handy to “install” packages into the local repository for testing purposes instead of uploading them to a remote repository.

Remote Repository

Remote repositories serve for upload and download of artifacts.  Maven supports different protocols for download and upload like HTTP (download), SCP, SFTP, FTP, WebDAV, or the filesystem. A remote repository can be a public or internal only - internal repositories are not publicly available but only within your enterprise infrastructure mainly due to security, speed or bandwidth reasons. Some interesting repository solutions are Nexus or Artifactory - both have OSS versions which supports maven repositories by default.

General settings for repositories are defined in the settings.xml file, whereas specific project settings are defined in the respective  pom.xml. The settings.xml file is also central when it comes into defining credentials to authenticate. Assuming you already setup a user in your repository with enough permissions, you would like to encrypt the password before adding it to the settings.xml file.

mvn --encrypt-password

Then you have to add the credentials and the repository to your settings.xml:

<?xml version="1.0" encoding="UTF-8"?>
<settings>
  <servers>
    <server>
        <id>repo.example.com</id>
        <username>uploader</username>
        <password>{encrypted password}</password>
    </server>
  </servers>
  <profiles>
    <profile>
      <id>default</id>
      <repositories>
          <repository>
              <id>repo.example.com</id>
              <url>http://repo.example.com/artifactory/repo</url>
          </repository>
      </repositories>
    </profile>
  </profiles>
  <activeProfiles>
    <activeProfile>default</activeProfile>
  </activeProfiles>
</settings>

Take care of the id-tag which should match for server and r2017-10-02-introduction-to-mavenepository. This id is also used in the project pom.xml simply as this:

<distributionManagement>
    <repository>
        <id>repo.example.com</id>
        <name>repo.example.com</name>
        <url>http://repo.example.com/artifactory/libs</url>
    </repository>
</distributionManagement>

Wrap-Up

This is just a brief summary of the most important concepts and terminologies of Maven. Maven is quite powerful but very “chatty” due to usage of xml and as the first image shows, there may be actually better (?) tools like Gradle. However Maven exists since years and has been proven very useful. If you want to learn Maven there is no better way to use it with a real project and real problems to solve - the learning curve is not that steep.