Modern Software Experience

2011-09-19

Maven Logo

opinionated software

Apache

The Apache Software Foundation is best known for the Apache HTTP Server, often shortened to Apache Server, or even just Apache. The Apache Software Foundation is about much more than just the Apache HTTP Server. There are literally dozens of projects. One of these is Apache Maven.

This article is a quick introduction to Maven through some key facts and features. You won't learn Maven from it, but should get some idea what it is and does. There are links to more information at the end.

Maven is a customisable software development management system.

Maven

It is hard to describe Maven in just a few words. Maven is a build automation tool. Maven is a software project management tool. Maven is a project management framework.
The Apache Maven home page summarises Maven thus:

Maven is a software project management and comprehension tool. Maven is Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.

Maven can be used as a build tool, but is more than just another build tool. Maven is not only about building projects, it is also about generating documentation, metrics and reports, testing and deploying.
Maven is a customisable software development management system; a system for managing all artifacts and stages of software development. Maven is both an approach and a tool; if you use Maven, your other development tools should plug in to it.

Java Logo

Java

Maven is an Apache project. Maven is programmed in Java and popular with Java developers.
Maven isn't a GUI-tool, but a command-line tool. Maven is a free download, but requires that the Java Development Kit (JDK) already be installed. Maven really needs the Java Development Kit, the Java Runtime Environment (JRE) is not sufficient.

There is just one Maven variant for all platforms, as platform differences are hidden by the Java runtime environment. The Maven download page does provide installation instructions for several platforms.

tip: documentation

There is plenty of documentation on the Maven site, including a Getting Started Guide, a FAQ, a Maven in 5 Minutes guide and two references, a Settings reference and a POM reference.

It is easy to overlook, but the Maven download page offers the official Maven documentation as both a JAR file and a PDF file.

Maven project

Many build tools take a procedural approach; you specify the steps needed to build your software. Maven takes a declarative approach; you specify artefacts and relationships, and let Maven figure out what steps to take.

A Maven project is defined by a pom.xml file. The pom.xml is an XML-based configuration file. As long as you agree with the Maven defaults, you do not need to put much in there. However, as your project and toolset grows, your POM files will grow too.

XML files can be edited with any editor, but that isn't ideal. Maven does not include a user-friendly editor for POM files. Many POM files are created by the Maven archetype command, and then manually edited as needed.

Maven projects commonly use the fixed filename pom.xml for each project and subproject. Some projects use project.pom, the project name followed by the file extension *.pom.

Project Object Model

Maven has a Project Object Model (POM). That is a model of how projects are organised, and that model is expressed in the XML hierarchy used within a POM file. The Project Object Model has a version number independent of the Maven version number. One of the first things each pom.xml specifies is the POM version. The POM model version number has been constant at 4.0.0 for a while and is not expected to change soon.

minimum POM file

Everything in Maven revolves around the notion of a project, and each project has a POM file. This is the minimum POM file Maven allows:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>GroupId</groupId>
    <artefactId>ArtefactId</artefactId>
    <<version>Vversion</version>
</project>
Maven is opinionated software; it wants you to do things the Maven way.
Maven coordinates

The GroupId is some name for the group that created the project. It is typically based on the domain name for that group. For example, the GroupId for Maven itself is apache.maven. The ArtefactId is the name of the artefact that this is the POM file for, and version is its version number.
Together, the GroupId, ArtefactId, and version are known as the Coordinates. The three coordinate values can be combined together to form the fully qualified name of an artefact like this: GroupId:ArtefactId:version.
Every POM file must contain Coordinates. Everything else is optional.

Maven supports project inheritance. A Project can specify a parent project by specifying its maven coordinates.
Maven's default settings are also known as the Super POM; all projects inherit settings from the Super POM.

Maven uses default settings for everything you do not specify. You don't have think about or specify every detail. That sounds nice, but there is another side to that…
Maven is opinionated software; it wants you to do things the Maven way. If you don't like its defaults, you probably don't like Maven.

default directory structure

directorycontents
pom.xmlthe POM file
LICENSE.txtproject license
NOTICE.txtlegal notices and attributions
REAMDE.textproject readme
src/main/javaproject sources
src/main/resourcesproject resources
src/main/filtersresource filter files
src/main/assemblyassembly descriptors
src/main/configconfiguration files
src/main/webappweb application sources
src/test/javatest sources
src/test/resourcestest resources
src/test/filterstest resource filter files
src/sitesite
targetproject target

Maven prefers convention over configuration.
Maven has many defaults, including a default directory structure. It is possible to change the directories used in the POM file, by configuring elements within the <build> element, such as <sourceDirectory> and <resources>.
However, that it is possible doesn't mean you should do so. An key idea behind Maven is to keep different projects as similar as possible; once you are familiar with one Maven project, you pretty much know your way around any Maven project.

Maven expects child projects to be in a subdirectory of their parent project. When that isn't the case, when parent and child are at the same directory level, you can use <relativePath> to specify that the parent project can actually be found at .../parent/pom.xml; <relativePath>.../parent/pom.xml</relativePath>.
Notice the use of relative paths. Maven features default subdirectory names, but avoids the use of absolute paths.

Generally, Maven projects are portable. By avoiding the use absolute paths, Maven keeps the project location flexible; different developers working on the same project may keep the top-level project in different locations.

Maven does not only have a default directory structure for projects, it has naming conventions for builds too, that use the version numbers inside POM files.

Maven plugins

Most of Maven isn't in Maven itself, but in Maven plugins. The core Maven application is a plugin execution framework. All the real work is done by Maven plugins. The Maven project distinguishes between build plugins and reporting plugins; build plugins are executed during build and are configured within the <build> element of the POM, reporting plugins are executed during site generation, and are configured within the <reporting> element.

Maven commands

commandbrief description
validatevalidate the project info is complete and correct
compilecompile the sources
testperform the unit tests
packagepackage the code into its distribution format
integration-testprocess and deploy the package integration testing
verifyverify the package is valid
installinstall package into local repository
deploydeploy final package to a remote repository
cleanclean up artefacts created by prior builds
sitegenerate web site for this project

Maven is a command line tool that accepts various commands. The table provides a quick overview of the most important commands.
Like so many development tools, maven allows you to define environments variables and otherwise override some project settings through its command line.

Maven commands are conceptual commands. What they mean exactly depends on the project, the content of the POM files and the plugins used.
Notice that Maven includes the ability to generate a web site.

documentation generation

Generating documentation is an essential feature of Maven. Most of the work may be done by plugins and external applications such as Javadoc, but Maven provides the framework to make documentation generation part of the automated build process. Maven can generate a Maven site for your Maven project. Some customisation of your Maven site is possible, but that all Maven sites look similar to each other is considered a feature.
Maven can generate more than just a Maven site. Maven can be used to generate code documentation, unit test reports, code quality reports, etcetera. You can provide central access to all the documentation and reports generated by various plugins by using the bundled Maven dashboard plugin.

repositories

Maven distinguishes between two kinds of repositories: local repositories and remote repositories. Your local repository is a cache of downloads from remote repositories, and a container of build artefacts you haven't released to a remote repository yet. Typically, your local repository is just a directory structure, while the remote repository is a version control system. In a corporate setting, a central corporate repository is considered a remote repository, not a local one. There are several Maven repository managers to help you manage your repositories.

Maven dependencies

scopebrief description
compilecompile-time dependency
providedprovided at runtime
runtimerequired at runtime
testdependencies required for tests
systemprovided by the system
importimport dependency specified in POM

Maven includes dependency management; when you decide to build a project, it will figure out the dependencies between projects, and automatically get everything needed to build, including transitive dependencies.
To do this right, Maven supports six different dependency scopes: compile, provided, runtime, test, system and import. The default scope is compile. Use of dependency scopes allows restricting dependencies to particular build phases.

continuous integration

Maven features support for continuous integration. The Maven documentation links to Jenkins (formerly known as Hudson), the continuous integration system used by Maven, to show how the Maven project itself takes advantage of this feature, but Maven can be used with other systems as well. Continuous integration support is configured within the <ciManagement> element of the POM.

tip: free Maven books

There are multiple books about Maven. Several of these can be read online or are available as free Adobe PDF downloads. The official Apache Maven web site has links to those.

offline mode

Maven generally assumes that you are online, and that it can go out to access whatever repository it needs. However, because that is not always the case, Maven can be run in offline mode; just include the -o command line switch. You can omit the command line switch if you include the <offline>true</offline> in the POM <settings>. In offline mode, Maven requires all artefacts to available in the local repository.

links