Apache Maven

What is Apache Maven

Apache Maven is a project management tool, used for compiling and building Java projects, generating documentation and reports and manage versioning and dependencies of the project. It is similar to Apache Ant tool, but with much more features.

Where to start

First download Apache Maven from Apache servers and unzip to custom directory. Then you need to add ~/maven/bin directory to system path. I assume you already have Java installed on the system. Check if everything is working correctly:

$ mvn -version

Next thing you need to know is that Maven standard directory structure is a bit different as you know from regular Java projects:

MyProject
  +-- pom.xml
  +-- src
      +-- main
      |   +-- com
      |       +-- test
      |           +-- App.java
      +-- test
          +-- com
              +-- test
                  +-- AppTest.java

pom.xml

Project Object Model (or POM) file is a xml file that describes how the project should be built, parameters for building and dependencies (jars).

My first Maven project

Use the Maven to create new project with name MyProject:

$ mvn archetype:generate -DgroupId=com.test -DartifactId=MyProject -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Take a look at generated pom.xml file.

Build the project:

$ mvn package

Notice that directory target was created inside MyProject directory. Target directory contains generated classes, documentation and generated jar file.

Run the project:

$ java -cp target/MyApp-1.0-SNAPSHOT.jar com.test.App

Maven phases are similar to targets in Ant.

  • validate - validate the project
  • compile - compile the sources
  • test - perform unit tests on compiled sources
  • package - create jar from compiled sources
  • integration-test - deploy the package and perform integration tests
  • verify - verify the package
  • install - install the package in local repository to be used as dependency for other projects
  • deploy - deploy the package to working environment
  • clean - clean target directory
  • site - generate documentation

Many phases can be nested in one command:

$ mvn clean package site

Dependencies

Dependencies are jar files that your project needs to run, for example JSF libraries (jsf-api and jsf-impl). To include desired external libraries add the following definitions into pom.xml:

<project>
...
<dependencies>
...
<dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.2.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.2.7</version>
<scope>provided</scope>
</dependency>
...
</dependency>
...
</dependencies>
...
<project>

Set scope to provided for dependencies like servlet-api or jsp-api or jsf..., otherwise these jars will be exported to WEB-INF/lib (to avoid duplicating with server libraries).
It means that libraries will be provided by container or framework, here are just for the purpose of compiling.

Copy the all project dependencies to target/dependency directory:

$ mvn package dependency:copy-dependencies

Adding repositories

To add new repository to pom.xml add the following definitions:

<project>
...
<repositories>
...
<repository>
<id>JBoss repository</id>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
...
</repositories>
...
<project>

Plugins

Technically Maven is a platform for plugins, where each plugin is specialized for specific task. For example: to execute main method in built project, you need to define a plugin and use it as goal.

First add this to pom.xml:

<build>
...
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>com.test.MyApp</mainClass>
</configuration>
</plugin>
...
</plugins>
...
</build>

Run java application:

$ mvn exec:java

Add MANIFEST.MF file with Maven

To add manifest file in jar, use the following plugin:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>si.matjazcerkvenik.ftpsync.App</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>

Run Ant build.xml file with Maven

To run Ant build.xml file with maven, add the following plugin into pom.xml:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>deploy-ui</id>
<phase>prepare-package</phase>
<inherited>false</inherited>
<configuration>
<target>
<property name="buildDir" value="${project.build.directory}/${project.build.finalName}" />
<ant antfile="build.xml" target="myTarget" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>

Run the maven goal package and the ant build.xml should run during the prepare-package phase:

$ mvn package

Add jar to local repository

If you have the pom file, you can build jar file on your own. To install jar to local repository, simply execute the following maven command:

$ mvn install

If all you have is jar file, then install it to local repository, with command:

$ mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>

At the end, add installed jar to your project as new dependency.

To remove installed jar just delete a directory in ~/.m2 directory (rm -rf ~/.m2/repository/org.*).

Deploying on Tomcat 6

To deploy your application on Tomcat server, you must first configure Tomcat and Maven authentication. In file $TOMCAT_HOME/conf/tomcat-users.xml enable admin user. This user must have the admin permissions to deploy an application to the server (Tomcat 6):

<tomcat-users>
<user username="tomcat" password="tomcat" roles="manager,admin" />
</tomcat-users>

Remark: on Tomcat 7 use following roles:

<tomcat-users>
<user username="tomcat" password="tomcat" roles="manager-gui,manager-status,manager-script,admin" />
</tomcat-users>

Then you need to add tomcat admin credentials to maven configuration in file ~/.m2/settings.xml:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
...
<servers>
<server>
<id>TomcatServer6</id>
<username>tomcat</username>
<password>tomcat</password>
</server>
</servers>
...
</settings>

Add a plugin into pom.xml to allow deploying on Tomcat:

<plugin>
<groupId>my.test.project</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<configuration>
<url>http://127.0.0.1:8080/manager</url>
<server>TomcatServer6</server>
<path>/MyJeeApp</path>
</configuration>
</plugin>

Execute goal (Tomcat must be running):

$ mvn tomcat:deploy

To undeploy execute goal:

$ mvn tomcat:undeploy

Deploying on Tomcat 7

The same as Tomcat 6, except I had some problems with tomcat user roles and tomcat url.

Use following roles in tomcat-users.xml:

<tomcat-users>
<user username="tomcat" password="tomcat" roles="manager-gui,manager-status,manager-script,admin" />
</tomcat-users>

Url in pom.xml is slightly different (/text at the end):

<url>http://127.0.0.1:8080/manager/text</url>

Deploying on JBOSS

To deploy your application on JBOSS server, you must first add the plugin into the pom.xml:

<project>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.5.Final</version>
</plugin>
...
</plugins>
...
</build>
...
</project>

Then you can execute goal:

$ mvn jboss-as:deploy

To redeploy or undeploy use:

$ mvn jboss-as:redeploy
$ mvn jboss-as:undeploy