Intro to Apache Maven

July 26, 2020

background

Apache Maven is a build automation tool, extensively used in Java projects. It is also known for its Dependency Management feature. Other build and dependency management tools like Apache Gradle and Apache Ivy uses the key concepts behind Maven.


Install Maven

  • Make sure you have Java installed in your machine and JAVA_HOME env variable is set
  • Go to this URL and Download Maven (https://maven.apache.org/download.cgi)
  • Extract the zip file using this command unzip apache-maven-3.6.3-bin.zip
  • Add the bin directory of the created directory apache-maven-3.6.3 to the PATH environment variable
  • Confirm the installation by entering mvn -v in a new tab

If you're using Mac OS, you can use homebrew to install maven.

  • brew install maven to install maven
  • brew services start maven to start maven

After a successful installation, you should be able to see something similar to this when you enter mvn -v in your terminal.

Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /usr/local/Cellar/maven/3.6.3_1/libexec
Java version: 14.0.1, vendor: N/A, runtime: /usr/local/Cellar/openjdk/14.0.1/libexec/openjdk.jdk/Contents/Home
Default locale: en_IN, platform encoding: UTF-8
OS name: "mac os x", version: "10.14.4", arch: "x86_64", family: "mac"

When should we use Maven?

  • If there are multiple dependencies for a project
  • If the dependency version updates frequently
  • To ease the process of Continuous Integration, Deployment and testing

Creating a Maven Project

If you are using an IDE like Eclipse or IntelliJ IDEA it is easy to create Maven projects.

For IntelliJ IDEA choose File -> New -> Project. Choose Maven and after naming the project click Finish.

You can also run the following Maven command to create a new Maven Project.

mvn -B archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.first.app -DartifactId=maven-demo

Here, Archetype is a sample project template, GroupId denotes the group/package your project comes under artifactId is the name of your project.

It'll take maven sometime to execute this command as it will download all the necessary packages and plugins from the Central Maven Repository. After the project is created(either in IDE or terminal) open the project folder and you can see the pom.xml file.


Need for pom.xml file

The POM stands for Project Object Model and contains all the details about your project and the dependencies it needs. We can also tell maven to execute certain tasks using the pom.xml file.

The pom.xml file will look like this,

<?xml version="1.0" encoding="UTF-8"?>
<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.karthickram</groupId>
    <artifactId>maven-demo</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>

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

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <configuration>
            <source>9</source>
            <target>9</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
</project>

Here,

  • packaging is the packaging format of the project. The default type of packaging is jar. Other options are tar, war, etc.
  • version indicates the version number of this project. If the version has SNAPSHOT in it, then it means that the project is still in development and not yet stable.
  • dependencies contains a list of dependency. Each and every dependency will be identified based on the groupId, artifactId, and version of the dependency project.
  • build contains the build configuration of this project in the form of plugins. Here, I've specified a compiler plugin and I've specified that the source and target as 9, which means the source and the compilation should be in Java 9 version.

Maven Architecture

As shown in this architecture diagram, for each dependency you add in your pom.xml file, maven downloads it from the Central Maven Repository(https://mvnrepository.com) (or) the Remote Repository and stores it in your local repository so that you can use that for your project. The interesting thing to note here is since it keeps a copy in your local repository the next time you add the same dependency for another project it won't download the dependency again. It'll simply use the copy which was download previously. Hence saving time and memory.


Src and target

The project tree structure for the maven project will be like this,

Project Main Directory
|
|-- src
|    |
|    |-- main
|    |    |
|    |    |-- java
|    |    |
|    |    |-- resources
|    |
|    |-- test
|          |
|          |-- java
|
|-- target
|    |
|    |-- classes
|
|-- pom.xml

Whenever you run the command mvn clean install maven does the following steps

  • Removes all the class files generated by the previous build
  • It will put the compiled java classes inside target/classes folder
  • It will build a .jar or .war file that lives in the target folder

Maven Build Lifecycle

Maven follows a specific life cycle to deploy and distribute the artifacts. It has the following 3 lifecycles,

  • default - This is the one that is responsible for project deployment.
  • clean - This is used to clean the project and removes the files generated by previous builds.
  • site - This is responsible to create the project's site documentation.

Maven Phases

Each Maven life cycle is made up of a sequence of phases. A Maven phase is more like a particular state within the Maven life cycle. Each phase is responsible for executing a specific task.

Some phases in Default Lifecycle are,

  • validate - It validates the project and checks if all necessary information is available.
  • initialize - Initializes the build state like setting properties and creating necessary directories
  • generate-sources - Generate any source code for inclusion in compilation
  • process-sources - Process the source code, for example, to filter any values
  • compile - This phase compiles the source code. Use the command mvn compile to compile the src
  • test-compile - This phase compiles the tests source code
  • test - Runs all the unit tests present. Use the command mvn test to run the unit tests
  • prepare-package - Perform any operations necessary to prepare a package before the actual packaging
  • package - This phase will package compiled classes into a distributable format like jar or war. Use the command mvn package to package the code
  • integration-test - This phase will process and deploy the package if necessary into an environment where integration tests can be run
  • verify - This phase will ensure if quality criteria are met for the project
  • install - This phase installs the package to a local repository. Use the command mvn install to install the package
  • deploy - This phase copies the package to the remote repository

Maven Goals

Each goal will execute a specific task and a sequence of goals constitutes a phase. When a specific phase in run on maven, it executes all the goals in order. Some of the phases and the default goals bound to them are as follows,

  • compiler: compile in the compile phase
  • compiler: testCompile in test-compile phase
  • install: install in the install phase
  • jar and war: war in the packing phase