Chapter 05Lesson 01~105 minutes

Maven POM Structure, Coordinates, Packaging, Build Lifecycle, Phases, and Goals: Concepts, Architecture, and Mental Model

Build a beginner-first mental model of Maven’s POM, coordinates, packaging, lifecycles, phases, plugin goals, default bindings, and effective-model inheritance.

POMCoordinatesLifecyclePhases & GoalsEffective POM

Learning objectives

  • Explain how pom.xml becomes the effective project model Maven actually executes.
  • Distinguish Maven coordinates, packaging, lifecycle, phase, plugin, goal, execution, and binding without treating them as synonyms.
  • Predict which earlier phases run when a later phase such as package or install is invoked.
  • Explain how jar, pom, and war packaging select different default lifecycle bindings.
  • Use read-only effective-model and plugin inspection before changing a build.
Current baseline — checked 2026-08-23. Required labs use Maven 3.9.16 through Maven Wrapper 3.3.4, JDK 21 to run Maven, and Java 17 as the compilation release target. For Maven 3.9.16 jar packaging, core default bindings currently include Resources 3.4.0, Compiler 3.15.0, Surefire 3.5.4, JAR 3.5.0, Install 3.1.4, and Deploy 3.1.4. The lab uses a disposable project-local repository path; no remote publication, paid repository manager, or hosted CI is required.

1. The practical problem — why did Maven run that goal?

Chapter 04 established which Maven runtime, settings, wrapper, repositories, and JDK are active. This chapter asks the next production question: when you run ./mvnw package, why do resources get copied, Java gets compiled, tests run, and a JAR appears even though your POM never named those goals?

The answer is not “because package means build a JAR.” Maven first builds an effective project model. That model contains your POM plus inherited/default state. The project’s packaging selects default goal-to-phase bindings. Maven then walks the chosen lifecycle through the requested phase and executes every bound plugin goal encountered on that path.

2. The model-to-execution pipeline

POM model to lifecycle execution
flowchart TD
  P[pom.xml] --> M[Model builder]
  S[Super POM] --> M
  R[Parent POMs + active profiles] --> M
  M --> E[Effective POM]
  E --> C[Coordinates + packaging + build configuration]
  C --> L[Selected lifecycle and requested phase]
  B[Packaging default bindings] --> L
  X[Explicit plugin executions] --> L
  L --> G[Ordered plugin goals]
  G --> O[target outputs]
  G --> I[local repository on install]

Read every arrow literally. pom.xml, the Super POM, parents, and active profiles feed the model builder. The resulting effective POM contributes coordinates, packaging, properties, dependencies, and plugin configuration. Packaging contributes default bindings. Explicit executions add more goals. The requested phase determines how far Maven walks the lifecycle. Goals then create observable files, reports, artifacts, or local-repository state.

3. Vocabulary that must stay separate

Term Meaning Example / evidence
POM XML project model read from pom.xml. Declared coordinates, dependencies, properties, build/plugins.
Coordinates Artifact identity, principally groupId:artifactId:version. dev.academy:lifecycle-lab:1.0.0.
Packaging Project/artifact type that participates in lifecycle mapping. jar is the default when omitted; pom is metadata/parent/aggregator packaging.
Lifecycle An ordered sequence of phases. Built-in default, clean, site.
Phase Named checkpoint in a lifecycle. compile, test, package, verify, install.
Plugin Artifact that provides Maven capabilities. maven-compiler-plugin.
Goal One executable capability of a plugin. compiler:compile, jar:jar.
Binding Association between a goal and a lifecycle phase. For jar packaging, jar:jar is bound to package.
Execution A configured plugin-goal invocation in the POM, with an ID, optional phase, goals, and configuration. A custom antrun:run execution bound to prepare-package.

4. Minimal POM versus effective POM

<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>dev.academy</groupId>
  <artifactId>lifecycle-lab</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.release>17</maven.compiler.release>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>5.13.4</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

This POM says less than Maven actually knows. All Maven 3 models implicitly inherit the Super POM, which supplies conventions such as target, src/main/java, src/test/java, resource directories, and Central. The effective model can also include parent inheritance and active profiles.

./mvnw --version
./mvnw org.apache.maven.plugins:maven-help-plugin:3.5.2:effective-pom \
  -Dverbose \
  -Doutput=target/effective-pom.xml

# Inspect, do not edit, the generated evidence file.
grep -nE '(<packaging>|<sourceDirectory>|<outputDirectory>|maven-.*-plugin)' \
  target/effective-pom.xml | head -80
Generated evidence, not source of truth: target/effective-pom.xml is an inspection artifact. Do not copy it back over pom.xml; doing so would freeze inherited/default implementation details into your source model.

5. Three built-in lifecycles; phases are ordered checkpoints

Lifecycle Purpose Representative phases
default Build, test, package, verify, install, and deploy project artifacts. validate → … → compile → … → test → … → package → … → verify → install → deploy
clean Remove build output created by prior builds. pre-clean → clean → post-clean
site Generate/deploy project documentation site. pre-site → site → post-site → site-deploy

If you invoke install, Maven executes every earlier phase of the default lifecycle before install. It does not automatically run clean because clean belongs to a different lifecycle. That is why ./mvnw clean install contains two separate CLI phase requests.

A phase can have zero goals bound to it. In a minimal JAR project, validate is still a valid phase even if no default goal performs visible work there.

6. Packaging turns phases into concrete plugin goals

Phase for jar packaging Maven 3.9.16 default binding Observable role
process-resources maven-resources-plugin:3.4.0:resources Copies/processes main resources into target/classes.
compile maven-compiler-plugin:3.15.0:compile Compiles main Java sources.
process-test-resources maven-resources-plugin:3.4.0:testResources Copies/processes test resources.
test-compile maven-compiler-plugin:3.15.0:testCompile Compiles test Java sources.
test maven-surefire-plugin:3.5.4:test Runs unit tests.
package maven-jar-plugin:3.5.0:jar Creates the main JAR.
install maven-install-plugin:3.1.4:install Adds POM/artifact(s) to the local repository.
deploy maven-deploy-plugin:3.1.4:deploy Publishes to a configured remote repository.

These versions come from Maven 3.9.16 core bindings. They are not a timeless promise. Changing the Maven runtime can change the default plugin versions even if pom.xml is unchanged. That is one reason the wrapper and effective-model evidence matter.

7. Packaging changes the lifecycle mapping

Packaging is not merely a filename extension. It participates in lifecycle mapping.

Packaging At package At install Typical role
jar Default jar:jar binding creates a JAR. Installs POM + JAR (+ attached artifacts). Java library/application artifact.
pom No core package artifact goal is bound. Installs the POM. Parent/metadata/aggregation project.
war Default war:war binding creates a WAR. Installs POM + WAR. Servlet/web application packaging.

If a project says <packaging>pom</packaging> but an operator expects target/*.jar, the model and expectation disagree. Diagnose the POM before blaming the JAR plugin.

8. Inspect before mutating

./mvnw --version

# Effective model with source-line origins in comments.
./mvnw org.apache.maven.plugins:maven-help-plugin:3.5.2:effective-pom \
  -Dverbose -Doutput=target/effective-pom.xml

# Read a plugin goal description without executing the build lifecycle.
./mvnw org.apache.maven.plugins:maven-help-plugin:3.5.2:describe \
  -Dplugin=org.apache.maven.plugins:maven-jar-plugin:3.5.0 \
  -Dgoal=jar -Ddetail

# Record declared coordinates/packaging from the source POM.
grep -nE '<(groupId|artifactId|version|packaging)>' pom.xml

This sequence proves Maven/JDK identity, declared model, effective model, and plugin capability before you add or move any execution. In CI, capture the same concise evidence near the beginning of a job when lifecycle behavior matters to incident diagnosis.

9. Build-state and trust boundaries

State Source-controlled? Why it matters
pom.xml Yes Authoritative declared project/build model.
Wrapper scripts/properties Yes Select and verify the Maven runtime used by developers/CI.
Parent POM Usually coordinates in POM; parent artifact may be remote/local Can inject properties, plugin management, dependencies, and build behavior.
Super POM/default bindings No; supplied by Maven runtime Implicit defaults change when the Maven runtime changes.
target/ No Generated evidence/output; should be reproducible from declared inputs.
Local repository No Cache plus install target; can affect availability but is not source truth.
Remote repositories/plugin repositories Policy/configuration Supply model parents, dependencies, and build plugins—therefore a supply-chain boundary.

10. DevOps operating model

A production build should be explainable as a chain: declared POM → effective model → packaging/lifecycle bindings → ordered plugin goals → artifact/report/local-repository evidence. When CI only records “mvn package succeeded,” it hides the versions and model that produced the result. Record wrapper/Maven/JDK identity and retain enough lifecycle/artifact evidence to reproduce or diagnose the run.

Knowledge check

You invoke ./mvnw install. Does Maven run only the install:install goal?

A minimal POM omits <packaging>. What should you predict?

Why can two projects with identical pom.xml files but different Maven runtime versions execute different default plugin versions?

Is compiler:compile a phase?

Summary

The POM is Maven’s declared project model; the effective POM is the model after inheritance, profiles, and defaults. Packaging selects default lifecycle bindings. Lifecycles contain ordered phases, and phases execute bound plugin goals. A phase request walks every earlier phase in that lifecycle; a direct goal invocation does not. The wrapper fixes the Maven runtime that supplies the Super POM and core bindings, so wrapper identity is part of lifecycle reproducibility.

Next lesson

Trace one project through the lifecycle

Lesson 2 turns the model into evidence by authoring a tiny Maven project and inspecting what each phase and direct goal changes.

Official references and version notes

Version-sensitive statements in this lesson were checked against Apache Maven primary documentation on 2026-08-23. The production teaching baseline is Maven 3.9.16 through Maven Wrapper 3.3.4, running on JDK 21 and compiling the lab project with maven.compiler.release=17. Maven 4 is intentionally outside this chapter’s required path because it remains preview-stage. Default lifecycle plugin versions are properties of the Maven runtime and can change when the Maven runtime changes; re-check the matching core reference after an upgrade.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.