Maven is a Jakarta build project which is used for project management tool and report generation. It is an artifact manager and allows sharing of source code and binaries between projects. Benefits of using Maven are:

Standardization
Reuse across the organization
Dependency management
Plugin architecture

POM

A project is described using POM (Project Object Model) which is written in XML. It defines how to build a project and also defines the external dependencies. The project build results are created in the local repository where as the dependent JARs are downloaded from a remote repository. The Maven functionality is implemented in terms of plugins.

POM contains following:

Project information
Company information
List of developer and their roles
Mailing list and CVS server access
Source code and unit test code location
Definition of JAR dependencies
Resources needed for a build
Assembling of artifacts, e.g. JAR


The concept

Maven's concept is that the code written in a project is defined by a project descriptor (Project Object Model). The projects can be discrete components or they can be full applications.

POM is written in XML format specified by the maven-project.xsd XML Schema file. Normally it is a standard practice to copy an example POM (project.xml)from some Maven installation and then customize it for use. It serves the purpose and saves time. No need to write a POM from scratch.
Goals

If you have worked with Ant, then you must be knowing about targets. In Maven, targets are referred as goals. We can use goals to generate source code documentation, compile the application, perform unit test. We can also use targets to run the plug-ins shipped with Maven.

Consider that you have a project.xml defined in a project and you wish to see the project's available goals. Yes, you may simply open the file in some editor and find the goals. But there is command for that as well. Run the following command from the directory that contains the project.xml to find the available goals.

Java Code:
1
maven –g
It will return a list of plug-ins and their defined goals.
Output:
Java Code:
1
2
3
4
5
6
7
8
9
10
11
[java] ( NO DEFAULT GOAL )
  compile .................... Compile the project
  jar ........................ Create the deliverable jar file
  jar-resources .............. Copy any resources that must be present in the
                               deployed JAR file
  prepare-filesystem ......... Create the directory structure needed to compile
[javadoc] : Generate API documentation
  generate ................... Generate API documentation
[jdepend] : Generate a dependency report with JDepend
  generate-report ............ Generate a dependency report with JDepend
[junit-report] : Generate a report from the test results
Let me explain the output. The output shows the installed Maven plugins (names in brackets) and their defined goals (underneath the plugin names). For instance: Java is a plugin and compile, jar, jar-resources, prepare-filesystem are its goals. There is no default goal defined for java plugin. Similarly, javadoc is a plugin and generate is its goal. Lets say we want to run javadoc generate goal. Then the command will be as follows:

Java Code:
1
javadoc:generate
Since generate is the default goal of javadoc, you are not required to mention the goal’s name here. Even the following will serve the purpose:

Java Code:
1
maven javadoc
Additional goals can be defined in the maven.xml file. It is specific to each project and should reside in the same directory as project.xml. Maven uses <goal> tag to define the goals where as Ant uses <target> tag. The <goal> element has few attributes which are used to provide additional information like: attributes are there for providing goal’s name and a description. A goal can have a list of prerequisite goals that have to be executed before running a particular goal. The prereqs attribute specifies these goals. In the given example, jar goal is executed before prepare goal.

Java Code:
1
<goal name="runtime:prepare" prereqs="java:jar">
Goals can also be extended. This is useful for extending Maven's built-in goals. For instance: you might want to archive an old jar file when a new build is created.


Repositories

In Maven, projects can share dependencies which means that different project can use common jar files. These jar files will be updated over time and Maven keeps each project current with the latest jar file. These jar files will be placed in a repository on a remote server and are accessed by the projects. These files will be mirrored in a local repository under the Maven installation. The remote repository location is given in the driver.properties file which is located in your Maven installation's bin subdirectory. A property called maven.repo.remote takes a comma-separated list of URLs.

You may setup your repository by putting copies of internal jar files, private builds of open source projects, and other resources you might need.

Maven provides a repository element which is used in the project.xml to refer to the source control repository your project uses for storing its source.
Building project


First, prepare project.xml and maven.xml files for your project. Once done, run Maven from the command line from the directory that contains these files. Now Maven will start downloading the required jar files in to your local repository. It will create a target directory for storing its output. Maven uses javac to compile the source directory's contents to a subdirectory called classes under the target directory. Once done, it will start executing the unit tests configured in project.xml. On successful execution of the tests, it will create a jar file with the project's name and version in the target directory.
Documentation the project

Maven also provides support for creating documentation for your project. Run the following:

Java Code:
1
maven site:generate
On running this, Maven will create a subdirectory called docs under target. This will contain all the documentation generated. Open index.html and browse through. All the project information like: javadocs, unit-test information, source code cross referencing, a coding style check, metrics will be included in the web site generated.

Maven uses XDoc plug-in(maven/plugins/maven-xdoc-plugin-1.1/) for generating the website. If you wish to modify the look and feel, feel free to modify the CSS, images, and XML templates.

Setting Compiler Version

For setting the compiler version, review the following:

Java Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<project>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>

Running Unit Tests

The command mvn test is used to compile and run unit tests. The command mvn clean cobertura:cobertura generates a code-coverage report for the tests. It only works, if the pom.xml is configured as follows:

Java Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</project>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
</plugin>
</plugins>
</reporting>
</project>
Example

I will use project.xml included in Torque 3.0 beta 4 as an example. Review the code below:

Java Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<project>
<pomVersion>3</pomVersion>
<id >torque </id >
<name >jakarta-turbine-torque </name >
<currentVersion >3.0-b4 </currentVersion >
<organization >
<name >Apache Software Foundation </name >
<url >http://jakarta.apache.org/ </url >
<logo >/images/jakarta-logo-blue.gif </logo >
</organization >
<inceptionYear >2000 </inceptionYear >
<package >org.apache.torque </package >
<logo >/images/blue-logo.gif </logo >
<!-- Gump integration -- >
<gumpRepositoryId >jakarta </gumpRepositoryId >
<description >Torque is a persistence layer. </description >
<shortDescription >Persistence Layer </shortDescription >
<url >http://jakarta.apache.org/turbine/torque/ </url >
<issueTrackingUrl >http://issues.apache.org/scarab/servlet/scarab/ </issueTrackingUrl >
<siteAddress >jakarta.apache.org </siteAddress >
<siteDirectory >/www/jakarta.apache.org/turbine/torque/ </siteDirectory >
<distributionDirectory >/www/jakarta.apache.org/builds/jakarta-turbine-torque/ </distributionDirectory >
...
We start with a root element of <project>. The <pomVersion> element is used to give POM version. The <id> element is used to name jar files. The current tool version is appended with <id> tag's value to form the jar name torque-3.0-b4.jar. The <name> is a longer version of <id>. The company name is given using organization element and the logo can be using logo element.

Gump is a Jakarta Project build tool that helps build many interdependent projects. You probably aren't using it, so you can leave this element out. This description element is used to enter project relevant information that will go on the front page of the Website generated with Maven. Use shortDescription element to enter more details. The url element simply specifies the URL for the project. This may be useful if you have a web site hosted for your project.

You may use issueTrackingUrl element if you are using some web based issue/bug tracker like Jira.

Maven has the power to deploy the generated Website to another Web server. For this, use site:deploy goal.

Java Code:
1
2
<siteAddress >jakarta.apache.org </siteAddress >
<siteDirectory >/www/jakarta.apache.org/turbine/torque/ </siteDirectory >
We use distributionDirectory element to publish the entire distribution created by Maven to the Web server.

The code snippet below shows how to give you CVS connection. If you are using WebCVS or another Web-accessible CVS server, then URL element will prove to be very useful since developers that visit your site don't have to load CVS to get one or two source code files.

Java Code:
1
2
3
4
<repository >
<connection>scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:jakarta-turbine-torque </connection >
<url >http://cvs.apache.org/viewcvs/jakarta-turbine-torque/ </url >
</repository >
Modify the value of the mailingList XML elements below specific to your project. The <subscribe> and <unsubscribe> elements should be email addresses monitored by the list-manager software. The <archive> element can point to the URL for your mailing list's back emails.

Java Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<mailingLists >
<mailingList >
<name >Torque User List </name >
 <subscribe >...</subscribe >
 <unsubscribe >...</unsubscribe >
 <archive >...</archive >
</mailingList >
<mailingList >
<name >Torque Developer List </name >
 <subscribe >...</subscribe >
 <unsubscribe >...</unsubscribe >
 <archive >...</archive >
</mailingList >
</mailingLists >
Maven creates an HTML page that lists developers names which is useful for big companies.

Java Code:
1
2
3
4
5
6
7
8
9
10
11
12
<developers >
<developer >
<name >…</name >
<id >…</id >
<email >…</email >
<organization/ >
<roles >
<role >…</role >
</roles >
</developer >
</developers>
Maven can manage all jar file dependencies for the build machines. We use dependency element to refer to a jar file which reside in a remote repository. It is said that in near future, the dependencies will extend beyond jar files. Maven places the jar files (fetched from remote repository) on the local repository. The <dependency> element has three child elements, <id>, <version>, and <url>. Maven looks in the remote repository for a directory with the same name as the <id>. Under that directory, it looks for a jars subdirectory. Inside the jars directory should be a jar file that has the filename id-version.jar. In the given example, the defined first dependency will look for ant-1.4.1.jar in the remote repository. The url element is used for documentation only.

Java Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<dependencies >
<dependency >
<id >ant </id >
<version >1.4.1 </version >
<url >http://jakarta.apache.org/ant/ </url >
</dependency >
 
<dependency >
<id >commons-beanutils </id >
<version >1.4 </version >
</dependency >
 
<dependency >
<id >commons-collections </id >
<version >2.0 </version >
<url >http://jakarta.apache.org/commons/collections.html </url >
</dependency >
 
<dependency >
<id >commons-configuration </id >
<version >1.0-dev </version >
<url >http://jakarta.apache.org/commons/ </url >
</dependency >
<dependencies>
Source directory is mentioned using sourceDirectory element. Maven will simply compile the entire directory using the classpath it creates from the dependencies:

Java Code:
1
<sourceDirectory>src/java</sourceDirectory>
You may be using JUnit for unit testing. Maven can compile your unit tests but you have to use the following element to outline the tests directory
Java Code:
1
<unitTestSourceDirectory>src/test</unitTestSourceDirectory>

Summary

Maven is a coherent, standardized and effective way of organizing source code, libraries and fully deployable application artifacts within projects and enterprise organizations. It provides inter project sharing from repositories and all project setup and processes are
standardized across the organization.

Some interesting info for ANT guys is that you can start MAVEN from an ANT script and you can reuse ANT tasks in Maven.