Chapter 31Lesson 01~310 minutes

Production Capstone: Build, Test, Secure, Publish, and Optimize a Multi-Module JVM Platform: Requirements, Constraints, and Target Architecture

Translate a production-style JVM platform brief into measurable build requirements before writing build logic. Choose a Gradle-first architecture with an explicit Maven consumer boundary, define trust and evidence flows, and establish invariants that can be independently verified.

Capstone architectureGradle 9.7.1Maven boundaryBuild invariantsTrust model

Learning objectives

  • Translate business/release/security requirements into build-engineering invariants before choosing commands.
  • Separate Gradle runtime, Java toolchain, dependency graph, repository state, caches, publications, and CI evidence.
  • Choose a Gradle-first multi-project design with one Maven interoperability boundary instead of duplicate full builds.
  • Define measurable clean-room, test, reproducibility, origin, secret, promotion, and cache-trust acceptance criteria.
  • Read two compound diagrams that cover architecture/build graph and trust/artifact/evidence flows.

Capstone rule: evidence before confidence. A successful build is only one signal. This chapter treats tool identity, dependency origin, test coverage, artifact bytes, publication metadata, cache provenance, and promotion history as separate evidence that must agree.

1. Production brief: Orbit JVM Platform

Orbit is a fictional internal JVM platform with a shared text-normalization library and a small command-line application. Two product teams change application behavior independently, while a platform team owns dependency/version policy and build controls. Releases must run on Java 17, build on controlled JDK 21 agents, and be consumable by one legacy Maven service.

The business requirement is not “use Gradle.” It is: produce a tested, traceable, reproducible artifact that can be promoted without rebuilding, while keeping dependency and credential trust boundaries explicit. Gradle is chosen as the primary implementation because the course has already established its multi-project, platform, test-suite, verification, cache, and publishing models. Maven remains a consumer/interoperability contract—not a second source build.

2. Translate the brief into explicit build requirements

Concern Requirement Independent evidence
Compatibility Gradle runs on JDK 21; Java sources compile with --release 17. ./gradlew -version, toolchain report, javap -verbose major version 61.
Build identity Gradle Wrapper 9.7.1 distribution and wrapper JAR are verified. Pinned distributionSha256Sum; wrapper JAR SHA-256 comparison.
Module ownership platform → core → app policy/dependency direction is explicit. projects, dependency reports, project paths.
Dependency policy Commons Lang 3.20.0 and JUnit 6.1.3 are governed by the platform; project aliases stay versionless. Platform constraints, lockfiles, dependencyInsight.
Tests Unit and integration evidence is required; integration suite participates in check. Task graph, XML/HTML reports, test counts, failing-test propagation.
Supply chain Only declared repositories may resolve dependencies; external artifacts are checksum-verified. Settings repository policy plus reviewed gradle/verification-metadata.xml.
Artifact identity JARs are reproducible across clean source copies and isolated Gradle User Homes. SHA-256 comparison from two clean directories.
Publication Platform and core publish to disposable staging; clean Maven consumer resolves the promoted core. Repository tree, POM/module metadata, Maven clean-repo compile.
Promotion Release bytes are copied from staging after acceptance; no rebuild is allowed in promotion. Before/after artifact SHA-256 equality.
Secrets/caches No committed credentials; cache readers/writers are bounded by trust level. Repository scan, provider-neutral CI contract, cache policy.

3. Name the state stores before changing any of them

Orbit has several independent state stores. Treating them as “the build cache” would hide important failure modes:

State store Examples What it means
Source/governance settings.gradle.kts, build scripts, catalog, lockfiles, verification metadata Declared model and policy under review.
Wrapper/toolchain gradlew, wrapper JAR/properties, installed JDKs Executable build-tool/compiler identity.
Resolved dependencies Gradle dependency metadata/artifact cache Downloaded external inputs; reusable only within explicit trust policy.
Workspace outputs build/ directories Current checkout outputs; not authoritative promotion input unless captured as artifacts.
Build/configuration caches Gradle build cache, configuration cache Derived reusable state; correctness depends on complete input modeling.
Staging/release repository Disposable Maven-layout file repositories Published contract consumed by other builds.
CI evidence Test reports, source manifest, tool versions, checksums, logs Audit trail connecting source → build → artifact → promotion.

4. Architecture + dependency + build graph

Architecture, dependency, and build graph
flowchart TD
  W[Verified Gradle Wrapper 9.7.1] -->|launches pinned build tool| G[Gradle runtime on JDK 21]
  G -->|configures settings/build model| R[Root build]
  R -->|project :platform provides constraints| P[:platform java-platform]
  R -->|project :core uses platform + source| C[:core java-library]
  R -->|project :app uses core + platform| A[:app application]
  P -->|version policy edge| C
  P -->|version policy edge| A
  C -->|project dependency/API edge| A
  C -->|unit verification| CT[core:test]
  A -->|unit verification| AT[app:test]
  A -->|integration verification| IT[app:integrationTest]
  CT -->|required by check| Q[check gate]
  AT -->|required by check| Q
  IT -->|explicitly attached| Q
  Q -->|accepted component| PUB[staging publication]

The wrapper-to-Gradle arrow transfers executable tool identity. Gradle-to-root transfers the configured model. Platform-to-core/app arrows transfer version constraints, not JAR code. Core-to-app transfers compiled API/runtime classes. Test arrows transfer pass/fail evidence into the check gate. Only an accepted gate may feed the staging publication.

5. Trust boundary + artifact + evidence flow

Trust boundary, artifact flow, and evidence flow
flowchart TD
  SRC[Reviewed source + governance] -->|hash source manifest| BUILD[Ephemeral build workspace]
  UP[(Maven Central)] -->|verified dependency bytes| BUILD
  BUILD -->|test XML/HTML + tool identity| EVID[Evidence bundle]
  BUILD -->|core-1.0.0.jar + POM + module metadata| STAGE[(Disposable staging repo)]
  STAGE -->|SHA-256 verified, copy exact bytes| REL[(Disposable release repo)]
  REL -->|Maven repository contract| MC[Maven 3.9.16 clean consumer]
  EVID -->|binds source + tests + checksums| APPROVE[Promotion decision]
  APPROVE -->|authorizes copy, never rebuild| REL
  CACHE[(Dependency/build caches)] -->|read only if trust policy allows| BUILD
  BUILD -->|write only from approved lane| CACHE

The upstream repository is outside the project trust boundary, so its artifacts require repository policy and verification metadata. The build workspace is disposable. Staging is not release authority. The promotion decision consumes evidence, and the release repository receives bytes copied from staging. The Maven consumer proves an external metadata contract. Cache arrows are conditional: a cache hit is accepted only when the cache writer/read policy matches the build’s trust level.

6. Write invariants before implementation

Invariant ID Acceptance criterion Failure blocks
I-01 Tool identity Gradle 9.7.1 distribution checksum and wrapper JAR checksum match official values; JDK 21 recorded. Any build execution.
I-02 Target runtime All application/library class files target Java 17 (major 61). Publication/promotion.
I-03 Graph policy No unmanaged external version; lock/constraint evidence explains selected versions. Merge/release.
I-04 Required tests Unit + integration suites execute and report; zero/missing integration execution is failure. Publication.
I-05 Clean build Fresh source copy + isolated Gradle User Home succeeds from declared state. Release.
I-06 Reproducibility Two clean copies produce identical core JAR SHA-256. Immutable promotion claim.
I-07 Origin/integrity Dependency repositories are centralized and verification metadata is reviewed. Trusted build claim.
I-08 Secret hygiene No real repository credentials/signing keys are committed or printed. CI/release.
I-09 Immutable promotion Release JAR checksum equals staged JAR checksum; promotion does not run compilation/tests. Release.
I-10 Bounded caches Untrusted branches cannot write shared authoritative caches; build outputs are not restored as dependency caches. CI trust boundary.
I-11 Maven boundary Maven 3.9.16 clean consumer resolves/compiles against promoted core without Gradle-only assumptions. Interoperability acceptance.

7. Pin the current baseline explicitly

Layer Pinned capstone baseline Why
Gradle 9.7.1 Current recommended 9.7 patch release at generation time.
Gradle distribution SHA-256 acd53f1edaf02f1a8ff99879f8a34b302661a057d9b063ae9e35b552f804d20a Wrapper verifies downloaded -bin distribution before use.
Gradle Wrapper JAR SHA-256 7a9ce74cff467ca1bf60a4fcd9f05185acceda4d0f382434d393e17864262c5d Bootstrap JAR is executable supply-chain input.
Build/compiler JDK 21 Controlled build/toolchain runtime for the capstone.
Java release target 17 Supported runtime contract and JUnit 6 floor.
JUnit 6.1.3 Current documented course test baseline; requires Java 17+.
Commons Lang 3.20.0 Concrete governed external dependency.
Maven boundary Maven 3.9.16 via Wrapper 3.3.4 Current GA Maven line; Maven 4 RC remains preview.

8. Read-only preflight before creating the capstone

Start from identity and filesystem evidence. Do not generate wrappers or mutate caches yet:

java -version
javac -version

test -f gradlew && ./gradlew -version || true
test -f gradle/wrapper/gradle-wrapper.properties && cat gradle/wrapper/gradle-wrapper.properties || true

git status --short 2>/dev/null || true
pwd
python --version

If the project Wrapper is not present, bootstrap it only from a trusted Gradle 9.7.1 installation or from a previously reviewed course skeleton. A wrapper script downloaded ad hoc from an arbitrary source defeats invariant I-01 before the build begins.

9. Mandatory local/free path and optional enterprise boundaries

The mandatory capstone requires only a JDK, the checked-in wrapper, Git/Python/shell utilities, Maven Central for initial external dependencies, and project-local directories. Staging and release repositories are ordinary directories using Maven repository layout. The Maven consumer uses an isolated local repository.

Hosted CI, Nexus/Artifactory, Develocity, remote HTTP build caches, HSM-backed signing, and cloud secret managers are valid production integrations but are not required here. Their role is represented as an interface contract: trusted inputs, writers/readers, authentication, retention, immutable promotion, and evidence export.

10. Why Gradle primary + Maven boundary is the chosen architecture

Alternative Benefit Cost/risk Capstone decision
Two complete Maven + Gradle builds Maximum syntax practice Duplicate source-build logic, two policy surfaces, divergence risk Reject.
Maven primary only Predictable lifecycle, broad interoperability Would underuse later Gradle governance/cache/variant material Not chosen.
Gradle primary + Maven clean consumer One source build plus real cross-tool contract Requires careful POM/platform metadata mapping Choose.
Gradle primary + no Maven check Simpler Does not prove mixed-estate boundary from Chapter 30 Reject.

11. Implementation order is itself a control

Lesson 2 follows this dependency order: wrapper/toolchain → settings/repositories → module graph → version policy → tests → lock/verification metadata → packaging → staging publication → clean Maven consumption → evidence bundle → immutable promotion → performance baseline. Later steps depend on evidence produced by earlier steps. Do not start by copying a giant final build script: incremental construction makes causal failures visible.

Knowledge check

Why is the Maven build not duplicated in the capstone?

What does the :platform project contribute to :core?

Why does a matching dependency lockfile not prove a trustworthy build?

Which invariant forbids rebuilding during promotion?

Why is cache trust an architectural concern?

What does Java class major version 61 prove?

Official references and version notes

Version-sensitive statements were rechecked against primary documentation on 2026-08-24. Mandatory work remains local/free. Hosted CI, commercial build analytics, production repository managers, remote caches, and real signing/credential systems are optional integration boundaries only.

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.