Skip to content

AGS-13/AGS-14: Java 21 baseline, enforced, with a committed Maven wrapper - #15

Open
Ugbot wants to merge 1 commit into
mainfrom
java21-baseline-enforced
Open

AGS-13/AGS-14: Java 21 baseline, enforced, with a committed Maven wrapper#15
Ugbot wants to merge 1 commit into
mainfrom
java21-baseline-enforced

Conversation

@Ugbot

@Ugbot Ugbot commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Java 21 was decided as the baseline, but all 13 poms still declared 17 and nothing enforced or provisioned the toolchain. These two tickets are coupled — enforcing a baseline you have not actually set is meaningless — so they land together.

Baseline (AGS-13)

All 13 poms now declare 21, via <release> rather than source/target.

That mechanism change matters independently: with source/target, javac links against the host JDK's API, so code can reference post-baseline methods, compile clean, and then NoSuchMethodError on a real baseline JVM. release pins the API too. ports/quarkus and ports/kafka-streams already did this correctly and were left alone. No literal 17 remains in any pom.

Verified it actually took effect, not just declared — emitted class files are major version: 65.

Enforcement (AGS-14)

  • Committed mvnw / mvnw.cmd / .mvn/wrapper/, pinned to Maven 3.9.16. The build no longer needs a preinstalled mvn. This is not hypothetical: when the home directory was wiped on 2026-07-26, the only Maven on the machine lived inside the deleted ~/.m2, so the loss took the build tool with the cache. A committed wrapper makes that a non-event.
  • maven-enforcer-pluginrequireJavaVersion [21,) and requireMavenVersion [3.9,), each with an actionable message so a contributor on JDK 17 is told the baseline rather than handed an obscure compiler error.
  • Lombok 1.18.38 → 1.18.46 (1.18.40 was the first release supporting JDK 25), so a later baseline bump is not blocked by annotation processing.
  • Runtime --add-opens, which surefire had but no launcher did. .mvn/jvm.config covers every mvn exec:java path — exec:java runs in the Maven JVM — and a new examples-bin/jvm-opts.sh holds the single flag list that the two bare java -jar launchers source. Also chmod +x run-banking-local.sh, which was 100644 while all 14 siblings were 100755.
  • CI now calls ./mvnw instead of the runner's mvn, so every run exercises the wrapper.

Verification

Both rules were checked for firing, not just presence — I temporarily demanded JDK 99 and confirmed the build failed with our own message rather than a generic error, then reverted:

[ERROR] This project requires JDK 21 or newer (see docs/audit-backlog.md, AGS-13/AGS-14).

Full local build on JDK 21.0.12 through ./mvnw:

Module Result
jagentic-core 95 tests
agentic-flink (main) 770 tests
ports (kafka-streams, temporal, pekko, pulsar) 2 each; spring/quarkus compile
agentic-pekko 14
tool-services (packs + app) 15 + 11
a2a-gateway 9
banking-job assembly only

All green, plus enforcer:3.5.0 reporting both rules passed.

Considered and skipped

maven-toolchains-plugin — with the enforcer plus a pinned wrapper it adds a toolchains.xml prerequisite for no additional guarantee on this project.

Backlog entries for AGS-13 and AGS-14 are marked done in docs/audit-backlog.md.

🤖 Generated with Claude Code

…pper

Java 21 was decided as the baseline but all 13 poms still declared 17, and
nothing enforced or provisioned the toolchain.

Baseline (AGS-13):
- All 13 poms now declare 21, via `release` rather than source/target. With
  source/target javac links against the *host* JDK's API, so code can reference
  post-baseline methods, compile clean, and then NoSuchMethodError on a real
  baseline JVM. Verified the change took effect: emitted class files are major
  version 65.
- ports/quarkus and ports/kafka-streams already used <release> and were left
  alone. No literal 17 remains in any pom.

Enforcement (AGS-14):
- Committed mvnw / mvnw.cmd / .mvn/wrapper, pinned to Maven 3.9.16. The build
  no longer needs a preinstalled mvn — the exact failure mode that cost a
  reinstall when the home directory was wiped on 2026-07-26, since the only mvn
  on that machine lived inside the deleted ~/.m2.
- maven-enforcer-plugin: requireJavaVersion [21,) and requireMavenVersion
  [3.9,), each with an actionable message. Verified the rule actually fires by
  temporarily demanding JDK 99 and confirming the build failed with our text,
  not a generic error.
- Lombok 1.18.38 -> 1.18.46 (1.18.40 first supported JDK 25), so a later
  baseline bump isn't blocked by annotation processing.
- Runtime --add-opens, which surefire had but no launcher did: .mvn/jvm.config
  covers every `mvn exec:java` path (exec:java runs in the Maven JVM), and a new
  examples-bin/jvm-opts.sh holds the single flag list the two bare `java -jar`
  launchers source. Also chmod +x run-banking-local.sh, which was 100644 while
  all 14 siblings were 100755.
- CI now invokes ./mvnw instead of the runner's mvn, so every run exercises the
  wrapper.

A maven-toolchains-plugin was considered and skipped: with the enforcer plus a
pinned wrapper it adds a toolchains.xml prerequisite for no extra guarantee.

Verified locally on JDK 21.0.12 via ./mvnw: jagentic-core 95, main module 770,
ports 6, agentic-pekko 14, tool-services 26, a2a-gateway 9 — all green.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant