Introduction
Maven is a build and dependency management tool for Java projects. A lot of Maven documentation is freely available on the web. The Maven homepage is a fine place to start. There is a lot of data there, finding the information can be a bit challenging. The pom.xml reference is really useful, as are the various introductions. Sonatype provides a digital version of Maven: The Complete Reference, which is a more prosaic exposé of mostly the same information. Throughout the post, I've included some links to specific parts of the documentation that provide more in-depth information about the discussed material.
Plugins and goals
Just about every action that Maven performs is delegated to a plugin. Plugins define goals, which represent the individual actions that they can perform. These actions can be as simple as copying the contents of one folder to another, or as complex as generating a website with a number of reports about your project.
You can tell Maven to invoke a specific plugin goal by invoking it as follows.
mvn <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>
While this is wonderfully exact, it is not terribly convenient. A shorthand form exists using a plugin-prefix.
mvn <plugin-prefix>:<goal>
Prefix here is a bit of a misnomer; the default prefixes that are available actually correspond to the middle part of the artifact-id of the plugin they identify. The prefix something
can be used to refer to
org.apache.maven.plugins:maven-something-plugin
Conveniently, all the standard plugins all follow this naming pattern. The prefix resolution process can be rather complex and is described in detail here.
Lifecycle phases
As said, goals represent single actions performed as part of the build process. While these can be quite large (e.g. "compile all java files under the src/main/java
folder"), we often have to invoke many of them in sequence in order to produce various outputs that can be derived from a project's sources. This idea is expressed in Maven via lifecycles and their phases. A lifecycle is a list of phases, which are nothing more than placeholders to which any number of plugin goals can be associated (a plugin goal can be associated to multiple phases as well).
The default lifecycle defines phases like compile, test and package which represent steps in producing and deploying artifacts associated to the project. When ask Maven to execute a phase by invoking
mvn <phase>
it will execute the goals associated which each phase in the corresponding lifecycle up to and including the specified one, in order. So, since compile
comes before test
in the default lifecycle, invoking mvn test
will also compile the sources.
Two additional lifecycles exist: clean
and site
. The former is used to purge generated outputs from the project, the later to produce reporting information about the project.
Configuring plugins
The plugins section of the build definition in a project's pom file serves two purposes. It can bind plugins to specific lifecycle phases by defining executions, and it configure the way (bound) plugins function by setting plugin property values.
Each plugin has its own configuration options. The list of plugins on the Maven site has links to sites for the various standard plugins, which include usage and configuration details. One cross-cutting concern that affects many plugins is the encoding used for text files (input and output). Fortunately, there is a property that you can define in your pom file,project.build.sourceEncoding
, which is used as the default value by
many plugins
. Unfortunately, it has a really bad default value, but at least Maven emits a warning if you don't configure it.
Closing thoughts
They say the best way to really learn something is to teach it. Writing up this summary has forced me to study the working of Maven a lot more closely than I would have otherwise. I hope that it's useful and doesn't contain too many wildly inaccurate statements. Should any have slipped in, let me know and I'll try to correct them.