Maven
01 / 02

POM Structure, Lifecycle & Dependencies

POM Structure, Lifecycle & Dependencies

pom.xml Basics

<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>

  <properties>
    <maven.compiler.release>17</maven.compiler.release>
  </properties>

  <dependencies>
    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>33.0.0-jre</version>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>5.10.0</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Build Lifecycle

A fixed, ordered sequence of phases: validate, compile, test, package, verify, install, deploy. Running a later phase automatically runs every earlier one first.

mvn test       # compile + run unit tests (Surefire)
mvn package    # ...then build the JAR/WAR into target/
mvn verify     # ...then run integration tests (Failsafe)
mvn install    # ...then copy the artifact into ~/.m2/repository (local cache)
mvn deploy     # ...then publish to a remote shared repository

mvn help:effective-pom   # see the fully-resolved POM, including inherited parent settings
mvn dependency:tree      # see resolved versions across the whole dependency graph

Dependency Scopes

<!-- compile (default) — available everywhere, bundled transitively -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.16.0</version></dependency>

<!-- test — only on the test classpath -->
<dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>5.8.0</version><scope>test</scope></dependency>

<!-- provided — needed to compile, but supplied by the runtime (e.g. servlet container) -->
<dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>6.0.0</version><scope>provided</scope></dependency>

<!-- runtime — needed at runtime, not to compile against -->
<dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><version>42.7.1</version><scope>runtime</scope></dependency>

Excluding Transitive Dependencies

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<!-- Maven resolves conflicts via "nearest definition wins" — the version
     declared closest to your project in the tree takes precedence. -->

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free