Maven
Maven
What is Maven?
Maven is a project management and comprehension tool. Maven provides developers a complete build lifecycle framework. Development team can automate the project's build infrastructure in almost no time as Maven uses a standard directory layout and a default build lifecycle. In case of multiple development teams environment, Maven can set-up the way to work as per standards in a very short time. As most of the project setups are simple and reusable, Maven makes life of developer easy while creating reports, checks, build and testing automation setups. Maven provides developers ways to manage following: Builds Documentation Reporting Dependencies SCMs Releases Distribution mailing list
To summarize, Maven simplifies and standardizes the project build process. It handles compilation, distribution, documentation, team collaboration and other tasks seamlessly. Maven increases reusability and takes care of most of build related tasks.
Maven History
Maven was originally designed to simplify building processes in Jakarta Turbine project. There were several projects and each project contained slightly different ANT build files. JARs were checked into CVS. Apache group then developed Maven which can build multiple projects together, publish projects information, deploy projects, share JARs across several projects and help in collaboration of teams.
Maven Objective
Maven primary goal is to provide developer A comprehensive model for projects which is reusable, maintainable, and easier to comprehend. plugins or tools that interact with this declarative model.
Maven project structure and contents are declared in an xml file, pom.xml referred as Project Object Model (POM), which is the fundamental unit of the entire Maven system.
In order to build the project, Maven provides developers options to mention life-cycle goals and project dependencies (that rely on Maven pluging capabilities and on its default conventions). Much of the project management and build related tasks are maintained by Maven plugins. Developers can build any given Maven project without need to understand how the individual plugins work.
ENVIRONMENTSETUP
Maven is Java based tool, so the very first requirement is to have JDK installed in your machine.
System Requirement
JDK Memory Disk Space Operating System 1.5 or above no minimum requirement no minimum requirement no minimum requirement
Let's verify the output for all the operating systems: OS Windows Output java version "1.6.0_21" Java(TM) SE Runtime Environment (build 1.6.0_21-b07) Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing) java version "1.6.0_21" Java(TM) SE Runtime Environment (build 1.6.0_21-b07) Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing) java version "1.6.0_21" Java(TM) SE Runtime Environment (build 1.6.0_21-b07) Java HotSpot(TM)64-Bit Server VM (build 17.0-b17, mixed mode, sharing)
Linux
Mac
If you do not have Java installed, install the Java Software Development Kit (SDK) from http://www.oracle.com/technetwork/java/javase/downloads/index.html . We are assuming Java 1.6.0_21 as installed version for this tutorial.
Append Java compiler location to System Path. OS Windows Linux Mac Output Append the string ;C:\Program Files\Java\jdk1.6.0_21\bin to the end of the system variable, Path. export PATH=$PATH:$JAVA_HOME/bin/ not required
Linux
Mac
Finally, verify the output of the above commands, which should be something as follows: OS Windows Output Apache Maven 2.2.1 (r801777; 2009-08-07 00:46:01+0530) Java version: 1.6.0_21 Java home: C:\Program Files\Java\jdk1.6.0_21\jre Apache Maven 2.2.1 (r801777; 2009-08-07 00:46:01+0530) Java version: 1.6.0_21 Java home: C:\Program Files\Java\jdk1.6.0_21\jre Apache Maven 2.2.1 (r801777; 2009-08-07 00:46:01+0530) Java version: 1.6.0_21 Java home: C:\Program Files\Java\jdk1.6.0_21\jre
Linux
Mac
Congratulations! you are now all set to use Apache Maven for your projects.
MAVEN POM
POM stands for Project Object Model. It is fundamental Unit of Work in Maven. It is an XML file. It always resides in the base directory of the project as pom.xml. The POM contains information about the project and various configuration details used by Maven to build the project(s). POM also contains the goals and plugins. While executing a task or goal, Maven looks for the POM in the current directory. It reads the POM, gets the needed configuration information, then executes the goal. Some of the configuration that can be specified in the POM are following: project dependencies plugins goals build profiles project version
Before creating a POM, we should first decide the project group (groupId), its name (artifactId) and its version as these attributes help in uniquely identifying the project in repository.
Example POM
<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>com.companyname.project-group</groupId> <artifactId>project</artifactId> <version>1.0</version> </project>
It should be noted that there should be a single POM file for each project. All POM files require the project element and three mandatory fields: groupId, artifactId,version. Projects notation in repository is groupId:artifactId:version. Root element of POM.xml is project and it has three major sub-nodes : Description This is an Id of project's group. This is generally unique amongst an organization or a project. For example, a banking group com.company.bank has all bank related projects. This is an Id of the project.This is generally name of the project. For example, consumer-banking. Along with the groupId, the artifactId defines the artifact's location within the repository. This is the version of the project.Along with the groupId, It is used within an artifact's repository to separate versions from each other. For example: com.company.bank:consumer-banking:1.0 com.company.bank:consumer-banking:1.1.
Node groupId
artifactId
version
Super POM
All POMs inherit from a parent (despite explicitly defined or not). This base POM is known as the Super POM, and contains values inherited by default. Maven use the effective pom (configuration from super pom plus project configuration)to execute relevant goal. It helps developer to specify minimum configuration details in his/herpom.xml. Although configurations can be overridden easily. An easy way to look at the default configurations of the super POM is by running the following command: mvn help:effective-pom Create a pom.xml in any directory on your computer. Use the content of above mentioned example pom. In example below, We've created a pom.xml in C:\MVN\project folder. Now open command console, go the folder containing pom.xml and execute the following mvn command.
C:\MVN\project>mvn help:effective-pom
-----------------------------------------------------------------------BUILD SUCCESSFUL -----------------------------------------------------------------------Total time: < 1 second Finished at: Thu Jul 05 11:41:51 IST 2012 Final Memory: 6M/15M ------------------------------------------------------------------------
Effective POM displayed as result in console, after inheritance, interpolation, and profiles are applied.
<?xml version="1.0"encoding="UTF-8"?> <!-- ================================================================= <!-<!-- Generated by Maven Help Plugin on 2012-07-05T11:41:51 <!-- See: http://maven.apache.org/plugins/maven-help-plugin/ <!-<!-- ================================================================= <!-- ================================================================= <!-<!-- Effective POM for project <!-- 'com.companyname.project-group:project-name:jar:1.0' <!-<!-- ================================================================= <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance" 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>com.companyname.project-group</groupId> <artifactId>project</artifactId> <version>1.0</version> <build> <sourceDirectory>C:\MVN\project\src\main\java</sourceDirectory> <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory> <testSourceDirectory>C:\MVN\project\src\test\java</testSourceDirectory> <outputDirectory>C:\MVN\project\target\classes</outputDirectory> <testOutputDirectory> C:\MVN\project\target\testclasses </testOutputDirectory> <resources> <resource> <mergeId>resource-0</mergeId> <directory>C:\MVN\project\src\main\resources</directory> </resource> </resources> <testResources> <testResource> <mergeId>resource-1</mergeId> <directory>C:\MVN\project\src\test\resources</directory> </testResource> </testResources> <directory>C:\MVN\project\target</directory> <finalName>project-1.0</finalName> <pluginManagement> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.3</version> </plugin> <plugin> --> --> --> --> --> --> --> --> --> --> --> -->
<artifactId>maven-assembly-plugin</artifactId> <version>2.2-beta-2</version> </plugin> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> </plugin> <plugin> <artifactId>maven-dependency-plugin</artifactId> <version>2.0</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.4</version> </plugin> <plugin> <artifactId>maven-ear-plugin</artifactId> <version>2.3.1</version> </plugin> <plugin> <artifactId>maven-ejb-plugin</artifactId> <version>2.1</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <artifactId>maven-javadoc-plugin</artifactId> <version>2.5</version> </plugin> <plugin> <artifactId>maven-plugin-plugin</artifactId> <version>2.4.3</version> </plugin> <plugin> <artifactId>maven-rar-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <artifactId>maven-release-plugin</artifactId> <version>2.0-beta-8</version> </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.3</version> </plugin>
<plugin> <artifactId>maven-site-plugin</artifactId> <version>2.0-beta-7</version> </plugin> <plugin> <artifactId>maven-source-plugin</artifactId> <version>2.0.4</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.4.3</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.1-alpha-2</version> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <artifactId>maven-help-plugin</artifactId> <version>2.1.1</version> </plugin> </plugins> </build> <repositories> <repository> <snapshots> <enabled>false</enabled> </snapshots> <id>central</id> <name>Maven Repository Switchboard </name> <url>http://repo1.maven.org/maven2 </url> </repository> </repositories> <pluginRepositories> <pluginRepository> <releases> <updatePolicy>never</updatePolicy> </releases> <snapshots> <enabled>false</enabled> </snapshots> <id>central</id> <name>Maven Plugin Repository</name> <url>http://repo1.maven.org/maven2 </url> </pluginRepository> </pluginRepositories> <reporting> <outputDirectory>C:\MVN\project\target/site</outputDirectory> </reporting> </project>
In above pom.xml , you can see the default project source folders structure, output directory, plug-ins required, repositories, reporting directory which Maven will be using while executing the desired goals. Maven pom.xml is also not required to be written manually. Maven provides numerous archetype plugins to create projects which in order create the project structure and pom.xml
There are always pre and post phases which can be used to register goals which must run prior to or after a particular phase. When Maven starts building a project, it steps through a defined sequence of phases and executes goals which are registered with each phase. Maven has following three standard lifecycles: clean default(or build) site
A goal represents a specific task which contributes to the building and managing of a project. It may be bound to zero or more build phases. A goal not bound to any build phase could be executed outside of the build lifecycle by direct invocation. The order of execution depends on the order in which the goal(s) and the build phase(s) are invoked. For example, consider the command below. The clean and package arguments are build phases while the dependency: copy-dependencies is a goal.
Here the clean phase will be executed first, and then the dependency:copy-dependencies goal will be executed, and finally package phase will be executed.
Clean Lifecycle
When we execute mvn post-clean command, Maven invokes the clean lifecycle consisting of the following phases. pre-clean clean post-clean
Maven clean goal (clean:clean) is bound to the clean phase in the clean lifecycle. Its clean:clean goal deletes the output of a build by deleting the build directory. Thus when mvn clean command executes, Maven deletes the build directory. We can customize this behavior by mentioning goals in any of the above phases of clean life cycle. In the following example, We'll attach maven-antrun-plugin:run goal to the pre-clean, clean, and post-clean phases. This will allow us to echo text messages displaying the phases of the clean lifecycle. We've created a pom.xml in C:\MVN\project folder.
<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>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> <execution> <id>id.pre-clean</id> <phase>pre-clean</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>pre-clean phase</echo> </tasks> </configuration>
</execution> <execution> <id>id.clean</id> <phase>clean</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>clean phase</echo> </tasks> </configuration> </execution> <execution> <id>id.post-clean</id> <phase>post-clean</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>post-clean phase</echo> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
Now open command console, go to the folder containing pom.xml and execute the following mvn command.
C:\MVN\project>mvn post-clean
Maven will start processing and display all the phases of clean life cycle
[INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [echo] [INFO] [INFO] [INFO] [INFO] [echo] [INFO] [INFO] Scanning for projects... -----------------------------------------------------------------Building Unnamed - com.companyname.projectgroup:project:jar:1.0 task-segment: [post-clean] -----------------------------------------------------------------[antrun:run {execution: id.pre-clean}] Executing tasks pre-clean phase Executed tasks [clean:clean {execution: default-clean}] [antrun:run {execution: id.clean}] Executing tasks clean phase Executed tasks [antrun:run {execution: id.post-clean}]
[INFO] [echo] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO]
Executing tasks post-clean phase Executed tasks -----------------------------------------------------------------BUILD SUCCESSFUL -----------------------------------------------------------------Total time: < 1 second Finished at: Sat Jul 07 13:38:59 IST 2012 Final Memory: 4M/44M ------------------------------------------------------------------
You can try tuning mvn clean command which will display pre-clean and clean, nothing will be executed for post-clean phase.
install deploy
Install the package into the local repository, which can be used as a dependency in other projects locally. Copies the final package to the remote repository for sharing with other developers and projects.
There are few important concepts related to Maven Lifecycles which are wroth to mention: When a phase is called via Maven command, for example mvn compile, only phases up to and including that phase will execute. Different maven goals will be bound to different phases of Maven lifecycle depending upon the type of packaging (JAR / WAR / EAR).
In the following example, We'll attach maven-antrun-plugin:run goal to few of the phases of Build lifecycle. This will allow us to echo text messages displaying the phases of the lifecycle. We've updated pom.xml in C:\MVN\project folder.
<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>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> <execution> <id>id.validate</id> <phase>validate</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>validate phase</echo> </tasks> </configuration> </execution> <execution> <id>id.compile</id> <phase>compile</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks>
<echo>compile phase</echo> </tasks> </configuration> </execution> <execution> <id>id.test</id> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>test phase</echo> </tasks> </configuration> </execution> <execution> <id>id.package</id> <phase>package</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>package phase</echo> </tasks> </configuration> </execution> <execution> <id>id.deploy</id> <phase>deploy</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>deploy phase</echo> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
Now open command console, go the folder containing pom.xml and execute the following mvn command.
C:\MVN\project>mvn compile
Maven will start processing and display phases of build life cycle up to compile phase.
[INFO] Scanning for projects... [INFO] -----------------------------------------------------------------[INFO] Building Unnamed - com.companyname.projectgroup:project:jar:1.0 [INFO] task-segment: [compile] [INFO] -----------------------------------------------------------------[INFO] [antrun:run {execution: id.validate}] [INFO] Executing tasks [echo] validate phase [INFO] Executed tasks [INFO] [resources:resources {execution: default-resources}] [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory C:\MVN\project\src\main\resources [INFO] [compiler:compile {execution: default-compile}] [INFO] Nothing to compile - all classes are up to date [INFO] [antrun:run {execution: id.compile}] [INFO] Executing tasks [echo] compile phase [INFO] Executed tasks [INFO] -----------------------------------------------------------------[INFO] BUILD SUCCESSFUL [INFO] -----------------------------------------------------------------[INFO] Total time: 2 seconds [INFO] Finished at: Sat Jul 07 20:18:25 IST 2012 [INFO] Final Memory: 7M/64M [INFO] ------------------------------------------------------------------
Site Lifecycle
Maven Site plugin is generally used to create fresh documentation to create reports, deploy site etc. Phases pre-site site post-site site-deploy
In the following example, We'll attach maven-antrun-plugin:run goal to all the phases of Site lifecycle. This will allow us to echo text messages displaying the phases of the lifecycle. We've updated pom.xml in C:\MVN\project folder.
<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>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <build>
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> <execution> <id>id.pre-site</id> <phase>pre-site</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>pre-site phase</echo> </tasks> </configuration> </execution> <execution> <id>id.site</id> <phase>site</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>site phase</echo> </tasks> </configuration> </execution> <execution> <id>id.post-site</id> <phase>post-site</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>post-site phase</echo> </tasks> </configuration> </execution> <execution> <id>id.site-deploy</id> <phase>site-deploy</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>site-deploy phase</echo> </tasks> </configuration> </execution> </executions>
Now open command console, go the folder containing pom.xml and execute the following mvn command.
C:\MVN\project>mvn site
Maven will start processing and display phases of site life cycle up to site phase.
[INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [echo] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [echo] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] Scanning for projects... -----------------------------------------------------------------Building Unnamed - com.companyname.projectgroup:project:jar:1.0 task-segment: [site] -----------------------------------------------------------------[antrun:run {execution: id.pre-site}] Executing tasks pre-site phase Executed tasks [site:site {execution: default-site}] Generating "About" report. Generating "Issue Tracking" report. Generating "Project Team" report. Generating "Dependencies" report. Generating "Project Plugins" report. Generating "Continuous Integration" report. Generating "Source Repository" report. Generating "Project License" report. Generating "Mailing Lists" report. Generating "Plugin Management" report. Generating "Project Summary" report. [antrun:run {execution: id.site}] Executing tasks site phase Executed tasks -----------------------------------------------------------------BUILD SUCCESSFUL -----------------------------------------------------------------Total time: 3 seconds Finished at: Sat Jul 07 15:25:10 IST 2012 Final Memory: 24M/149M ------------------------------------------------------------------