Introduction to Maven



Table of Contents

Maven is a popular Java software tool for building projects. You can actually create software projects using other languages as well, but Maven is built in Java, and therefore is hene used more commonly for Java projects.

This Maven tutorial aims to get you to understand how Maven works. Hence this tutorial concentrates on Maven's core concepts. Once you understand the important concepts, in the Maven documentation, it is much easier to look up the fine details or search for them on the internet.

The Maven developers simply claim Maven is more than just a build tool. But just think of it as a build tool for now. Once you understand it, you will find out what Maven really is, and start using it.

the history of maven main versions is shown below:

  • Maven 1 (2003)
    • Very Ugly
    • Used in Stack 1
  • Maven 2 (2005)
    • Complete rewrite
    • Not backwards Compatible
    • Used in Stack 2.0,2.1,2.2,3.0
  • Maven 3 (2010)
    • Same as Maven 2 but more stable
    • Used in Stack 2.3, 3.1

Benefits of Maven

  • Portability and Standardization
  • Fast and easy to set up a powerful build process
  • Dependency management (automatic downloads)
  • Project website generation, Javadoc
  • Continuous Integration Server automatic
  • Very useful for TDD and testing

Installation and Setup

  1. Download Maven from http://maven.apache.org/
  2. Unzip the distribution
  3. Create environment variable M2_HOME, which points to Maven directory, e.g. c:\tools\apache-maven-3.1.0
  4. Add Maven’s bin directory to System Variable Path
  5. Ensure JAVA_HOME is set to the installed JDK
  6. Run mvn –version to test installation
Apache Maven 3.6.1 
Maven home: C:\apache-maven-3.6.1\bin\..
Java version: 14, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk-14
Default locale: de_DE, platform encoding: Cp1252
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

Tasks

All build systems are essentially try to solve the same problem by providing the following functionalities:

  • Compile Source code
  • Link resources and dependencies
  • Compile and Run Tests
  • Package Project
  • Deploy Project
  • Cleanup

some othe java build tools similar to maven are:

  • Ant
    • First release: 2000
    • Granddaddy of Java Build Tools
    • Scripting in XML
    • Very flexible
  • Ant+Ivy
    • First release: 2004
    • Ant but with Dependency Management
  • Gradle
    • First release: 2008
    • Attempt to combine Maven structure with Groovy Scripting
    • Easily extensible

Project Name (GAV)

Maven uniquely identifies a project using:

  • groupID: Arbitrary project grouping identifier (no spaces or colons)
    • Usually loosely based on Java package
  • artfiactId: Arbitrary name of project (no spaces or colons)
  • version: Version of project
    • Format {Major}.{Minor}.{Maintanence}
    • Add -SNAPSHOT to identify in development

GAV Syntax: groupId:artifactId:version

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.11</version>
</dependency>

Conventions

Maven is opinionated about project structure, here the main parts:

  • target: default working directory
  • src: all project source files go in this directory
  • src/main: all sources that go into primary artifact
  • src/test: all sources contributing to testing project
  • src/main/java: all java source files
  • src/main/webapp: all web source files
  • src/main/resources: all non compiled source files
  • src/test/java: all java test source files
  • src/test/resources: all non compiled test source files

Build Lifecycle

A Maven build follow a lifecycle. This is the default lifecycle:

  • compile
  • test
  • package
  • Install
  • site
  • deploy

To invoke a Maven build you set a lifecycle "goal"

  • mvn install : Invokes generate* and compile, test, package, integration-test, install
  • mvn clean : Invokes just clean
  • mvn clean compile : Clean old builds and execute generate*, compile
  • mvn compile install : Invokes generate*, compile, test, integration-test, package, install
  • mvn test clean : Invokes generate*, compile, test then cleans

Dependency Management

  • Maven revolutionized Java dependency management

No more checking libraries into version control

  • Maven introduced the Maven Repository concept

Established Maven Central

  • By using Maven you can use a module metadata file (POM) for managing the dependencies.
  • Maven also introduced concept of transitive dependency

roughly speaking, a dependencies consist of:

  • GAV: groupId:artifactId:version
  • Scope: compile, test, provided (default=compile).
    • Provided are those that are provided at runtime by the Server for example.
<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

Repositories

By using Maven, the dependencies are downloaded from repositories via http

The downloaded dependencies are cached in a local repository, which usually found in ${user.home}/.m2/repository

Repository follows a simple directory structure {groupId}/{artifactId}/{version}/{artifactId}-{version}.jar ( groupId . is replaced with / )

The Maven Central is the primary community repository:

https://mvnrepository.com/repos/central

Proxy (Private) Repositories

Proxy (Private) Repositories are useful:

  • organizationally caches artifacts
  • allows organization some control over dependencies
  • combines repositories

Define a Repository

  • Private repositories are defined in the pom
  • Repositories can be inherited from parent
  • Repositories are keyed by id
  • Downloading snapshots can be controlled
...
<repositories>
    <repository>
        <id>lds-main</id>
        <name>LDS Main Repo</name>
        <url>http://code.lds.org/nexus/content/groups/main-repo</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

Installing JARs to local repository

Sometimes you need to put some specific JARs in your local repository for use in your builds. The JARs must be placed in the correct place in order for it to be correctly picked up by Maven.

To install a JAR in the local repository use the following command:

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

Now can include dependency in pom.xml:

<dependency>
    <groupId><group-id></groupId>
    <artifactId><artifact-id></artifactId>
    <version><version></version>
</dependency>

Transitive Dependencies

Transitive Dependency is defined as follows:

A dependency that should be included when declaring project itself is a dependency

For example, if ProjectB depends on ProjectA, and ProjectC depends on ProjectB then ProjectA and ProjectB are automatically included, whenever ProjectC is included.

Only compile and runtime scopes are transitive

Transitive dependencies are controlled using:

  • Exclusions
  • Optional declarations

Dependency Exclusions

By using "dependency exclusions" functionality, we can exclude transitive dependencies:

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>3.0.5.RELEASE</version>
    <exclusions>
      <exclusion>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
</dependencies>

POM (Project Object Model)

A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details used by Maven to build the project.

  • As a "Convention over configuration" rule, the Super POM is Maven's default POM.
  • All POMs extend the Super POM unless explicitly set.
  • The configuration specified in the Super POM is inherited by the POMs you created for your projects.

The minimum requirement for a POM are the following:

  • project root
  • modelVersion - should be set to 4.0.0
  • groupId - the id of the project's group.
  • artifactId - the id of the artifact (project)
  • version - the version of the artifact under the specified group

Here's an example:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
</project>

Plugins

Maven is really just a core framework for a collection of Maven Plugins. In other words, plugins are where much of the real action is performed, plugins are used to:

  • create jar files
  • create war files
  • compile code
  • unit test code
  • create project documentation
  • etc.

Almost any action that you can think of performing on a project is implemented as a Maven plugin.

Plugins are the central feature of Maven that allow for the reuse of common build logic across multiple projects. They do this by executing an "action" in the context of a project's description (POM). Plugin behavior can be customized through a set of unique parameters which are exposed by a description of each plugin goal (or Mojo: Maven plain Old Java Object).

One of the simplest plugins in Maven is the Clean Plugin. The Maven Clean plugin (maven-clean-plugin) is responsible for removing the target directory of a Maven project. When you run "mvn clean", Maven executes the "clean" goal as defined in the Clean plug-in, and the target directory is removed. The Clean plugin defines a parameter which can be used to customize plugin behavior, this parameter is called outputDirectory and it defaults to ${project.build.directory}.

Plugins in Maven 2.0 look much like a dependency. For example, configure the Java compiler to allow JDK 6.0 sources:

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

Mojo

A Mojo is really just a goal in Maven, and plug-ins consist of any number of goals (Mojos). Mojos can be defined as annotated Java classes or Beanshell script. A Mojo specifies metadata about a goal: a goal name, which phase of the lifecycle it fits into, and the parameters it is expecting.

Maven web site presents a very nice description of Mojo development.