One of the things that we do on a daily basis is use Maven to build our projects by issuing build commands such as mvn install. Maven then looks at our project’s configuration file, affectionately known as a POM, magically figures out what do and, hey presto, your build is complete. I imagine that we do this so often that we never think about what’s going on behind the scenes, and in some cases without ever understanding what’s going on either. This blog takes a bird’s eye look at the Maven build lifecycle and reveals what happens when you issue commands such as mvn clean install.
If you’ve ever looked at the Maven documentation you'll have read that Maven is all about a hierarchical object oriented build structure. In this there are three main artefacts: build life-cycles, build phases and goals, so a good place to start would be to explain the relationship between these terms. Take a look at the following UML diagram:
Jumping straight in, you can see that Maven HAS 1 one or more build life-cycles and each life-cycle HAS one or more build phases, which are executed in a given sequence. Likewise, each build phase has one or more build goals, which are also executed in a given sequence.
A good way of defining a build phase is to give an example. The Maven documentation lists what’s called the default life-cycle and here are its build phases:
- validate - validate the project is correct and all necessary information is available
- compile - compile the source code of the project
- test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
- package - take the compiled code and package it in its distributable format, such as a JAR.
- integration-test - process and deploy the package if necessary into an environment where integration tests can be run
- verify - run any checks to verify the package is valid and meets quality criteria
- install - install the package into the local repository, for use as a dependency in other projects locally
- deploy - done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.
Hence, we can define a build phase as something that takes care of one part of a build life-cycle, for example compiling or testing your project.
You can tell Maven to build your project by specifying a build phase on the command line. For example:
...means “carry out all build phases up to and including install phase in the default build life cycle”.
...whilst issuing a
mvn clean install
...means “carry all build phases of the clean life cycle up to and including the clean build phase and then carry out all build phases up to and including install phase in the default build life cycle”.
From this you can deduce that issuing a
...command will carry out the validate build phase, executing its goals; then the compile phase, executing its goals and finally the test phase, executing its goals.
So, what are goals? In the Maven world a goal can be defined as a single task or job that actually does something concrete towards getting your project built. If we compare Maven to the company you probably work for, then the life-cycles would be the board of directors, the build phases the middle managers and the goals the workers who get the job done.
Most build phases come with default goals attached, for example the compiler build phase is bound, as you may have guessed, to the compiler:compile goal, and likewise the install build phase is bound to the install:install goal.
You can also bind your own goals to phases using the <plugin> element in your POM file, this can be used to either override a goal’s default behaviour or to add new goals and new behaviour.
A final point to note on goals is that they are usually associated with your POM’s package type. This makes sense as, for example, the compiler:compile goal is associated with jars and ejb packaging, but would be meaningless in terms of the POM, wars or ear packages.
In reading this, you may have gathered that by convention the names of goals contain a colon, whilst the names of build phases don’t. This allows you to specify goals on the Maven command line without confusing them with build phases. For example:
...will carry out the compiler:compile goal, which is in the compiler build phase of the default build lifecycle. And, mixing things up at bit...
mvn install tomcat:redeploy
...will carry out all build phases up to and including install in the default build life cycle followed by the tomcat:redeploy goal found in the Tomcat Mojo.
And that’s the mile high, bird’s eye view of Maven.
1 HAS in the UML sense of the word.