Maven : Setup and Basics

Maven is a build automation tool used primarily for Java projects. It can also be used as a project management tool. Here we will only focus on how maven is used as a build tool. It help us to do following common activities in a typical project easily :

  • Compiling source code
  • Multiple jars – Takes cares of all the jars that is required by a project
  • Dependencies and version – If a jar is dependent on other jars or likewise, it handles that as well
  • Project structure
  • Building, publishing and deploying

Let get started. Download maven from here. I downloaded the 3.1.1 version.

Download the zip file and extract it. Now you have to setup some variables:

M2_HOME – Create a new variable and the value will be the path where you have extracted maven ( like C:\Learning\apache-maven-3.1.1)

Path – Append the maven bin folder path to this already existing variable.

To test open up the command prompt/terminal and run $mvn  version to check what the version is.

You may also be asked to have a JAVA_HOME path which is your path of java. Also make sure that your machine is connected to the internet as maven gets most of the things online, if its not present in your local repository.

Lets now create a directory for testing purpose and from that directory generate an archetype:

$mkdir MavenTest

$cd MavenTest

$mvn archetype:generate

This will scan for projects and gives a list of all the archetype that you can choose from. An archetype is a modal of how you want to be your project structure. Maven has predefine project structures for you to choose and maven will download all the jars and dependencies related to the archetype.

Right now lets go with the default, which is a quickstart maven project.  Just hit enter (For me it was 347, this number might be different for you).

Now it will ask for the version that you want to go, default being the latest. Lets go with that. Just hit enter.

Now you have to define values for few properties:

  • groupId – package name
  • packageId – Name of the whole project.
  • version – Lets go with the default snapshot. Note that snapshot is generally used if your project is in development stage. This is usually removed when its ready for release. Its a good practice. In case of Version, if Maven once downloaded the mentioned version say data-service:1.0, it will never try to download a newer 1.0 available in repository. To download the updated code, data-service version is be upgraded to 1.1. In case of SNAPSHOT, Maven will automatically fetch the latest SNAPSHOT (data-service:1.0-SNAPSHOT) every-time team build their project.
  • package – lets go with the default

Now it will ask for confirmation, type ‘Y’ and enter.

Maven01-archetypeGenerate

Maven has generated a project structure for us. Lets have a look :

Maven02-projectStructure

Inside our project directory we have a src folder and pom.xml. Main folder contains your main java classes that needs to be compiled and package. the test folder contains your JUnit. The App.java here is a simple POJO with “Hello World!” written in sysout.

Maven projects are configured using a Project Object Model, which is stored in a pom.xml file. The POM file describes what to build, but most often not how to build it. How to build it is up to the Maven build phases and goals. You can insert custom actions (goals) into the Maven build phase if you need to, though. pom.xml should be located in the root directory of your project. A project divided into subprojects will typically have one POM file for the parent project, and one POM file for each subproject. Let us see the pom.xml created for the above project:


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

<groupId>mynotes.maven.test</groupId>
 <artifactId>MyFirstProject</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>jar</packaging>

<name>MyFirstProject</name>
 <url>http://maven.apache.org</url>

<properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

<dependencies>
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>3.8.1</version>
 <scope>test</scope>
 </dependency>
 </dependencies>
</project>

Note that the packaging is ‘jar’. The only dependencies for now is that on junit. A project’s fully qualified artifact name  is  <groupId>:<artifactId>:<version>. So we have to use this combination in our dependencies and also in our project which could be used in other projects. Notice the <scope> tag inside the dependency which for junit is test meaning that this dependency is only require in test phase. We wll see different phases in maven in a while. Also, we only need to add those dependencies here which out project directly depends upon. if Junit depends on some other jars internally, we dont have to take care of that, maven does it for us.

Let us compile this project. To compile make sure you are at the root of the project where your pom.xml is and run the following command:

$mvn compile

Maven03-compileResult

Notice the new folder ‘target’ that has been created with out class file. Lets package this now using

$mvn package

Maven04-packageResult

Notice that the jar is now created inside the target folder. Also, maven has executed Junit test cases. Lets run the jar now

Maven05-runClass

Every build will have a lifecycle and a buld lifecycle has been seperated into different phases. If you donot explicitly configure it maven chooses the default build lifecycle. ‘Compile’ is a phase, similarly ‘package’ is also a phase. There is a default behaviour for all phases, like when you do a compile, maven assumes that it has to compile all the java files that are in the ‘main’ folder. Also, if you directly jump to a phase, previous phases are called automatically. Like lets take 3 phases- compile, test, package. Now if you choose to do a ‘mvn package directly, previous phases like ‘mvn compile’ will run automatically and on success of that only next phase will run till it gets to the current phase.

Some of the important 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.
  • install: install the package into the local repository (~\m2\repository on your local machine), for use as a dependency in other projects locally. Note that it does not deploy your code to the server.
  • deploy: done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects. Note that it does not deploy your code to the server.

Convention over Configuration

Maven uses Convention over Configuration which means developers are not required to create build process themselves.

Developers do not have to mention each and every configuration detail. Maven provides sensible default behavior for projects. When a Maven project is created, Maven creates default project strcture. Developer is only required to place files accordingly and he/she need not to define any configuration in pom.xml.

As an example, following table shows the default values for project source code files, resource files and other configurations. Assuming, ${basedir} denotes the project location:

Item Default
source code ${basedir}/src/main/java
resources ${basedir}/src/main/resources
Tests ${basedir}/src/test
Complied byte code ${basedir}/target
distributable JAR ${basedir}/target/classes

Maven compared with Ant

Ant uses an imperative approach, meaning you specify in the Ant build file what actions Ant should take. You can specify low level actions like copying files, compiling code etc. You specify the actions, and you also specify the sequence in which they are carried out. Ant has no default directory layout. The fundamental difference between Maven and Ant is that Maven’s design regards all projects as having a certain structure and a set of supported task work-flows (e.g., getting resources from source control, compiling the project, unit testing, etc.).

An Ant file describes how to build your project. In Maven, how to build your project is predefined in the Maven Build Life Cycles, Phases and Goals.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: