5.2 Maven Basics
Prerequisites: Why You Need a Package Manager
Estimated time: 15 minutes
Reading approach: Read about POMs and lifecycles, and defer online builds until real projects
You are ready to continue when: you can read POMs, run lifecycles, and explain Maven's locking boundaries
Java dependencies must do more than download successfully: they must appear on the correct compile, test, and runtime classpaths. Maven describes the project in a POM and connects those steps through a lifecycle.
POM and Artifact Coordinates
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>example.workshop</groupId>
<artifactId>hello-maven</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version>
</plugin>
</plugins>
</build>
</project>Save this as pom.xml in the project root; the example targets Maven 3.6.3+ and JDK 17. Pinning the compiler plugin avoids older Maven defaults that ignore maven.compiler.release. release=17 constrains language syntax, bytecode, and available Java SE APIs. This POM has no source or tests yet, so a successful build only establishes that the empty project configuration works. See the Compiler Plugin release documentation.
groupId:artifactId:version is an artifact coordinate. Whether the namespace is unique depends on publisher governance and cannot be guaranteed by string alone.
Lifecycle Stages
./mvnw clean verify # Prefer the Wrapper when available
mvn clean verify # Otherwise, use the local Maven installation
mvn dependency:tree
mvn help:effective-pomCalling verify will sequentially go through stages such as validate, compile, test, and package. install also writes the artifact into the local Maven repository, making it available for dependency resolution by other builds on the same machine; it is not responsible for installing the application into the operating system.
Wrapper writes the Maven version into the project. On first use, it may download Maven, and Windows users should use mvnw.cmd. The Wrapper fixes the version of the build tool but does not automatically lock all dependencies and plugins.
scope Decides classpath
| scope | Main code compilation | Main code runtime | Testing |
|---|---|---|---|
compile | Yes | Yes | Yes |
provided | Yes | Provided by runtime environment | Yes |
runtime | No | Yes | Yes |
test | No | No | Yes |
dependencyManagement manages versioning and default properties, dependencies declares the actual dependencies used by the project. BOMs are usually imported into dependencyManagement with type=pom and scope=import.
Maven Does Not Have a Default Complete Lock
Explicit versions in the POM and BOM can reduce drift, but transitive dependencies, plugins, parent POMs, repository contents, snapshots, JDKs, and build parameters still affect the result. Repeatable builds require:
- Submitting the Maven Wrapper and controlling JDK/toolchains;
- Explicitly defining direct dependencies, plugins, and repository strategies;
- Avoiding mutable snapshots in release builds;
- Validating downloaded artifacts and performing clean builds in CI.
requirements.txt is not a Maven lock, and pom.xml is not equivalent to npm's entire package-lock.json.
Git Boundaries
Commit pom.xml, wrapper files, source code, and tests. Ignore target/. Whether to commit .idea/ and .vscode/ is determined by the team and cannot be universally ignored.