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 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:
-
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. - 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.
- A fresh Maven local repository should be empty before consumption and should contain the resolved artifact afterward.
-
A second attempt to publish different bytes as
2.0.0should 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/repositorycontent 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?
Otherwise Maven may satisfy the artifact locally and the test would not prove that the Nexus group can serve the release.
The release JAR exists in the group URL. Does that mean the group owns a second authoritative copy?
No. The group is an aggregated read view over members; the hosted release repository remains the authoritative publication target.
What does matching producer/group/client SHA-256 establish?
For this fixture, those three observed byte sequences are identical. It does not by itself establish trusted provenance or vulnerability safety.
The redeploy failure blocks an urgent fix. What should happen?
Build and publish a new version after the intended change is accepted. Do not overwrite the existing release coordinate.
A fresh client cannot resolve the release, but direct hosted retrieval works. Where should diagnosis focus first?
Group membership/order, client mirror/effective settings, authorization through the group, and routing—not the hosted artifact bytes that already proved retrievable.
Why is deleting blob files an invalid cleanup shortcut?
Blob content and relational metadata are coordinated state. Manual deletion can create inconsistency; use supported repository/component/task operations.
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.
Official references and version notes
- Nexus Repository Download and 3.95.x release notes — current self-hosted baseline.
- Sonatype: Maven Repositories — Maven version/layout policies, default repositories, grouping, settings and deployment examples.
- Configurable Repository Fields — hosted deployment policy, proxy caching, and group ordering.
- Components API and REST API Reference — supported component/asset inspection and upload boundaries.
- Apache Maven Download — current Maven 3 stable line.
- Apache Maven Settings Reference — localRepository, servers, mirrors, environment interpolation and profiles.
-
Using Mirrors for Repositories
—
mirrorOfmatching and single-repository patterns. - Apache Maven Deploy Plugin — deployment goals and repository-id matching.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.