Introduction to Maven

Maven is a very flexible build tool. To understand it, you need to understand the following concepts:

  • projects and the POM
  • plugins and their goals
  • build life cycle and phases
  • packaging types
  • dependency management and the local repository

Projects and the POM

In Maven, the unit of work is a project. Each project has its project object model (POM) defined in pom.xml, an XML file that contains information about the project and details instructing Maven how to build the project. A project's POM can inherit from another project's POM to form a POM inheritance hierarchy; this is the mechanism used in Maven to avoid duplication. Eventually, all POM files inherit from the Maven Super POM.

Plugins and goals

As its plugin documentation states, Maven is "at its heart - a plugin execution framework; all work is done by plugins".  There are countless plugins, for example:

Each plugin defines one or more goals. For example, the Compiler Plugin has two goals - compile to compile the production code and test-compile to compile automated tests.

Build life cycle and phases

Maven defines a build lifecycle that consists of a sequence of phases. For example, here are some phases of Maven's default life cycle:

  • compile - compile the project's source code (in other words, create .class files from the .java files)
  • test - run the project's automated tests
  • package - take the compiled code and package it in its distributable format (for example, put all the .class files into a JAR)
  • install - install the project's artifact into the local repository, for use as a dependency in other projects locally
  • deploy - deploy the project's artifact to the artifact repository, usually Nexus (this phase should not normally be run by a developer)

Each phase of Maven's build life cycle is configured to run a specific goal of a specific plugin. Maven is configured with reasonable defaults for the plugin and goal to run in each phase. For example, the Compiler Plugin's compile goal is configured to run during Maven's compile phase. The Compiler Plugin's test-compile goal is configured to run during Maven's test-compile phase. (The overloaded use of terms such as compile can get confusing, but you get used to it.)

Packaging types

The most important aspect of a Maven project is its packaging type, which specifies the type of artifact the project produces. There are many built-in Maven packaging types (for example, jar, war, and ear). A project's packaging type specifies the plugin goals that are executed during each Maven build phase. For example, in a jar project, the maven-jar-plugin's jar goal is executed. In a war project, the maven-war-plugin's war goal is executed.

Dependency management and the local repository

Maven uniquely identifies all artifacts using a group ID, artifact ID, version, and type (these values are collectively referred to as an artifact's Maven coordinates).

With Maven, you never have to store artifacts that you depend on in source control... hallelujah! No more lib folders in source control that have no traceability and have to be checked out as part of every submission!

Instead of artifacts in source control, a Maven build gets artifacts from the local Maven repository. For example, if my machine compiles two projects that use the same version of log4j, only one copy of log4j.jar exists on my machine. The artifact is only downloaded once. In a corporate environment, projects are typically configured to download all of their artifacts from a corporate repository (such as Nexus).

On a Windows XP machine, the Maven local repository is stored in the C:\Documents and Settings\<userid>\.m2\repository folder. Get to know where the local Maven repository is stored on your machine!