Chapter 06Lesson 05190–240 min

Checkpoint Lab — Maven 2 Repositories, Snapshots, Releases, Metadata, Checksums, and Maven Client Configuration

Publish and consume a synthetic Maven component through a disposable Nexus topology, prove release identity from fresh-client evidence, inspect generated metadata/checksums, and clean up only the lab state.

Checkpoint labRelease identityFresh local repoEvidence packetSafe cleanup

Checkpoint outcomes

  • Build a disposable Maven release/snapshot/proxy/group topology and record its exact assumptions.
  • Publish a synthetic Maven release without placing repository credentials in project source or command-line arguments.
  • Verify POM/JAR, Maven metadata and component/assets using Nexus UI/API/direct requests.
  • Consume the release through the group from a fresh Maven local repository and prove checksum identity independently.
  • Produce an evidence packet, explain predicted state changes, and remove only lab repositories/client state through supported operations.

Checkpoint boundary. Perform this only on a disposable loopback Nexus Repository Community Edition 3.95.2 instance. The lab uses synthetic namespace com.example.academy. Never substitute employer coordinates, production blob stores/databases, real CI secrets, or a public Nexus endpoint.

1. Scenario and acceptance contract

You are onboarding a small JVM team. Developers must read internal releases, snapshots and Central through one Nexus group; publication must go only to hosted repositories; stable releases must be write-once; Maven client state must be isolated; and the final evidence must prove that the release bytes consumed by a fresh client are the same bytes published by the producer.

Pinned assumption Checkpoint value
Nexus Community Edition 3.95.2, self-hosted on 127.0.0.1:8081
Nexus runtime Java 21 / bundled supported runtime; H2 acceptable only because this is disposable
Maven Apache Maven 3.9.16 stable line, executed on JDK 21 for this lab so the JDK jar tool is available
Blob/database Default file blob store + embedded H2 for this local checkpoint; no direct internals access
Repositories academy-ch06cp-releases, -snapshots, -central, -public
Artifact com.example.academy:ch06-checkpoint:2.0.0
Credentials Disposable least-privilege publisher injected at runtime; no credential committed to project files

2. Predict state before you mutate it

Write these predictions into predictions.md before creating the repositories:

  1. After publishing 2.0.0, the release hosted repository will gain one Maven component with at least POM and JAR assets; Nexus relational metadata and the selected blob store will both change.
  2. The public group should expose the release without receiving an independent authoritative upload; group routing changes what readers can see, not the identity of the hosted release bytes.
  3. A fresh Maven local repository should be empty before consumption and should contain the resolved artifact afterward.
  4. A second attempt to publish different bytes as 2.0.0 should fail because the release repository uses Disable redeploy.

3. Setup and preflight

set -eu
NX_URL=http://127.0.0.1:8081
LAB="${TMPDIR:-/tmp}/academy-nexus-ch06-checkpoint"
rm -rf "$LAB"
mkdir -p "$LAB/m2-empty" "$LAB/project/payload" "$LAB/evidence"
mvn --version | tee "$LAB/evidence/00-maven-version.txt"
curl -fsS "$NX_URL/service/rest/v1/status" | tee "$LAB/evidence/01-nexus-status.txt"
curl -fsS "$NX_URL/service/rest/v1/repositories" > "$LAB/evidence/02-repos-before.json"

In Nexus UI, confirm the instance is disposable, loopback-only, and has sufficient free disk. Record version/runtime/database mode using supported system information. Do not inspect H2 files directly.

4. Create checkpoint repositories

Create four Maven repositories:

Repository Settings
academy-ch06cp-releases hosted · Release · Strict · Disable redeploy
academy-ch06cp-snapshots hosted · Snapshot · Strict · Allow redeploy
academy-ch06cp-central proxy · Release · Strict · https://repo1.maven.org/maven2/
academy-ch06cp-public group · members releases, snapshots, central in that order

Create a disposable publisher with browse/read on the group and add/edit/browse/read on the two hosted repositories. Record the authorization matrix in the evidence packet.

5. Isolate Maven configuration and credentials

read -r -p 'Disposable Nexus username: ' NX_USER
read -r -s -p 'Disposable Nexus password: ' NX_PASS; echo
export NX_USER NX_PASS
export MAVEN_LAB_REPO="$LAB/m2-empty"

cat > "$LAB/settings.xml" <<'XML'
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0">
  <localRepository>${env.MAVEN_LAB_REPO}</localRepository>
  <servers>
    <server><id>academy-ch06cp-releases</id><username>${env.NX_USER}</username><password>${env.NX_PASS}</password></server>
    <server><id>academy-ch06cp-snapshots</id><username>${env.NX_USER}</username><password>${env.NX_PASS}</password></server>
  </servers>
  <mirrors><mirror><id>academy-ch06cp-public</id><mirrorOf>*</mirrorOf><url>http://127.0.0.1:8081/repository/academy-ch06cp-public/</url></mirror></mirrors>
  <profiles><profile><id>academy-ch06cp</id><repositories><repository><id>central</id><url>http://central.invalid/</url><releases><enabled>true</enabled></releases><snapshots><enabled>true</enabled></snapshots></repository></repositories><pluginRepositories><pluginRepository><id>central</id><url>http://central.invalid/</url><releases><enabled>true</enabled></releases><snapshots><enabled>true</enabled></snapshots></pluginRepository></pluginRepositories></profile></profiles>
  <activeProfiles><activeProfile>academy-ch06cp</activeProfile></activeProfiles>
</settings>
XML

Windows PowerShell: keep the same XML in a temporary directory; use protected runtime environment variables or your local credential mechanism, not a committed password. Use Get-FileHash for SHA-256 verification.

6. Build the deterministic release fixture

printf 'course=nexus-repository
chapter=06
version=2.0.0
' > "$LAB/project/payload/evidence.txt"
(cd "$LAB/project/payload" && jar --create --file ../ch06-checkpoint-2.0.0.jar evidence.txt)
cat > "$LAB/project/pom.xml" <<'XML'
<project xmlns="http://maven.apache.org/POM/4.0.0"><modelVersion>4.0.0</modelVersion><groupId>com.example.academy</groupId><artifactId>ch06-checkpoint</artifactId><version>2.0.0</version><packaging>jar</packaging></project>
XML
sha256sum "$LAB/project/ch06-checkpoint-2.0.0.jar" | tee "$LAB/evidence/03-producer-sha256.txt"

The SHA-256 is the producer's byte-identity observation. It is not a signature or provenance attestation.

7. Publish once to the hosted release repository

mvn -s "$LAB/settings.xml" org.apache.maven.plugins:maven-deploy-plugin:3.1.4:deploy-file   -DrepositoryId=academy-ch06cp-releases   -Durl="$NX_URL/repository/academy-ch06cp-releases/"   -Dfile="$LAB/project/ch06-checkpoint-2.0.0.jar"   -DpomFile="$LAB/project/pom.xml"   | tee "$LAB/evidence/04-release-deploy.txt"

Now verify the predicted state independently: Browse/Search should show the component; the hosted repository should contain POM and JAR assets; direct group retrieval should find the same release; database metadata and blob usage should have increased.

8. Capture protocol and Nexus evidence

curl -fsS "$NX_URL/service/rest/v1/search?repository=academy-ch06cp-releases&group=com.example.academy&name=ch06-checkpoint&version=2.0.0"   | tee "$LAB/evidence/05-search.json"

curl -fsS "$NX_URL/repository/academy-ch06cp-public/com/example/academy/ch06-checkpoint/2.0.0/ch06-checkpoint-2.0.0.pom"   | tee "$LAB/evidence/06-retrieved.pom"

curl -fsS "$NX_URL/repository/academy-ch06cp-public/com/example/academy/ch06-checkpoint/2.0.0/ch06-checkpoint-2.0.0.jar"   -o "$LAB/evidence/07-retrieved.jar"
sha256sum "$LAB/evidence/07-retrieved.jar" | tee "$LAB/evidence/08-retrieved-sha256.txt"

The producer and group-retrieved SHA-256 values must match. If they do not, stop and diagnose; do not continue to “prove” consumption.

9. Consume through the group from a fresh Maven local repository

Delete only the checkpoint's disposable Maven local directory, not your normal Maven cache, then recreate it empty. The request should be forced through the Nexus group.

rm -rf "$LAB/m2-empty"
mkdir -p "$LAB/m2-empty"
MAVEN_LAB_REPO="$LAB/m2-empty" mvn -s "$LAB/settings.xml" -U   org.apache.maven.plugins:maven-dependency-plugin:3.9.0:get   -Dartifact=com.example.academy:ch06-checkpoint:2.0.0   | tee "$LAB/evidence/09-fresh-client.txt"

sha256sum "$LAB/m2-empty/com/example/academy/ch06-checkpoint/2.0.0/ch06-checkpoint-2.0.0.jar"   | tee "$LAB/evidence/10-client-cache-sha256.txt"

Compare all three observations: producer JAR, direct group retrieval, and fresh Maven local-cache JAR. They should have one SHA-256 value.

10. Failure drill: attempt a mutable release

Predict the result first: a different JAR at the same release coordinate must be rejected by Disable redeploy.

printf 'course=nexus-repository
chapter=06
version=2.0.0
mutated=true
' > "$LAB/project/payload/evidence.txt"
(cd "$LAB/project/payload" && jar --create --file ../ch06-checkpoint-2.0.0-mutated.jar evidence.txt)
set +e
mvn -s "$LAB/settings.xml" org.apache.maven.plugins:maven-deploy-plugin:3.1.4:deploy-file   -DrepositoryId=academy-ch06cp-releases   -Durl="$NX_URL/repository/academy-ch06cp-releases/"   -Dfile="$LAB/project/ch06-checkpoint-2.0.0-mutated.jar"   -DpomFile="$LAB/project/pom.xml"   2>&1 | tee "$LAB/evidence/11-redeploy-rejected.txt"
RC=${PIPESTATUS[0]}
set -e
printf 'Expected failure exit: %s
' "$RC"

Verify the original release SHA-256 through the group again. The correct repair is a new version, not weakening the release repository.

11. Required evidence packet

  • Nexus and Maven version output.
  • Repository topology and version/deployment policies.
  • Authorization matrix for the disposable publisher.
  • Producer, direct-retrieval and fresh-Maven-cache SHA-256 values.
  • Search/API response showing the release component/assets.
  • Snapshot/release metadata observations from the earlier workflow or an equivalent screenshot/API capture.
  • Original immutable-redeploy failure output and the explanation of why it is a healthy control.
  • A one-paragraph statement distinguishing Maven local cache, Nexus proxy cache, Nexus database metadata, and Nexus blob content.

12. Cleanup and rollback

First preserve the evidence packet outside the Nexus lab directory if required. Then remove the four academy-ch06cp-* repositories through the supported Nexus UI/API. Delete the disposable user. Remove the local lab directory. Do not delete blob-store files or database rows to “finish” cleanup.

unset NX_PASS NX_USER MAVEN_LAB_REPO
rm -rf "$LAB"
printf '%s\n' 'Client checkpoint state removed. Nexus lab repositories/user should already be deleted through supported Nexus controls.'

13. Verification checklist

  • All four lab repositories are absent after supported cleanup.
  • No production/global Maven settings or normal ~/.m2/repository content was modified.
  • No secret appears in the POM, HTML, shell history, Maven command arguments, or evidence packet.
  • Release byte identity matched at producer, group retrieval, and fresh Maven cache.
  • The mutable release attempt was rejected and its original error was retained.
  • No Nexus database/blob files were edited or manually deleted.

Knowledge check

Why must the fresh Maven cache be empty before the consumption proof?

The release JAR exists in the group URL. Does that mean the group owns a second authoritative copy?

What does matching producer/group/client SHA-256 establish?

The redeploy failure blocks an urgent fix. What should happen?

A fresh client cannot resolve the release, but direct hosted retrieval works. Where should diagnosis focus first?

Why is deleting blob files an invalid cleanup shortcut?

14. What Chapter 06 adds to the production operating model

You can now treat Maven as a protocol with explicit coordinate, metadata, cache, authentication and repository-topology semantics. A production operating model can enforce one governed read path, separate snapshot/release publication, preserve release identity, scope publisher credentials, collect checksum evidence, and debug clients without damaging shared repository state.

Chapter 07 applies the same discipline to npm, where scopes, package metadata, tokens and JavaScript package behavior differ substantially from Maven.

Next chapter

npm repositories and JavaScript supply chains

Move from Maven GAV/metadata semantics to npm scopes, package documents, tokens and proxy behavior without assuming the protocols are interchangeable.

Official references and version notes

Version-sensitive statements were rechecked against Sonatype and Apache Maven primary documentation on 2026-08-26. The mandatory lab pins Nexus Repository Community Edition 3.95.2 and Apache Maven 3.9.16. Nexus 3.95.2 was released 2026-08-21; Maven 3.9.16 is the current recommended Maven 3 release. Nexus 3.87+ requires Java 21 when using an external JVM and official Nexus packages include a bundled Java 21 runtime. Re-check live support/download pages before executing these labs.

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.