Skip to main content

Command Palette

Search for a command to run...

Apache Maven

Apache Maven: Internals, Repositories, Lifecycle, Plugins and Execution Model.

Updated
9 min readView as Markdown
Apache Maven

Introduction

Apache Maven is not just a build tool. It is a standardized software supply-chain system for Java projects. Maven defines how a project is structured, how dependencies are resolved, how builds are executed, and how artifacts are produced and distributed.

This article explains Maven from first principles, including:

  • what artifacts really are

  • how Maven repositories work internally

  • how lifecycle phases execute

  • what plugins and goals mean

  • how goal binding works using <executions>

The goal is to understand Maven deeply enough that one could design a similar system from scratch, like NPM or a custom package manager.


Core Philosophy of Maven

Maven is built on two fundamental ideas:

  1. Convention over Configuration - We should follow, It does not what we say, means in NPM we write scripts to manage packages but in maven it does everything but we just need to understand the process/convention

  2. Declarative Build Model - uses a Project Object Model (POM) to define the project's build configuration, dependencies, and plugins. This means you specify what should be accomplished rather than how to execute each specific step.

Instead of telling Maven how to build step by step, you describe what your project is, and Maven decides how to build it using conventions and plugins.


What Is an Artifact?

An artifact is the final, versioned output of a Maven build.

Technically, an artifact is any file produced and managed by Maven and stored in a repository.

Common artifact types:

  • JAR (Java libraries)

  • WAR (Web applications)

  • POM (Parent or BOM projects)

  • ZIP or TAR (distributions)

Example:

payment-service-1.0.0.jar

This file is the artifact.

Maven does not care about your source code after compilation.
Everything Maven manages is an artifact.


Artifact Identity (Coordinates)

Every artifact is uniquely identified by GAV coordinates:

G - Group ID

A - Artifact ID

V - Version

groupId : artifactId : version

Example:

com.googlepay : payment-service : 1.0.0

Meaning:

  • groupId: organization or namespace such as Test file in package A and Test file in package B are two different things even though contents are same

  • artifactId: project name

  • version: release identifier

These coordinates determine: (Above example)

  • where the artifact is stored

  • how it is resolved

  • how version conflicts are handled

This is conceptually identical to:

  • npm package name + version

  • Docker image name + tag


Maven Repositories

A Maven repository is a structured storage system for artifacts and metadata.

Types of Repositories

There are three main repository types:

  1. Local Repository

  2. Central Repository

  3. Remote / Private Repository - Company specific repository (Mostly accessible to employees)


Local Repository

The local repository is a directory on your machine:

If any project requests any package, All are stored in the below path in your system.

You can create as many projects you want but the plugins you use in the project are stored here and path of the plugin is passed to you project to avoid redundancy.

~/.m2/repository

It acts as:

  • a cache

  • a local artifact store

  • a shared dependency source for all Maven projects

When you run:

mvn install

The artifact produced by your project is copied into the local repository.


Central Repository

The central repository is a public, global repository hosted by the Maven community.

By default, Maven uses it automatically without configuration.

Most open-source Java libraries are published here.

Example: https://mvnrepository.com/


Remote / Private Repositories

Organizations often host private repositories using tools like:

  • Nexus

  • Artifactory

  • GitHub Packages

These store:

  • internal libraries

  • proprietary code

  • controlled releases


Repository Resolution Order

When Maven needs a dependency, it follows this strict order:

  1. Check local repository

  2. If not found, check configured remote repositories

  3. Download artifact

  4. Store it in local repository

  5. Use it in the build

Once downloaded, Maven does not download the same version again unless explicitly forced.


Internal Repository Structure

For the dependency:

org.springframework:spring-core:6.1.2

Maven stores it as:

~/.m2/repository/
└── org/
    └── springframework/
        └── spring-core/
            └── 6.1.2/
                ├── spring-core-6.1.2.jar
                ├── spring-core-6.1.2.pom
                └── _remote.repositories

Mapping logic:

groupId      → folder hierarchy - org.springframework
artifactId   → folder - springcore
version      → folder - 6.1.2

Combined will become GAV -> org.springframework.springcore.6.1.2

This structure is deterministic and reproducible.


Transitive Dependencies

Maven supports transitive dependency resolution.

If your project depends on A, and A depends on B, Maven automatically downloads B.

This happens because every artifact includes its own pom.xml, which declares its dependencies.

Maven builds a dependency graph and resolves it before compilation.


Dependency Conflict Resolution

When multiple versions of the same dependency exist, Maven uses the rule:

Nearest definition wins - It used DFS (Depth first search algorithm)

Meaning:

  • the dependency closest to your project in the dependency tree is selected

221121 New Maven algorithm tech blog v1 inc 1600x image 2

Image Credits goes to Ebay

From above after x → Z 2.0 will be selected.

This rule is simple, predictable, and crucial for large systems.


Maven Life cycle

Maven does not run arbitrary (not any order / sometimes random or unfair) commands.
It executes predefined life cycles, each consisting of ordered phases.

Important principle:

Life cycle phases do nothing by themselves.
Only plugins perform work.


Maven Lifecycles

Maven has three lifecycles:

  1. clean

  2. default

  3. site


Clean Lifecycle

Phases:

pre-clean
clean
post-clean

Purpose:

  • remove build artifacts

  • ensure clean builds

clean phase deletes the target directory.

Command:

mvn clean

Default Lifecycle

This is the most important lifecycle.

Key phases:

validate
compile
test
package
verify
install
deploy

Below is the same life cycle explanation, but strictly with Maven commands, what exact command you run, and what Maven actually executes.
Clean, technical, no fluff.


Maven Default Life cycle Phases with Commands

1. validate

Command:

mvn validate

What Maven does:

  • Reads pom.xml

  • Checks:

    • XML correctness

    • required fields (groupId, artifactId, version)

    • project structure validity

What it does NOT do:

  • No compilation

  • No dependency download for building

Use case:

  • CI sanity check

  • Early failure detection


2. compile

Command:

mvn compile

What Maven does:

  • Runs all phases before compile

  • Compiles Java source code

Internally:

src/main/java  →  target/classes

Plugin involved:

maven-compiler-plugin:compile

What it does NOT do:

  • No tests

  • No JAR creation


3. test

Command:

mvn test

What Maven does:

  • Runs:
validate → compile → test

Internally:

  • Compiles test code:
src/test/java → target/test-classes
  • Executes unit tests

Plugin involved:

maven-surefire-plugin:test

Behavior:

  • If any test fails → build fails

  • Artifact is NOT created


4. package

Command:

mvn package

What Maven does:

  • Runs:
validate → compile → test → package

Internally:

  • Takes compiled classes

  • Bundles them into an artifact

Output:

target/my-app.jar

(or .war, depending on packaging)

Plugin involved:

maven-jar-plugin:jar

Use case:

  • Create distributable binary

  • Still not shared with other projects


5. verify

Command:

mvn verify

What Maven does:

  • Runs:
validate → compile → test → package → verify

Internally:

  • Runs additional checks such as:

    • integration tests

    • code quality checks

    • custom validation plugins

No default behavior unless plugins are bound.

Use case:

  • CI pipelines

  • Quality gates


6. install

Command:

mvn install

What Maven does:

  • Runs:
validate → compile → test → package → verify → install

Internally:

  • Copies artifact to local repository

Location:

~/.m2/repository/

Example:

~/.m2/repository/com/pexeltech/my-app/1.0.0/my-app-1.0.0.jar

Plugin involved:

maven-install-plugin:install

Use case:

  • Allow other local Maven projects to depend on this artifact

7. deploy

Command:

mvn deploy

What Maven does:

  • Runs the entire lifecycle

  • Uploads artifact to a remote repository

Internally:

  • Pushes artifact + POM to:

    • Nexus

    • Artifactory

    • Maven Central (if configured)

Plugin involved:

maven-deploy-plugin:deploy

Use case:

  • Release builds

  • CI/CD pipelines


Command:

mvn clean

What Maven does:

  • Deletes:
target/

Plugin involved:

maven-clean-plugin:clean

Often combined with:

mvn clean package
mvn clean install

Key Rule (Must Memorize)

Running a later phase automatically runs all earlier phases.

Example:

mvn install

Is equivalent to:

mvn validate
mvn compile
mvn test
mvn package
mvn verify
mvn install

Key rule:
Running any phase runs all previous phases automatically.

Example:

mvn package

Runs:

validate → compile → test → package

Maven Plugins

Maven itself does almost nothing.

All real work is performed by plugins.

A plugin is a collection of executable units called goals.


Plugin and Goal Model

Conceptual mapping:

Plugin → Toolbox
Goal   → Tool

Examples:

  • maven-compiler-plugin

    • compile

    • testCompile

  • maven-surefire-plugin

    • test

What Is a Goal?

A goal is a single executable task.

Examples:

compiler:compile
surefire:test
jar:jar
shade:shade

Each goal performs one responsibility.


Default Goal Bindings

Maven automatically binds certain plugin goals to lifecycle phases.

Examples:

compile phase → compiler:compile
test phase    → surefire:test
package phase → jar:jar
clean phase   → clean:clean

These bindings are predefined by Maven.


Bound Plugin Goals

A bound goal is a goal that executes automatically when a life cycle phase runs.

You do not invoke it manually.

When a phase executes, all goals bound to that phase are executed in order.


Custom Goal Binding Using <executions>

Consider the configuration:

<executions>
  <execution>
    <phase>package</phase>
    <goals>
      <goal>shade</goal>
    </goals>
  </execution>
</executions>

This configuration means:

When Maven reaches the package phase, it must also execute the shade goal.


Real-Life Analogy

Normal behavior:

  • Package phase creates a JAR

Custom behavior:

  • At packaging time, also merge all dependencies into the JAR

The configuration is an automation rule:

IF phase == package
THEN run shade goal

What Is the Shade Goal?

The shade goal belongs to the maven-shade-plugin.

It:

  • takes your project JAR

  • takes all dependency JARs

  • merges them into a single executable JAR called One FAT JAR

This is commonly used in:

  • microservices

  • CLI tools

  • standalone Java applications


Internal Execution Flow

When you run:

mvn package

Maven performs:

validate
compile
test
package
   ├── jar:jar       (default binding)
   └── shade:shade   (custom binding)

Multiple goals can be bound to the same phase.


Complete Maven Execution Model

High-level flow:

Command (mvn install)
      ↓
Read pom.xml
      ↓
Resolve dependencies
      ↓
Determine lifecycle
      ↓
For each phase:
      ↓
Execute all bound plugin goals
      ↓
Produce artifact
      ↓
Store artifact in repository

Maven is essentially:

  • a dependency resolver

  • a life cycle engine

  • a plugin execution framework

  • an artifact distribution system


Why This Matters

Understanding Maven at this level teaches:

  • build system design

  • dependency graph resolution

  • artifact versioning

  • software supply-chain architecture

These concepts are transferable to:

  • NPM

  • Gradle

  • Bazel

  • internal build tools

  • custom package managers


Conclusion

Maven is not magic.
It is a predictable, rule-based system built on:

  • artifacts

  • repositories

  • life cycles

  • plugins

  • goal bindings

Once these fundamentals are clear, Maven becomes simple, powerful, and extensible.

This understanding is the foundation required to design your own build or package management system from scratch.

That’s all for today’s entry ! I will catch you in the next post until then, Keep Building and Happy Engineering !