Monday, August 5, 2013

Maven 3 Tutorial

In this post, we are going to how see what is maven and how to create a maven project.

  • Overview
    • What is Maven?
    • Plugins
    • Why not Ant and Ivy?
    • But It Downloads the Internet
  • Getting Started
    • Install
    • What is a POM?
    • Convention over Configuration
    • New Project
  • Project Management
    • Parent POM
    • Local Maven Repository
    • Multiple Artifacts from a Single Source
    • Release Plugin
    • Aggregate POM
    • Dependency Management
    • Distribution Zip


What is Maven?

Maven is a software project management and comprehension tool that includes: build tools, dependency management, project reporting and much more.  I say “much more” because at the core Maven is a plugin execution framework.  There are plugins supported by the Maven project (, plugins supported by Mojo Project (, and third party plugins.  If you can find or write a plugin, Maven can run it.


Plugins are configured to run during specific phases in the Maven lifecycle.  The high-level phases that make up the build lifecycle include: validation, compile, test, package, integration-test, verify, install, and deploy.

But It Downloads the Internet
I can’t tell you how many people have told me that they don’t like Maven because it “downloads the internet”. I find it ironic that many of them like Ivy.  I hate to break the news, but Ivy downloads the internet too. I’m not sure why this is a concern.  Is there a fear that Maven will fill up their hard drive?  Disk space is cheap.  The computer I am working on right now has 150GB of hard disk space and my Maven local repository is eating up 300MB of it. 

Getting Started

The new stable version Maven 3.0.3 was released March 3rd of this year.  This tutorial will demonstrate how to setup and run this newest version.  The only system requirements for Maven are JDK 1.5 or above and an internet connection.


  1. Download Maven 3.0.3 from
  2. Unzip the contents in your root Maven folder.  In my case I unzipped it in C:/java/maven.
  3. Setup M2_HOME in your environment variables and point it to your installation directory.  In my case this is C:/java/maven/apache-maven-3.0.3.  (Note: You need to use M2_HOME instead of M3_HOME because the maven plugin for eclipse will not work with M3_HOME.)
  4. Add ‘%M2_HOME%/bin’ to your PATH variable.
  5. Open a command window and run the ‘mvn -version’ command.
  6. You should see version information about Maven 3.0.3.

What is a POM?

POM stands for “Project Object Model”.  This XML file stores information about your project.

Project Information

  1. Basic information about the project including version, artifcat type, dependencies, properties, etc.
  2. Build Settings allow you to declare custom directory structures, configure custom plugin steps, and project reporting.
  3. Project Information includes: license, organization, developers, and contributors.
  4. Environment Settings allow you to configure locations for issue management, continuous itegration, mailing lists, versin control, Maven repositories, and download urls.
If you really hate XML there are a few options.  One option that has been around for a while is to use an IDE that provides tooling for Maven configuration.  In my experience these are very helpful but advanced configurations will still need to be added by hand.  Maven 3 breaks this wide open by introducing configuration alternatives in Groovy, Scala, Clojure, and JRuby (  If you have an existing Maven 3 project that you want to switch from XML to a JVM language there is a translate command

Convention over Configuration

Maven uses project information from the pom.xml file to manage the project.  The package type (pom, jar, maven-plugin, ejb, war, ear, rar, par) determines which actions are applied to your project by convention. These standard actions can be modified in the build secion of the POM.  This is one of the primary reasons that comparing Ant and Maven is like comparing apples and oranges.  Every action or task in Ant has to be explicitly declared for each project.  While Ant allows you to extract common tasks to be reused they do not provide an industry standard.  Ant is not a project management tool.  Ant merely provides the building blocks for you to create your own project management infrastructure.  Maven decided that all projects should be treated the same by default.  Maven hits the ground running.  Ant gives you the tools to begin running.

Maven conventions include:

  1. Standard package structures
  2. Standard output directories
  3. Standard artifact structure and naming
  4. Standard build steps and order
  5. Standard 3rd party dependency repository locations
  6. Standard Release process
  7. Standard artifact publishing
These standards are best practices within our industry.  Nevertheless, all of these defaults are easily extended and modified.  Maven provides a simple way to focus on developing software instead of focusing on project management.

New Project

For this example I will be using Eclipse for my IDE.
  1. Download Eclipse IDE for Java EE Developers from
  2. Unzip the contents in your root Eclipse folder.  In my case I unzipped it in c:/java/eclipse
  3. Run the ‘eclipse.exe’ in [eclipse root]/eclipse
  4. Select a workspace location for Eclipse to store your projects.  In my case I used the default location
  5. m3-02
  6. Click on the ‘Workbench’ icon
  7. m3-03[1]
  8. Select Help -> Install New Software
  9. m3-04[1]
  10. Click the ‘Add…’ button
  11. Name: m2eclipse
  12. Location:
  13. Click ‘OK’
  14. m3-05
  15. Check the ‘Maven Integration for Eclipse’ option
  16. Click ‘Next’
  17. m3-06
  18. Click ‘Next >’
  19. m3-07
  20. Select ‘I accept the terms of the license agreements’
  21. Click ‘Finish’
  22. m3-08
  23. Click ‘Restart Now’
  24. m3-09
  25. Select Window -> Preferences
  26. m3-11
  27. Add the Maven 3 location the you installed earlier
  28. m3-12
  29. Create a new Maven project by selecting File -> New -> Other…
  30. m3-13
  31. Select Maven -> Maven Project
  32. m3-14
  33. Check ‘Create a simple project (skip archetype selection)’
  34. Click ‘Next >’
  35. m3-24
  36. Enter Project Information
    1. Enter Group Id. This is the domain where the project is hosted. For example if the ‘Awesome’ project was hosted at GitHub then the Group Id would be ‘com.github.awesome’.
    2. Enter Artifact Id. This is the name of the resulting artifact. For example if Artifact Id is ‘awesome’ and the packaging is JAR the artifact will be named ‘awesome.jar’.
    3. The version can remain 0.0.1-SNAPSHOT
    4. Select the packaging that you desire
    5. Enter a Name. This name will show up in the console when you run Maven. This will also show up in the documentation that Maven generates
    6. Enter a Description. This is used in the documentation
    7. Click ‘Next >’
  37. m3-16
  38. Add a dependency on JUnit. One of the best features of m2eclipse plugin is the ability to search for available dependencies.  (This feature does not work if you configure ‘M3_HOME’ instead of ‘M2_HOME’)
  39. m3-17
  40. Click ‘Finish’
    • src – source and resource files
    • target – compiled files, reports and generated artifacts
    • main – application/library files
    • test – test files
    • java – java files
    • resources – non java files like XML
  41. m3-18
    Maven’s default package structure:
  42. Open the pom.xml file.
  43. Add the compiler plugin so you can configure your JDK version. Search for the maven-compiler-plugin.
  44. m3-20
  45. For this example set the JDK version to 1.6
  46. m3-21
  47. Run ‘Maven install’ to verify that the project and environment is setup correctly
  48. m3-22
  49. The build was successful
  50. m3-23 

Project Management

Parent POM

Parent POMs are an simple way to extract common configurations and reuse them in multiple projects. We will extract the compiler plugin configuration into a parent pom.
Create a new Maven Project with a packaging type of ‘pom’.
<project xmlns="" xmlns:xsi="" xsi:schemaLocation=""> <modelVersion>4.0.0</modelVersion> 
<name>Parent Sample POM</name>
<description>This contains common company settings for all projects.</description>
In the child pom file add the following
Note: Update the project configuration after you change the Java version. Right click your project -> Maven -> Update Project Configuration

Local Maven Repository

It’s a good idea for organizations to host their own local Maven repository. This provides more control over the hosting and management of project dependencies. This also provides a place to easily add third-party artifacts that may not be available in external Maven repositories.
I’m most familiar with Archiva so I will set it up in this tutorial. Nevertheless, there are other Build Artifact Repository Management software available such as Sonatype.
For this example I am going to follow the steps outlined in the Archiva Quick Start guide.
  1. Download and unzip Archiva
  2. archiva01
  3. Open a Commandline window
  4. Navigate to the ‘bin’ directory in the exploded Archiva directory
  5. Run ‘archiva.bat console’
  6. archiva02
  7. Setup a new Admin account
Add this repository to the ’settings.xml’ file in [Maven 3 Home]/conf. This sets Archiva as your dependency repository. Add this to the ‘mirrors’ section.
To publish your artifacts to Archiva add the following to the ’settings.xml’ file. Replace archiva-deployment-user with the Admin username (this is ‘admin’ by default) that you setup. Replace archiva-deployment-pwd withthe Admin password that you setup.
Add the following to the parent pom in the ‘parent-sample’ project. This tells your project where to publish it’s artifacts.
<name>Internal Release Repository</name>
<name>Internal Snapshot Repository</name>
Since the ‘distributionManagement’ information was modified you need to first run ‘mvn clean install’ on the ‘parent-example’ project. Then run ‘mvn clean deploy’ on the ‘example’ project. This will download the dependencies to the local Archiva dependency repository and publish the ‘example.jar’ to Archiva.
Navigate to http://localhost:8080/archiva/repository/snapshots/com/sourceallies/sample/sample/ to view the published files for the ‘example’ project.
Navigate to http://localhost:8080/archiva/repository/internal/ to view the dependencies that were downloaded during the installation of the ‘parent-example’ project and the deployment of the ‘example’ project. Refer to the Archiva Administration Guide for more details on hosting an internal Maven repository.

Multiple Artifacts from a Single Source

Maven restricts projects to one artifact per ‘pom’ file. While we can argue whether this is the right approach, there is a simple solution. If you have a project called ’sample-service’ that produces a WAR and you want to create a JAR from the same source code then you need to create a second package containing a single pom file.
The ’sample-client’ pom is configured to point to ’sample-service’ for it’s source files. This should be added to the ‘build-helper-maven-plugin’ configuration. Please refer to for more information.

Release Plugin

This is a very powerful plugin. If you’ve ever released a project by hand you will appreciate this plugin. One of my favorite features is that it checks to see if all of the dependencies refer to released versions. Without this automatic check you are forced to search through all of the dependency management configurations for unreleased dependencies. Depending on the size of your hierarchy this can be quite painful.
Along with this dependency check it also runs all of the tests, tags the code with the release name, and publishes the artifacts in the Maven repository. This plugin embodies the best standards for releasing within our industry. Standards that I easily forget and/or mess up. I highly recommend that you use this plugin to release your projects. Please refer to for more information.

Aggregate POM

An aggregate POM joins multiple modules together.
_pom.xml (aggregate)
|_pom.xml (module 1)
|_pom.xml (module 2)
The aggregate pom configures multiple modules in the modules section.
When you execute a Maven command at the aggregate level it will execute the same command on all of the configured modules. If any of these modules depends on another module Maven builds them in the correct order. This is a simple way to break up a large project into focused modules without loosing a coordinated project management strategy. While this could be replicated with Ant and Ivy it would be painful to configure and maintain. Aggregate projects are first class citizens in Maven.

Dependency Management

The ‘dependencymanagement’ section defines the acceptable versions for a project. This configuration does not result in a JAR being downloaded and included in the project. On the other hand, this is a directive specifying which version of a dependency should be used if a project depends on it. This is a simple way to force Maven to select a specific dependency version. In the case of an aggregate project it is best to add this to the aggregate pom. Configure the dependency versions in one place for all of the modules.

Distribution Zip

Maven provides a simple way to package all of your artifacts in a single zip file. This simplifies the deployment process and increases traceability. For example I have used this feature to package my WAR, SQL, and external PDF files in the same zip file. Our deployment team extracted the WAR and PDF files and deployed them. Then they passed the SQL on to the DBA’s to run the scripts. All of the files necessary to deploy our project were packaged together and published to our Maven repository. Please refer to for more information.