Maven 2 – An Overview
Here’s a high level Maven2 cheat sheet which just explains what Maven 2 is and the steps that are executed when Maven does a build.
What is Maven?
It’s a build tool, basically! It also manages dependencies and produces build reports. It uses xml syntax to create build files (called POMs), and the build files support the concept of inheritance. Maven uses plugins to extend basic functionality and perform cool tricks. It’s mainly used in the Java world but apparently there’s also a .Net plugin (I haven’t actually tried it though).
Why Use Maven?
I would recommend using maven if you need a build tool which will:
- Take over dependency management
- Enforce a (fairly) rigid format and practice on developers
The dependency management system uses repositories to store binaries. You can have external (third party) binaries as well as internal dependencies. You can reference them from external repositories (like the maven central repository) or you can put them in your own repository. I actually really like the way Maven enforces it’s own best practices on things like naming conventions and project structures, it’s a real time-saver in the long run.
Installing Maven
Installing maven is a doddle. Simply download it from here. Check the installation pre-requisites (you basically need JDK installed).
For instructions on installing maven on Mac OSX look here
For instructions on installing maven on Windows look here
For instructions on installing Maven on Linux you basically do the same as you do for Mac OSX. That is:
Extract the archive you downloaded.
Add an environment variable called M2_HOME and point it to your Maven directory (I installed mine in /home/maven/maven2).
Add the bin directory ${M2-HOME}/bin to your PATH
Add these to your bash_profile by simply adding these 2 lines:
export M2_HOME=/home/maven/maven2
export PATH=${M2_HOME}/bin:${PATH}
To confirm Maven is installed on your system, simply type: mvn -version
What Happens When I Run a Build?
A lot. And it varies between different types of builds. You’ll need to have a POM file for your project in order to be able to run a build, and I’m going to assume you’ve already got one. If you haven’t, try checking out this post for a couple of examples to get you started.
When you run Maven, it steps through a series of phases in a build lifecycle. You can also call goals defined in plugins. So essentially it works like this:
A lifecycle is a sequence of phases, phases can call plugins, plugins contain goals.
Clear? Yeah, it’s not exactly crystal, but stick with it.
There are 3 basic lifecycles: clean, default and site. You call these when you do a bild, like this:
mvn clean deploy site-deploy
I’ll explain exactly what’s happening in this command a little later, but first I’ll briefly explain what each of the three lifecycles do:
Clean, as the name suggests, does the cleaning work – it deletes the build output directory.
Default does all the build work. It compiles the code and the tests, runs the unit tests, packages up the build, and deploys it to the repository.
The Site lifecycle generates all of the build reports and uploads them to a site for your project.
So, back to our mvn command:
mvn clean deploy site-deploy
What’s actually happening here is we’re calling the clean lifecycle by passing the command “clean”. So far so easy.
Next up is “deploy”. Where has this come from? Well, deploy is a phase in the Default lifecycle. In fact, it’s the last phase in the default lifecycle (for a full list of all the phases that run in all 3 lifecycles take a look here. Because it’s the last phase in the default lifecycle, it automatically includes the execution of all of the others, so simply by calling “deploy” we are ensuring that the phases for compiling our source code, compiling our tests, running our tests and packaging our code are also run. It’s a bit like using the “depends” feature in ant targets, but it’s implicit. In other words, it’s a shortcut way of making sure all the phases in the default lifecycle are executed.
Finally we have site-deploy, and again this is the final phase of the site lifecycle, so we’re implicitly calling the other preceeding site phases.
The Maven Release Plugin
The Release plugin is commonly used when making an official Release Candidate build. In a nutshell it increments the build version and tags your code in SCM. It has 2 main goals. relase:prepare and release:perform.
Release:prepare does the following:
- It checks that your source is up to date
- It checks the POM to make sure there’s no occurances of the word SNAPSHOT in the dependencies section (the idea here being that you should never make a release build using snapshot dependencies)
- It removes the word SNAPSHOT from your version
- It compiles the code to make sure it works
- It tags the code and commits the POM to scm
- It then increments the version and re-adds “SNAPSHOT”, and commits this back to the original SCM location (i.e. not the tags location)
Once this completes successfully, release:perform is executed. Release:perform checks out the code from the tag location, and then runs the standard maven goals “deploy site-deploy” which has the effect of recompiling the code, running the tests, packaging and uploading etc etc (see above for detail on what the deploy phase actually does).
Summary
In general, I think Maven is a good build tool, it does a lot of the hard work for you. It’s far from easy to understand and follow though, unless you’re prepared to dedicate a bit of time to reading through the documentation.
In the past, I’ve spent quite a bit of time and effort creating build systems using Ant, which, through my own design, have enforced some standards and best practices on the build process, and at the end of the day, I ended up with something fairly identical to what you get with Maven. I would definitely use Maven again, especially if standardisation and repository management were on my to-do list.