Checkpoint Lab — Maven 4 Preview, Build Consumer POM, Compatibility, Migration Planning, and Maven 3 Production Baselines
Produce an auditable Maven 4 migration dossier with independently pinned runtimes, build and artifact comparisons, consumer-POM evidence, blockers, rollback, and a go/no-go decision.
A migration dossier is the handoff artifact that lets another engineer reproduce your decision. This checkpoint creates one for a small Maven 3 project and ends with two separate conclusions: whether Maven 4 should remain in compatibility testing, and whether it should become the production standard today.
Learning objectives
- Pin Maven 3.9.16 and Maven 4.0.0-rc-6 independently and record distribution/JDK identity.
- Capture build/test/effective-model/artifact evidence from equivalent isolated lanes.
- Run mvnup compatibility checks for 4.0.0 and 4.1.0 targets without mutating the baseline.
- Inspect one Maven 4 consumer-POM transformation in a Maven 4-only experimental copy.
- Document blockers, known issues, rollback mechanics, and a go/no-go decision.
- Revert every experimental Maven 4-only change and leave production baseline state untouched.
1. Checkpoint acceptance contract
Your dossier must contain: generation date; official Maven 3/Maven 4
status; Maven/JDK/wrapper identities; exact baseline and candidate
POM hashes; Maven 3 and Maven 4 verify results; effective-POM diff;
artifact checksum comparison; mvnup check output;
consumer-POM observation; plugin/extension inventory; known-issue
applicability; rollback instructions; and two decisions—continue compatibility testing?
and standardize production now?
2. Create the dossier workspace and record predictions
set -euo pipefail
ROOT="$PWD/../maven4-checkpoint"
rm -rf "$ROOT"
mkdir -p "$ROOT"/{baseline-m3,candidate-m4,candidate-41,evidence,downloads,.lab}
cat > "$ROOT/evidence/predictions.txt" <<'EOF'
Prediction 1: model 4.0.0 source can be built by both Maven 3.9.16 and Maven 4.0.0-rc-6.
Prediction 2: with the same JDK and pinned plugins, the simple JAR should have the same SHA-256 in both lanes.
Prediction 3: model 4.1.0 will intentionally remove Maven 3 build compatibility.
Prediction 4: installed consumer metadata may differ from the source 4.1.0 build POM while preserving consumer coordinates/dependencies.
EOF
3. Capture current official status as a dated assumption
In evidence/status.txt, write the date and the exact
official URLs you checked. Do not copy an old course claim blindly.
For this generation the evidence is:
Checked: 2026-08-24
Maven 3 GA baseline: 3.9.16
Maven 4 latest listed release: 4.0.0-rc-6 (2026-08-04)
Maven 4 status: not yet GA / release candidate
Maven 4 runtime JDK requirement: Java 17+
Migration tool: mvnup, built into Maven 4 since rc-4
Primary sources:
https://maven.apache.org/docs/history.html
https://maven.apache.org/docs/4.0.0-rc-6/release-notes.html
https://maven.apache.org/guides/mini/guide-migration-to-mvn4.html
https://maven.apache.org/tools/mvnup.html
If those pages show different facts when you run the checkpoint later, update the dossier and decision. Status is version-sensitive evidence.
4. Create one Maven 3-compatible source baseline
Put the BASE_POM from Lesson 2 plus the deterministic
App.java and one-test AppTest.java into
baseline-m3. Copy the trusted Maven 3.9.16 wrapper into
that directory, then clone the whole project to
candidate-m4 before changing any wrapper property.
# From a trusted wrapper-enabled Maven 3.9.16 project:
cp mvnw mvnw.cmd "$ROOT/baseline-m3/"
cp -R .mvn "$ROOT/baseline-m3/"
# Add pom.xml and src/ as shown in Lesson 2.
cp -R "$ROOT/baseline-m3/." "$ROOT/candidate-m4/"
sha256sum "$ROOT/baseline-m3/pom.xml" "$ROOT/candidate-m4/pom.xml" > "$ROOT/evidence/source-pom-before.sha256"
5. Independently pin and verify both runtimes
The Maven 3 wrapper is the pre-existing trusted baseline. For Maven
4, download rc-6 plus its SHA-512 sidecar, verify it, derive
SHA-256, and add that value to the candidate wrapper's
distributionSha256Sum exactly as in Lesson 2. Preserve
both wrapper property files in evidence.
cd "$ROOT"
MAVEN_USER_HOME="$ROOT/.lab/home-m3" ./baseline-m3/mvnw -v | tee evidence/maven3-version.txt
MAVEN_USER_HOME="$ROOT/.lab/home-m4" ./candidate-m4/mvnw -v | tee evidence/maven4-version.txt
java -version 2> evidence/java-version.txt
cp baseline-m3/.mvn/wrapper/maven-wrapper.properties evidence/wrapper-m3.properties
cp candidate-m4/.mvn/wrapper/maven-wrapper.properties evidence/wrapper-m4.properties
6. Build and compare the Maven 3 and Maven 4 lanes
cd "$ROOT/baseline-m3"
MAVEN_USER_HOME="$ROOT/.lab/home-m3" ./mvnw -Dmaven.repo.local="$ROOT/.lab/repo-m3" clean verify | tee "$ROOT/evidence/verify-m3.log"
MAVEN_USER_HOME="$ROOT/.lab/home-m3" ./mvnw org.apache.maven.plugins:maven-help-plugin:3.5.2:effective-pom -Doutput="$ROOT/evidence/effective-m3.xml"
sha256sum target/maven4-migration-lab-1.0.0.jar > "$ROOT/evidence/jar-m3.sha256"
cd "$ROOT/candidate-m4"
MAVEN_USER_HOME="$ROOT/.lab/home-m4" ./mvnw -Dmaven.repo.local="$ROOT/.lab/repo-m4" clean verify | tee "$ROOT/evidence/verify-m4.log"
MAVEN_USER_HOME="$ROOT/.lab/home-m4" ./mvnw org.apache.maven.plugins:maven-help-plugin:3.5.2:effective-pom -Doutput="$ROOT/evidence/effective-m4.xml"
sha256sum target/maven4-migration-lab-1.0.0.jar > "$ROOT/evidence/jar-m4.sha256"
diff -u "$ROOT/evidence/effective-m3.xml" "$ROOT/evidence/effective-m4.xml" > "$ROOT/evidence/effective-model.diff" || true
Record whether the JAR digest values match. If not, inspect JAR entries, manifest metadata, plugin behavior, and timestamps before continuing. Never wave away a byte difference because “both builds succeeded.”
7. Capture compatibility and migration-tool findings
cd "$ROOT"
mkdir -p .lab/tools
unzip -q downloads/apache-maven-4.0.0-rc-6-bin.zip -d .lab/tools
M4_HOME="$ROOT/.lab/tools/apache-maven-4.0.0-rc-6"
"$M4_HOME/bin/mvnup" check --directory candidate-m4 | tee evidence/mvnup-400.txt
"$M4_HOME/bin/mvnup" check --model-version 4.1.0 --all --directory candidate-m4 | tee evidence/mvnup-410.txt
Classify every finding as: required for Maven 4 compatibility while
staying model 4.0.0; optional Maven 4-only model improvement;
plugin/extension update; or unrelated cleanup. Do not let
mvnup apply cross the compatibility boundary
implicitly.
8. Make Maven 4-only changes only in candidate-41
Copy candidate-m4 to candidate-41, save a
before hash, and apply model 4.1.0 there. The Maven 3 baseline and
first Maven 4 compatibility candidate remain untouched.
cd "$ROOT"
rm -rf candidate-41
cp -R candidate-m4 candidate-41
sha256sum candidate-41/pom.xml > evidence/pom-41-before.sha256
"$M4_HOME/bin/mvnup" apply --model-version 4.1.0 --all --directory candidate-41 | tee evidence/mvnup-apply-410.txt
sha256sum candidate-41/pom.xml > evidence/pom-41-after.sha256
diff -u candidate-m4/pom.xml candidate-41/pom.xml > evidence/model-400-vs-410.diff || true
Prediction 3 should now be true by design: if
candidate-41 is truly model 4.1.0, Maven 3 is no longer
an allowed build runtime for that source model. Do not “test” that
by changing the production wrapper; the compatibility fact is
defined by the model/runtime contract.
9. Install the Maven 4-only copy and inspect consumer metadata
Build/install candidate-41 only into a new local
repository. Locate the installed POM by its actual GAV, copy it to
evidence, and compare semantic content with the source build POM.
cd "$ROOT/candidate-41"
MAVEN_USER_HOME="$ROOT/.lab/home-41" ./mvnw -Dmaven.repo.local="$ROOT/.lab/repo-41" clean install | tee "$ROOT/evidence/install-41.log"
# For the unchanged example coordinates:
INSTALLED="$ROOT/.lab/repo-41/dev/academy/maven4-migration-lab/1.0.0/maven4-migration-lab-1.0.0.pom"
cp "$INSTALLED" "$ROOT/evidence/consumer-41.pom"
diff -u pom.xml "$ROOT/evidence/consumer-41.pom" > "$ROOT/evidence/build-vs-consumer.diff" || true
Record: emitted model version, GAV, dependency semantics, whether build-only plugin configuration appears, and any warning. If the project publishes a BOM, add a separate test because rc-6 currently documents a BOM consumer-POM property-reference known issue.
10. Inventory plugins, extensions, lifecycle assumptions, and CI changes
Create evidence/compatibility-inventory.md with one row
per executable build dependency or platform assumption:
| Item | Current version/state | Maven 4 evidence | Blocker? | Owner/next action |
|---|---|---|---|---|
| Maven Compiler Plugin | 3.15.0 | Verify succeeds in rc-6 lane | No for lab | Keep pinned. |
| Maven JAR Plugin | 3.5.1 | Verify succeeds; checksum compared | No for lab | Keep pinned. |
| Surefire / JUnit | 3.5.6 / 6.1.3 | One required test runs in both lanes | No for lab | Preserve report evidence. |
| Core extensions | None in lab | N/A | No | Real project must inventory .mvn/extensions.xml. |
| Launcher JDK | 21 | Meets Maven 4 Java 17+ requirement | No | Pin CI image/toolchain. |
| Build POM model | 4.0.0 baseline; 4.1.0 experiment | Dual build works before 4.1.0; experiment Maven 4-only | Decision boundary | Do not merge 4.1.0 while Maven 3 rollback required. |
| Publishing | Disabled in checkpoint | Consumer POM inspected only in isolated repo | No production publish | Run repository-specific staging test later. |
11. Document blockers and current known issues
At minimum, the dossier should explicitly answer:
- Is Maven 4 GA today? No, rc-6 on this generation date.
- Does every build agent provide Java 17+? Record actual image evidence.
- Do any plugins/extensions use unsupported/internal APIs? Record coordinates and test results.
- Do Maven 3 and Maven 4 required test suites both execute and fail correctly?
- Are JAR checksums and published/installed dependency semantics acceptable?
- Does the project publish BOMs affected by the rc-6 known issue?
- Can the release lane revert to the Maven 3 wrapper without reverting unrelated source work?
12. Write two decisions, not one
Use a short record such as:
Decision date: 2026-08-24
Compatibility lane: GO
Reason: Maven 4.0.0-rc-6 is the latest RC; JDK 21 is available; the controlled
model-4.0.0 build/test lane is valuable for discovering migration blockers.
Production standardization: NO-GO
Reason: Apache still classifies Maven 4 as not yet GA. Keep Maven 3.9.16 as the
production baseline. Re-evaluate when Maven 4 reaches GA and after plugin/
extension, consumer-metadata, CI, and rollback gates are satisfied.
Model 4.1.0 adoption: DEFER
Reason: it intentionally removes Maven 3 build compatibility; no required Maven
4-only feature justifies that rollback cost in this checkpoint.
If your organization explicitly accepts pre-GA tooling, document that exception separately; do not rewrite the upstream release status.
13. Roll back every experimental change
Rollback verification means more than deleting files. Re-run the baseline wrapper after candidate cleanup to prove the original path still works.
cd "$ROOT"
rm -rf candidate-m4 candidate-41 .lab/repo-m4 .lab/repo-41 .lab/tools
cd baseline-m3
MAVEN_USER_HOME="$ROOT/.lab/home-m3-rollback" ./mvnw -Dmaven.repo.local="$ROOT/.lab/repo-m3-rollback" clean verify | tee "$ROOT/evidence/rollback-m3-verify.log"
Delete the whole checkpoint directory only after copying any dossier
evidence you intend to retain. Never use this lab as a reason to
remove the normal user ~/.m2 state.
14. Verification checklist
- Current Maven release status is dated and sourced.
- Maven 3.9.16 and Maven 4.0.0-rc-6 are independently pinned.
- Both baseline/candidate use the intended JDK 21.
- Candidate Maven 4 distribution integrity is verified before execution.
- Model 4.0.0 source is compared under both runtimes before 4.1.0 edits.
- Required tests/build scope complete under both lanes.
- Artifact SHA-256 results are compared and any mismatch explained.
- Effective model/warning differences are preserved.
-
mvnup checkevidence exists for 4.0.0 and 4.1.0 targets. - Consumer POM semantics are inspected in an isolated repository.
- Plugin/extension and CI runtime assumptions are inventoried.
- Known RC issues relevant to artifact types are documented.
- Production publishing/signing credentials were never introduced to the RC lane.
- Rollback to Maven 3 is executed and verified.
Knowledge check
Why does the dossier contain separate “compatibility lane” and “production standardization” decisions?
Because testing Maven 4 RC can be valuable even when its upstream release status and organizational gates do not justify making it the production default.
What is the strongest evidence that Maven 4 did not change this simple artifact?
Equivalent required build/test scope plus matching artifact checksums under controlled JDK/plugin/source inputs; even then, also inspect consumer metadata and real-project integrations.
Why keep candidate-41 separate from candidate-m4?
candidate-m4 isolates Maven-core compatibility with model 4.0.0; candidate-41 separately tests Maven 4-only model changes so their effects are not conflated.
If a Maven 4 RC known issue affects your published BOM, what should the decision record say?
Record it as an applicable blocker or explicit risk, test the exact BOM consumer metadata, and avoid production publication from the RC lane until resolved/accepted.
What proves rollback is real?
After removing experimental candidate state, the independently pinned Maven 3 baseline still runs its required build successfully from controlled state.
When can the model 4.1.0 decision change from defer to adopt?
When Maven 4-only feature value is intentional, Maven 3 build rollback is no longer required, compatibility gates pass, consumer metadata is verified, and the runtime release policy permits it.
15. Production operating model and Chapter 15 bridge
Chapter 14 adds an upgrade rule to the production build-engineering model: major build-tool versions move through prepare → parallel test → controlled migration, with artifact/metadata invariants and rollback preserved at every boundary. Version status, launcher JDK, plugins/extensions, POM model, consumer metadata, CI images, and repository publishing are separate migration surfaces.
Chapter 15 now begins the Gradle half of the course. The same discipline carries over—wrapper identity, JDK/runtime boundaries, executable build scripts, generated/cache state, and reproducible evidence—but Gradle has a different project/task/configuration model that must be learned on its own terms.
Official references and version notes
Version-sensitive statements in this lesson were checked against current Apache Maven primary documentation on 2026-08-24.
- Maven releases history — Current GA and Maven 4 release-candidate status, release dates, and Java requirements.
- What is new in Maven 4 — Java 17 runtime requirement, consumer POM, model 4.1.0 features, BOM packaging, and Maven 4 behavior.
- Starting with Maven 4 — Official prepare → test → migrate strategy, compatibility changes, model 4.1.0 guidance, and rollback-friendly staging.
- Maven Upgrade Tool (mvnup) — Built-in Maven 4 migration tool, check/apply workflow, and 4.0.0 versus 4.1.0 target behavior.
- Maven 4.0.0-rc-6 release notes — Current RC status, migration notes, fixed RC-5 issues, and remaining known issues.
- Apache Maven Wrapper 3.3.4 — Stable wrapper release and integrity-capable wrapper behavior.
- Maven plugins compatibility plan — Use current plugin requirements and compatibility policy when inventorying real-project plugins/extensions.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.