Apache Maven is a build automation tool for Java projects. It takes your source code and produces a deliverable (a .jar or .war file) by orchestrating every step: compilation, tests, packaging, and dependency management.
In practice, Maven meets three fundamental needs:
| Need | What Maven does |
|---|---|
| Build the project | Compiles the code and produces an artifact (.jar, .war) |
| Manage dependencies | Automatically downloads the required libraries |
| Standardize | Enforces the same project layout everywhere |
Maven's core is a single file, the pom.xml (Project Object Model), which describes the project: its identity, its dependencies, and how to build it. It is the “recipe” Maven executes.
Without Maven, building a Java project means compiling by hand with
javac, downloading every library manually, and managing the classpath yourself. Maven automates all of that from a single file.
🔧 Mini-exercise — Name the three fundamental needs Maven addresses.
Build the project (compile + produce a .jar/.war artifact), manage dependencies (download libraries), and standardize (enforce the same project layout).
Before Maven, every Java project was built “by hand” or with homemade scripts. That led to several recurring problems:
| Problem (without Maven) | Solution (with Maven) |
|---|---|
Find and download .jar files one by one | Declaration in the pom.xml, automatic download |
| Library version conflicts | Automatic transitive resolution |
| “It compiles on my machine but not on yours” | Reproducible, standardized build |
| Every project organized differently | Imposed folder layout |
The key idea: a developer who joins a Maven project immediately knows where the code is, where the tests are, and how to launch the build — regardless of the company or the project.
# With Maven, building an unknown project comes down to:
mvn packageMaven turns “how do I build this project?” — a question that sometimes took hours — into a single universal command.
🔧 Mini-exercise — Write the one command that is enough to build an unknown Maven project.
mvn packageMaven's central principle is “convention over configuration”. Rather than describing everything explicitly, Maven starts from sensible defaults. If you follow the conventions, you barely have to configure anything.
Examples of default conventions:
| Element | Default expected location |
|---|---|
| Main source code | src/main/java |
| Main resources | src/main/resources |
| Test code | src/test/java |
| Produced artifact | target/ |
Comparing the philosophies:
| Approach | Consequence |
|---|---|
| Configure everything | Flexible but verbose, error-prone |
| Convention by default | Concise, consistent across projects, fast to start |
You can always override the conventions if needed, but 95% of projects stick with the defaults. Less configuration = fewer bugs.
Every Maven project follows the same tree. Knowing it lets you navigate instantly in any project.
Folder details:
| Path | Role |
|---|---|
pom.xml | The project recipe (at the root) |
src/main/java | The application source code |
src/main/resources | Non-Java files (.properties, .xml, images) |
src/test/java | Unit-test classes |
src/test/resources | Resources used by the tests |
target/ | Output folder: compiled classes and the final artifact |
🔧 Mini-exercise — In which folder should you put a unit-test class, and in which one an application.properties file?
The unit test goes in src/test/java, and application.properties goes in src/main/resources.
# Typical tree seen from the command line
mon-projet/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/ # e.g. com/exemple/App.java
│ │ └── resources/ # e.g. application.properties
│ └── test/
│ └── java/ # e.g. com/exemple/AppTest.java
└── target/ # generated: do not version (.gitignore)⚠️ The
target/folder is regenerated on every build. Add it to your.gitignore: compiled artifacts are never versioned.
Maven needs a JDK (Java Development Kit) already installed, because it relies on the javac compiler. The JAVA_HOME variable must point to that JDK.
Depending on your system:
| System | Installation command |
|---|---|
| Windows (with Chocolatey) | choco install maven |
| macOS (with Homebrew) | brew install maven |
| Linux (Debian/Ubuntu) | sudo apt install maven |
Manual installation (all platforms):
# 1. First check that Java is present
java -version
# Should display a version such as 17+
# 2. Set JAVA_HOME (Linux/macOS example)
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
# 3. Download Maven from maven.apache.org, extract it,
# then add the bin/ folder to the PATH
export PATH=$PATH:/opt/apache-maven-3.9.6/binOn Windows,
JAVA_HOMEis set in “Environment Variables”. On Linux/macOS, add theexportline to your~/.bashrcor~/.zshrcso it is permanent.
Once Maven is installed, you verify that it works and generate a first project skeleton.
# Check the installed version
mvn -versionTypical output:
Apache Maven 3.9.6
Maven home: /opt/apache-maven-3.9.6
Java version: 17.0.9, vendor: Eclipse AdoptiumTo generate an empty project that follows the conventions, you use an archetype (a template):
# Generates a standard “quickstart” project
mvn archetype:generate \
-DgroupId=com.exemple \
-DartifactId=mon-app \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false| Command | Effect |
|---|---|
mvn -version | Displays the Maven and Java versions |
mvn archetype:generate | Generates a project from a template |
mvn package | Builds the artifact in target/ |
The first
mvnis slow: Maven downloads its own plugins into a local cache (~/.m2/repository). Later builds are much faster.
🔧 Mini-exercise — Write the command that displays the installed Maven version (and the Java version).
mvn -versionQuestion 1: What does the pom.xml file represent in a Maven project?
a) The application's main source code
b) The Project Object Model: the recipe that describes the project and its build
c) The project's compiled result
d) A log file
Answer: b) — The pom.xml (Project Object Model) describes the project's identity, its dependencies, and how to build it.
Question 2: Where does Maven expect to find the main source code by default?
a) code/
b) target/main
c) src/main/java
d) java/source
Answer: c) — By convention, main code goes in src/main/java, and tests go in src/test/java.
Question 3: What does “convention over configuration” mean?
a) Everything must be configured explicitly
b) Maven uses sensible defaults, reducing the configuration you need
c) You can never change Maven's behavior
d) Maven has no configuration file
Answer: b) — By following the default conventions, the pom.xml stays minimal. You can always override a convention if needed.
Question 4: Which folder is generated automatically by Maven and must not be versioned?
a) src/main/java
b) src/test/java
c) target/
d) resources/
Answer: c) — target/ contains compiled classes and the artifact; it is regenerated on every build and must be listed in .gitignore.
Question 5: What does Maven need in order to work?
a) A web server
b) An installed JDK and a configured JAVA_HOME
c) A database
d) Node.js
Answer: b) — Maven relies on the JDK's javac compiler; JAVA_HOME must point to that JDK.
Verify your Maven installation, generate a “quickstart” project named mon-app in the com.exemple group, then build it and locate the produced artifact.
# 1. Check Maven and Java
mvn -version
# 2. Generate the project from the quickstart archetype
mvn archetype:generate \
-DgroupId=com.exemple \
-DartifactId=mon-app \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false
# 3. Enter the project and inspect the layout
cd mon-app
ls -R # or “tree” if available
# 4. Build the project
mvn package
# 5. Locate the generated artifact
ls target/Expected result:
target/
├── classes/
├── mon-app-1.0-SNAPSHOT.jar <-- the produced artifact
└── ...
BUILD SUCCESSThe generated tree should contain:
mon-app/
├── pom.xml
└── src/
├── main/java/com/exemple/App.java
└── test/java/com/exemple/AppTest.javaIf
mvn packageprintsBUILD SUCCESSand a.jarappears intarget/, your Maven toolchain is working. The-SNAPSHOTsuffix marks a version still in development (see lesson 02).
pom.xml is the single recipe that describes the project and its build.src/main/java, src/test/java, src/main/resources, output in target/.JAVA_HOME; you verify with mvn -version.Lesson 02 — The pom.xml file: dissect Maven's recipe in detail — project coordinates, properties, and parent inheritance.
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