Maven organizes a project's build into a lifecycle: an ordered sequence of phases. When you request a phase, Maven runs all previous phases in order.
This is the most important principle to remember:
Requesting a phase automatically runs all the ones that precede it.
mvn packagetherefore also runsvalidate,compile, andtest.
Maven actually has three lifecycles:
| Lifecycle | Role |
|---|---|
| default | Build the project (compile, test, package…) |
| clean | Clean up (delete target/) |
| site | Generate the project documentation |
# Running a phase = running everything up to it
mvn package # runs validate -> compile -> test -> package🔧 Mini-exercise — Which phases run when you launch mvn package? List them in order.
validate → compile → test → package: requesting a phase automatically runs all the ones that precede it.
The default lifecycle has many phases; here are the ones used most often day to day:
| Phase | What it does |
|---|---|
validate | Checks that the project is correct and that all required information is present |
compile | Compiles the source code (src/main/java) |
test | Runs the unit tests |
package | Packages the compiled code (.jar or .war) |
verify | Runs integration tests and quality checks |
install | Installs the artifact in the local repository ~/.m2 |
deploy | Publishes the artifact to a shared remote repository |
mvn validate # basic checks
mvn compile # + compilation
mvn test # + unit tests
mvn package # + artifact creation
mvn verify # + integration tests
mvn install # + copy into ~/.m2
mvn deploy # + remote publicationThe further you go in the list, the more Maven does.
mvn installis the “Swiss army knife” of local development: it builds everything and makes the artifact available to your other projects on the same machine.
The compile phase turns your Java code (src/main/java) into bytecode (.class) placed in target/classes. The Compiler plugin handles this, using the JDK's javac.
The Java version used is defined by the properties seen in lesson 02:
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties># Compile the main code
mvn compile
# Also compile the test code
mvn test-compile🔧 Mini-exercise — In which folder is the main code's .class bytecode placed after mvn compile?
In target/classes (for example target/classes/com/exemple/App.class).
| Property | Role |
|---|---|
maven.compiler.source | Java language version accepted in the code |
maven.compiler.target | Generated bytecode version |
Result in target/:
target/
└── classes/
└── com/exemple/App.class <-- compiled bytecodeIf compilation fails (
BUILD FAILURE), Maven stops immediately: later phases (test,package) do not run. You always fix compilation errors first.
The test phase runs the unit tests located in src/test/java. The Surefire plugin launches them, usually with the JUnit framework.
A typical JUnit test:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class CalculTest {
@Test
void additionDeDeuxNombres() {
assertEquals(4, 2 + 2);
}
}# Run all tests
mvn test
# Run a single test class
mvn test -Dtest=CalculTest
# Build while SKIPPING tests (avoid, except in specific cases)
mvn package -DskipTests🔧 Mini-exercise — Write the Maven command that packages the project without running the tests.
mvn package -DskipTests| Element | Role |
|---|---|
| JUnit | The framework that defines and checks the tests |
| Surefire | The Maven plugin that runs unit tests |
| Failsafe | The plugin that runs integration tests (verify phase) |
⚠️ If a single test fails, the entire build fails (
BUILD FAILURE) and thepackageis not produced. That is intentional: you do not ship an artifact whose tests do not pass. Skipping tests with-DskipTestsmust remain exceptional.
The package phase assembles the compiled code into a deliverable artifact, placed in target/. The artifact type depends on the <packaging> tag in the pom.xml.
| Packaging | Artifact | Usage |
|---|---|---|
jar | .jar | Library or standalone Java application |
war | .war | Web application deployed on a server (Tomcat…) |
pom | (none) | Parent/aggregator project, with no code |
<!-- Choice of artifact type -->
<packaging>jar</packaging># Produce the artifact
mvn package
# Locate the result
ls target/Result:
target/
├── classes/
├── mon-app-1.0.0-SNAPSHOT.jar <-- the deliverable artifact
└── ...The artifact name follows the pattern
artifactId-version.packaging. Example:mon-app-1.0.0-SNAPSHOT.jar. That is the file you distribute or deploy.
After package, three operations complete the lifecycle.
| Command | Effect |
|---|---|
mvn install | Builds + copies the artifact into ~/.m2 (reusable locally) |
mvn deploy | Builds + publishes the artifact to a remote repository (Nexus/Artifactory) |
mvn clean | Deletes the target/ folder (start from scratch) |
The clean install combination is one of the most common: it guarantees a fully clean build.
# Start from scratch and build everything through local installation
mvn clean install
# Build and publish to the team's remote repository
mvn clean deploy| Phase | Who needs it? |
|---|---|
install | A developer who wants to reuse the artifact in another local project |
deploy | The team / CI that publishes a version for everyone |
clean | Anyone who wants to avoid leftovers from a previous build |
mvn clean installis the reflex to adopt when “it no longer works for no reason”:cleanremoves any obsolete compiled files intarget/.
🔧 Mini-exercise — Write the command that starts from a clean target/ then installs the artifact in the local repository ~/.m2.
mvn clean installQuestion 1: What happens when you run mvn package?
a) Only the package phase runs
b) Maven also runs all previous phases (validate, compile, test)
c) Maven publishes the artifact to a remote repository
d) Maven deletes the target/ folder
Answer: b) — Requesting a phase runs all previous phases in order: validate → compile → test → package.
Question 2: Which Maven plugin runs the unit tests?
a) Compiler
b) Surefire
c) Shade
d) Jar
Answer: b) — The Surefire plugin runs the unit tests (with JUnit) during the test phase.
Question 3: What does the install phase do?
a) It installs Maven on the machine
b) It copies the artifact into the local repository ~/.m2
c) It publishes to Maven Central
d) It deletes target/
Answer: b) — install copies the artifact into ~/.m2, making it reusable by other local projects.
Question 4: Which tag determines whether the project produces a .jar or a .war?
a) <scope>
b) <version>
c) <packaging>
d) <artifactId>
Answer: c) — <packaging>jar</packaging> or <packaging>war</packaging> sets the artifact type produced by package.
Question 5: What happens during mvn package if a unit test fails?
a) The artifact is produced anyway
b) The build fails (BUILD FAILURE) and the artifact is not produced
c) Maven ignores the test
d) Maven jumps straight to deploy
Answer: b) — A failing test stops the build; the package is not created. That is intentional: you do not ship an artifact whose tests fail.
On a Maven project, walk through the lifecycle step by step: clean, compile, test, package, then install locally. At each step, observe what Maven produces in target/.
# 1. Start from scratch: delete target/
mvn clean
# 2. Compile: produces target/classes
mvn compile
ls target/classes # .class bytecode present
# 3. Test: Surefire runs the JUnit tests
mvn test
# 4. Package: produces the .jar in target/
mvn package
ls target/*.jar # mon-app-1.0.0-SNAPSHOT.jar
# 5. Install in the local repository ~/.m2
mvn install
# Most common condensed variant:
mvn clean installExpected result:
[INFO] --- compiler:compile --- (target/classes created)
[INFO] --- surefire:test --- Tests run: 1, Failures: 0, Errors: 0
[INFO] --- jar:jar --- Building jar: target/mon-app-1.0.0-SNAPSHOT.jar
[INFO] --- install:install --- Installing ... to ~/.m2/repository/...
[INFO] BUILD SUCCESSWatch the order of the
[INFO]lines:compile, thentest, thenjar, theninstall. That is the visible proof that Maven automatically chains the phases in lifecycle order.
validate → compile → test → package → verify → install → deploy.compile (Compiler plugin) produces bytecode in target/classes.test (Surefire plugin + JUnit) runs the tests; a failure stops the build.package creates the .jar/.war; install copies it into ~/.m2; clean empties target/.You now have a working grasp of Maven: layout, pom.xml, dependencies, and lifecycle. Module 04 will cover containerization with Docker, where you will package these Maven artifacts into portable images.
All rights reserved. Any reproduction, distribution, use or adaptation of this course, in whole or in part, is strictly prohibited without the prior written authorization of Dr. Haythem REHOUMA.
Course created by Dr. Haythem REHOUMA — Development and Deployment of Data Solutions