6 min read

 This article is written by Lorenzo Anardu, Roberto Baldi, Umberto Antonio Cicero, Riccardo Giomi, and Giacomo Veneri, the authors of the book, Maven Build Customization. A lifecycle is a sequence of phases. In each phase, depending on the POM configuration, one or more tasks are executed. These tasks are called goals. Despite the enormous variety of work that can be accomplished by Maven, there are only three built-in Maven lifecycles: default, clean, and site.

(For more resources related to this topic, see here.)

In this article, we will discuss the default lifecycle. The default lifecycle is responsible for the build process, so it’s the most interesting. Among its phases, the most important phases are described in the following table:

Phase

Actions

process-resources

Filter the resource files and copy them in the output directory

compile

Compile the source code

process-test-resources

Filter the test resource files and copy them in the test output directory

test-compile

Compile the test source code

test

Run the unit tests

package

Produce the packaged artifact (JAR, WAR, EAR)

install

Install the package in the local repository so that other projects can use it as a dependency

deploy

Install the package in a remote repository

We’ll speak later about local and remote Maven repositories.

When we invoke one phase from the command line, Maven executes all the phases of the lifecycle from the beginning up to the specified phase (included). In fact, one of the most common ways to run Maven is just to use the following syntax:

$ mvn <phase>

It will run all the portions of the respective lifecycle, ending with this phase.

Let’s consider an example. Suppose that the POM file of our transportation-acq-ejb module is the following, and it is located in the /transportation-project/transportation-acq-ejb directory:

<project   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>
   <parent>
       <groupId>com.packt.examples</groupId>
       <artifactId>transportation-project</artifactId>
       <version>0.0.1-SNAPSHOT</version>
 </parent>
   <artifactId>transportation-acq-ejb</artifactId>
   <packaging>jar</packaging>
   <name>transportation-acq-ejb</name>
   <dependencies>
       <dependency>
           <groupId>javax</groupId>
           <artifactId>javaee-api</artifactId>
           <version>6.0</version>
           <scope>provided</scope>
       </dependency>
   </dependencies>
</project>

As we can see in the preceding code, the transportation-acq-ejb module’s parent is the transportation-project parent project. We can add some sample Java classes and interfaces in the transportation-acq-ejb project. First, we add an EJB local interface, MyEjb.java:

package com.packt.samples;

import javax.ejb.Local;

@Local
public interface MyEjb
{
   public int myMethod();
}

Then, we add a dummy implementation, MyEjbImpl.java:

package com.packt.samples;

import javax.ejb.Stateless;

@Stateless
public class MyEjbImpl implements MyEjb
{

   @Override
   public int myMethod()
   {        
       return 0;
   }
}

Finally, we add a unit test class, SampleTest.java:

package com.packt.samples;

import static org.junit.Assert.*;

import org.junit.Test;

public class SampleTest
{
   @Test
   public void test()
   {
       assertTrue(true);
   }
}

The directory structure of the transportation-acq-ejb module is as shown in the following screenshot:

Maven Build Customization

In a Maven project, we have to put the project sources under /src/main/java and the test sources under /src/main/test. These default conventional values can be overridden, but this is not recommended; remember the convention over configuration paradigm!

Execute the following command:

$ mvn install

We’ll see the following output after executing the preceding command:

[INFO] Scanning for projects...
[...]
[INFO] -----------------------------------------------------------
[INFO] Building transportation-acq-ejb 0.0.1-SNAPSHOT
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ transportation-acq-ejb ---
[…]
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ transportation-acq-ejb ---
[INFO] Compiling 2 source files to ~/transportation-project/transportation-acq-ejb/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ transportation-acq-ejb ---
[…]
[INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ transportation-acq-ejb ---
[INFO] Compiling 1 source file to ~/transportation-project/transportation-acq-ejb/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.17:test (default-test) @ transportation-acq-ejb ---
[INFO] Surefire report directory: ~/transportation-project/transportation-acq-ejb/target/surefire-reports-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.packt.samples.SampleTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.032 sec - in com.packt.samples.SampleTest

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ transportation-acq-ejb ---
[INFO] Building jar: ~/transportation-project/transportation-acq-ejb/target/transportation-acq-ejb-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ transportation-acq-ejb ---
[INFO] Installing ~/transportation-project/transportation-acq-ejb-0.0.1-SNAPSHOT.jar to ~/.m2/repository/com/packt/examples/transportation-acq-ejb/0.0.1-SNAPSHOT
/transportation-acq-ejb-0.0.1-SNAPSHOT.jar
[INFO] Installing ~/transportation-project/transportation-acq-ejb/pom.xml to ~/.m2/repository/com/packt/examples/transportation-acq-ejb/0.0.1-SNAPSHOT/transportation-acq-ejb-0.0.1-SNAPSHOT.pom
[INFO] -----------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] -----------------------------------------------------------

If we run Maven for the first time, in addition to the preceding output shown, we’ll see a lot of other output lines saying that project plugins and dependencies are being downloaded from the Maven central repository.

So, as we can see, the sequence of operations performed by Maven follows the steps specified in the default lifecycle. You will also notice that each action performed by Maven is delegated to a certain plugin. In order to compile the project, Maven will download and use the specified dependencies (in this case, Java EE API is needed to compile the EJB classes). Plugins and dependencies are downloaded on-demand, and they are saved in the local repository, which is located under the local user home in the /.m2/repository subdirectory by default.

For Linux users, the local repository is located under ~/.m2/repository, where ~ means the user home directory that usually has the /home/<username> path.

For Windows users, the local repository is (usually) located under C:Users<username>.m2repository.

Once Maven downloads an artifact or a plugin, it will reuse its stored copy and never search the same version of this artifact or plugin in the Maven central repository or in other remote repositories that can be specified in our POM file again. The only exception to this rule regarding the snapshot versions is that if the version of a dependency or plugin is marked with the -SNAPSHOT suffix, this version is currently on development. For this reason, Maven will periodically attempt to download this artifact from all the remote repositories that have snapshots enabled in their configurations.

If we look in the /target directory, we’ll see all the work done by Maven; in this case, the compiled classes, unit test reports, and packaged artifact transportation-acq-ejb-0.0.1-SNAPSHOT.jar:

Maven Build CustomizationBuild output of the transportation-acq-ejb module

Note that if instead of running the previous command, we run the mvn package command, the lifecycle execution will stop with the package phase and the artifact will not be installed in the local repository. This can be a problem if the artifact is needed by other projects as a dependency.

Summary

In this article, we saw that every Maven build process relies on a skeleton called build lifecycle and we discussed the default lifecycle.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here