Skip to main content

Command Palette

Search for a command to run...

My Maven Learning Notes: From JAR Files to Maven Lifecycle

Updated
10 min read
My Maven Learning Notes: From JAR Files to Maven Lifecycle
S

I'm Saroj Bist, a self-taught web developer, learning and building with the MERN stack. I started with front-end tools like ReactJS and Tailwind CSS, and slowly stepped into full-stack development, working on real projects and solving real problems. This blog is where I share what I’m learning — from small bugs to full project insights — in a way that helps both me and anyone on a similar path.

Java projects commonly use build tools such as:

  • Maven

  • Gradle

These tools help manage dependencies, compile code, run tests, and package applications.

Understanding JAR Files

What is a JAR?

JAR (Java Archive) is a file format used to package Java applications and libraries.

When Java source code (.java files) is compiled, it becomes bytecode (.class files), which can be executed by the JVM (Java Virtual Machine).

Example:

User.java

After compilation:

User.class

The Problem Without JAR

Consider a project containing many classes:

User.java
Product.java
Order.java
Invoice.java

After compilation:

User.class
Product.class
Order.class
Invoice.class

A real project may contain hundreds or thousands of .class files.

Sharing all these files individually would be difficult and messy.

One possible solution is:

Zip all .class files

This works technically, but it is not a clean or standard approach.

How JAR Solves This Problem

A JAR file packages everything into a single file.

A JAR may contain:

  • .class files

  • Resources

  • Packages

  • Folders

  • Configuration files

  • Metadata

Example:

invoice-library.jar

Instead of sharing hundreds of files, we share one JAR file.

Using External Libraries

Suppose we want to connect our application to a database.

Instead of writing the database communication code ourselves, we can use an existing library.

Example:

mysql-connector.jar

We simply add this library to our application and use its functionality.

This is one of the main reasons JAR files are important—they allow code reuse.

Types of JAR Files

1. Library JAR (Non-Executable)

Contains reusable code.

Example:

mysql-connector.jar
jackson.jar
lombok.jar

These JARs are intended to be used by other applications.

2. Executable JAR

Contains an application that can be run directly.

Example:

java -jar app.jar

Spring Boot commonly creates executable JARs.

Libraries Depending on Other Libraries

A library may use other libraries internally.

Example:

Library A
    ↓
Library B
    ↓
Library C

To describe these dependencies, Maven uses a file called:

pom.xml

The POM file tells Maven:

  • Which dependencies are required

  • Which versions are required

  • Which additional libraries must be downloaded

Application Execution Flow

Java Code
    +
External Libraries (JARs)
    ↓
Compilation
    ↓
Bytecode (.class)
    ↓
JVM
    ↓
Application Runs

Why Maven Exists

Suppose we need a database connector.

Without Maven:

  1. Search for the JAR file.

  2. Download it manually.

  3. Add it to the project.

  4. Download its dependencies manually.

  5. Manage versions ourselves.

Problems:

  • Difficult version management

  • Missing dependencies

  • Dependency conflicts

  • Hard to share projects

  • Hard to reproduce builds

Transitive Dependencies

A dependency may depend on another dependency.

Example:

Application
    ↓
Spring Boot Starter Web
    ↓
Spring MVC
    ↓
Jackson
    ↓
Logging Libraries

Without Maven, we would need to download all of these manually.

Maven automatically handles this process.

What is Maven?

Maven is a Project Management and Build Tool.

Responsibilities:

  • Download dependencies

  • Manage dependency versions

  • Compile code

  • Run tests

  • Package applications

  • Create JAR files

  • Enforce standard project structure

Instead of manually downloading JARs, we simply define dependencies in:

pom.xml

Maven downloads everything automatically.


Maven Standard Project Structure

project
│
├── pom.xml
│
├── src
│   ├── main
│   │   ├── java
│   │   └── resources
│   │
│   └── test
│       └── java
│
└── target

src/main/java

Contains application source code.

Example:

Controllers
Services
Repositories
Entities

src/main/resources

Contains non-Java resources.

Examples:

application.properties
application.yml
static files
templates

src/test/java

Contains test classes.

Examples:

Unit Tests
Integration Tests

The Target Folder

The target folder is generated by Maven.

Example command:

mvn compile

Maven creates:

target/

Inside:

target/classes

Maven stores compiled bytecode (.class files) here.

Does Maven Generate Bytecode?

No.

Maven itself does not compile Java code.

Instead, Maven invokes the Java compiler (javac).

Process:

Maven
   ↓
Calls javac
   ↓
javac generates bytecode
   ↓
.class files created

Think of Maven as the manager and javac as the worker.

Maven: "Compile these files."
javac: "Done. Here are the .class files."

What is POM?

POM stands for Project Object Model.

The pom.xml file is the heart of a Maven project. It contains all the information Maven needs to build and manage the project.

If you come from a Node.js background, you can think of:

pom.xml  ≈  package.json

Both files contain project metadata, dependencies, versions, and build configuration.

Basic Structure

<project>
    ...
</project>

Everything in Maven is defined inside the <project> tag.

Model Version

<modelVersion>4.0.0</modelVersion>

This specifies the version of the POM model that Maven should use.

For modern Maven projects, you'll almost always see:

<modelVersion>4.0.0</modelVersion>

GAV Coordinates

Every Maven project is uniquely identified by three values:

G = Group ID
A = Artifact ID
V = Version

These are called Maven Coordinates.

Group ID

<groupId>com.saroj</groupId>

Identifies the organization, company, or developer who owns the project.

Conventionally, it follows a reversed domain name format.

Examples:

com.google
com.amazon
org.springframework
com.saroj

Think of it as a namespace to avoid naming conflicts.

Artifact ID

<artifactId>backend</artifactId>

The name of the project or library.

Examples:

spring-boot-starter-web
mysql-connector-j
backend

Version

<version>1.0.0</version>

Represents the version of the project.

Examples:

1.0.0
1.1.0
2.0.0

When the project is packaged, Maven creates something like:

backend-1.0.0.jar

Properties

The <properties> section allows us to define reusable values.

Example:

<properties>
    <java.version>21</java.version>
    <author.name>Saroj</author.name>
</properties>

These values can be referenced anywhere in the POM using:

${property-name}

Example:

${java.version}
${author.name}

This helps avoid duplication and makes version updates easier.

Parent POM

Many Spring Boot projects contain:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.0</version>
</parent>

The parent POM provides:

  • Dependency versions

  • Plugin versions

  • Build configurations

  • Spring Boot defaults

Think of it as inheriting configuration from a base class.

Dependencies

Dependencies are external libraries that our application needs.

Example:

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>

A dependency usually contains:

<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>

These values tell Maven exactly which library should be downloaded.

What Happens When We Add a Dependency?

Suppose we add:

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>

When Maven runs:

mvn compile

or

mvn package

it:

  1. Reads pom.xml

  2. Finds required dependencies

  3. Downloads missing JAR files

  4. Stores them in the local Maven repository

Location:

~/.m2/repository

What If We Don't Specify a Version?

There are two possibilities.

Case 1: Version Managed by Spring Boot

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>

This works because Spring Boot's parent POM already knows which version to use.


Case 2: Version Not Managed

<dependency>
    <groupId>com.cloudinary</groupId>
    <artifactId>cloudinary-http44</artifactId>
</dependency>

If Spring Boot does not manage this dependency, Maven will fail with an error similar to:

'dependencies.dependency.version' is missing

In that case, we must provide the version manually.

Transitive Dependencies

A dependency can depend on other dependencies.

Example:

Our Application
      ↓
Spring Boot Starter Web
      ↓
Spring MVC
      ↓
Jackson
      ↓
Logging Libraries

Instead of downloading all of these manually, Maven automatically resolves and downloads them.

This is called Transitive Dependency Management.

Build Section

The <build> section tells Maven how to build the project.

Example:

<build>
    <plugins>
        ...
    </plugins>
</build>

Think of:

dependencies → What my application needs

build → How Maven should build my application

Plugins

Plugins are tools that Maven uses during the build process.

Examples:

Spring Boot Maven Plugin

<artifactId>spring-boot-maven-plugin</artifactId>

Responsible for:

  • Creating executable Spring Boot JARs

  • Running Spring Boot applications

  • Packaging dependencies

Maven Compiler Plugin

<artifactId>maven-compiler-plugin</artifactId>

Responsible for:

  • Compiling Java source code

  • Configuring Java version

  • Running annotation processors such as Lombok

Maven Lifecycle

Maven follows a predefined build lifecycle. A lifecycle is simply a sequence of phases that Maven executes to build, test, package, and deploy a project.

Common Maven lifecycle phases:

validate → compile → test → package → verify → install → deploy

Maven Lifecycle Overview

Source Code
     ↓
validate
     ↓
compile
     ↓
test
     ↓
package
     ↓
verify
     ↓
install
     ↓
deploy

Each phase has a specific responsibility.

1. validate

Validates that the project structure and configuration are correct.

Examples:

  • Checks whether pom.xml is valid.

  • Ensures required project information is available.

  • Verifies that Maven can proceed with the build.

Command:

mvn validate

2. compile

Compiles Java source code into bytecode.

Process:

.java
   ↓
javac
   ↓
.class

Output location:

target/classes

Command:

mvn compile

Important:

Maven does not generate bytecode itself.

Instead, Maven invokes the Java compiler (javac) to compile the code.

3. test

Runs unit tests located inside:

src/test/java

Example:

@Test
void shouldCreateUser() {
    ...
}

Command:

mvn test

If tests fail:

BUILD FAILURE

Maven stops the build process.

4. package

Packages the application into a distributable format.

Common outputs:

JAR
WAR

Output location:

target/

Example:

target/gold-jar-backend-0.0.1-SNAPSHOT.jar

Command:

mvn package

For Spring Boot projects, the result is usually an executable JAR:

java -jar app.jar

5. verify

Performs additional verification after packaging.

Common examples:

  • Integration tests

  • Code quality checks

  • Security scans

  • JaCoCo code coverage validation

  • Custom plugin validations

Command:

mvn verify

Many teams use this phase in CI/CD pipelines.

6. install

Copies the packaged artifact into the local Maven repository.

Location:

~/.m2/repository

Command:

mvn install

Example flow:

Project
   ↓
package
   ↓
app.jar
   ↓
~/.m2/repository

This allows other local Maven projects to use your artifact as a dependency.

7. deploy

Publishes the artifact to a remote Maven repository.

Examples:

  • Nexus Repository

  • Artifactory

  • Maven Central

Command:

mvn deploy

Example flow:

Project
   ↓
package
   ↓
install
   ↓
Remote Repository

Now other developers or servers can download the artifact.

What About Site?

Maven also provides a Site lifecycle.

Command:

mvn site

Purpose:

Generate project documentation and reports.

Examples:

  • Dependency reports

  • Test reports

  • Plugin reports

  • Project information

  • Code coverage reports

Output location:

target/site

Most modern Spring Boot projects rarely use this feature, but it is still available.

Maven Executes Previous Phases Automatically

One important rule:

When you run a phase, Maven executes all previous phases automatically.

Example:

mvn package

Actually runs:

validate
   ↓
compile
   ↓
test
   ↓
package

Similarly:

mvn install

Runs:

validate
   ↓
compile
   ↓
test
   ↓
package
   ↓
verify
   ↓
install