Skip to content

feat(build): upgrade to Gradle 8.14.5 and support JDK 21 builds - #139

Open
halibobo1205 wants to merge 5 commits into
developfrom
java/JDK21
Open

feat(build): upgrade to Gradle 8.14.5 and support JDK 21 builds#139
halibobo1205 wants to merge 5 commits into
developfrom
java/JDK21

Conversation

@halibobo1205

@halibobo1205 halibobo1205 commented Jul 30, 2026

Copy link
Copy Markdown
Owner

What does this PR do?

Modernizes the build toolchain and widens the supported JDK envelope, in 5 commits:

  1. build(gradle): Gradle 7.6.4 → 8.14.5. Migrates removed Gradle 7 APIs (report enabledrequired, mainClassNameapplication.mainClass, fileModefilePermissions, archive properties), bumps protobuf-gradle-plugin 0.9.1 → 0.9.6, and relocates protobuf codegen out of protocol/src/ into build/generated. Legacy generated sources left in protocol/src/main/java by older builds are excluded from compilation and purged automatically, so existing checkouts upgrade without duplicate-class failures. Declares jacocoTestReport's dependency on classes so Gradle 8 task validation holds for build -x test.
  2. feat(build): per-arch JDK minimums. The build now accepts JDK 8+ on x86_64 and JDK 17+ on ARM64 (previously exact 8/17), while --release 8 keeps all bytecode Java 8 (major 52). The runtime exact-JDK gate in FullNode is removed (see rationale below). Test mocking works on JDK 21 by excluding Mockito's Byte Buddy 1.12.19 and declaring 1.17.7 directly. install_dependencies.sh now keeps any JDK meeting the architecture minimum instead of requiring an exact version, and validates the same JVM gradlew would use — JAVA_HOME first, then PATH — requiring javac in that same installation so a JRE is never mistaken for a JDK, and exiting non-zero when the resulting environment cannot build.
  3. build(deps): JDK-compatible tooling. lombok 1.18.46, AspectJ 1.9.25 (aspectjtools dropped — unused), JaCoCo 0.8.15, test-retry 1.6.5.
  4. fix(math): unify pow behavior across architectures. Removes the x86-only MathWrapper (raw Math.pow) and promotes the StrictMath + mainnet-patch-table implementation (already used by all ARM64 nodes to sync from genesis) as the single cross-arch implementation. All 48 historical pow special cases are preserved byte-for-byte.
  5. ci: every supported architecture × JDK combination is now built. x86_64 on JDK 8 (Debian 11), 17 (Rocky Linux 8) and 21 (Ubuntu 24.04); ARM64 on JDK 17 and 21 (Ubuntu 24.04) plus JDK 21 on macOS 26. The Rocky Linux job additionally pins JDK 17 explicitly and asserts the active version — dnf groupinstall "Development Tools" pulls in java-1.8.0-openjdk-headless, whose RHEL alternatives priority (1800502 vs 1) hijacks java and would leave the build on a JRE without javac.

Why are these changes required?

The exact-JDK runtime pin existed solely because x86 consensus pow depended on JDK 8's Math.pow intrinsics. Unifying MathWrapper on StrictMath (bit-reproducible by spec across JDKs and architectures) removes that dependency, which is what makes the minimum-based JDK envelope sound. Gradle 7.6.4 cannot run modern JDKs; 8.14.5 supports building on JDK 8–24.

Consensus note: on mainnet/nile/shasta ALLOW_STRICT_MATH (chain parameter 87, activated by mainnet proposal 101) is active, so new blocks use StrictMathWrapper and this change only affects historical replay, which the 48-entry table reproduces exactly — behaviour already validated by every ARM64 node syncing mainnet from genesis. Private chains that have not activated the parameter still execute MathWrapper.pow on the live path and should upgrade all x86 nodes in lockstep (or activate the proposal first).

This PR has been tested by:

  • Unit Tests: full suite green on JDK 17 (CI), plus full local runs on JDK 21 and JDK 25 — 3245 tests, 0 failures. A few tests fail on first attempt under full parallel load and pass on retry (AllowTvmLondonTest, ValidateMultiSignContractTest on JDK 21; a disjoint set on JDK 25); each passes cleanly when run on its own on both JDK 17 and JDK 21, so they are load-sensitive rather than JDK-specific.
  • Manual Testing:
    • Migration path: a develop-built dirty checkout (real stale codegen in protocol/src/) rebuilt on this branch without clean — no duplicate classes
    • Sequential no-clean builds with JDK 8(x86_64) → 17 → 21 → 25, including two x86↔arm64 dependency-profile flips — no cross-contamination, bytecode stays major 52
    • Per-commit builds in isolated worktrees (bisect-clean, including build -x test)
    • Runtime: the release-8 FullNode.jar boots and produces blocks on a JDK 25 private chain; packaged JDK17+ vmoptions validated on 17/21/25
    • Installer: JAVA_HOME pointing at a JRE, a JDK below the architecture minimum, a JDK 8 jre subdirectory, or an invalid path are all rejected; PATH-only JDK 8/17 and JAVA_HOME-set JDK 17 are accepted; a machine with no java is detected as such
    • Supply chain: gradle-wrapper.jar byte-identical to the official 8.14.5 release; every changed verification-metadata.xml checksum re-derived from Maven Central / Gradle Plugin Portal

Follow up

  • netty still uses sun.misc.Unsafe (warn-only on JDK 24/25; JDK 26 plans deny-by-default per JEP 498) — revisit with a netty upgrade
  • Gradle-9-removed idioms (buildFinished, configurations.archives, eager task APIs) remain and will need attention at the next Gradle major
  • Gradle officially supports running on ≤ Java 24; Java 25 requires Gradle 9.1+ (works unofficially today)

Extra details

  • Dist packaging is byte-equivalent to develop (jar names, zip layout, 0755 script permissions). bin/ vmoptions are selected when the distribution is built (build JDK < 17 → CMS file, ≥ 17 → ZGC file) rather than detected at node startup, so a distribution targets its build JDK's runtime family; java -jar is runtime-agnostic (verified 8→25).
  • CI job display names changed (Build rockylinux (JDK 17 / x86_64), Build macos26 (JDK 21 / aarch64)) and one job is added (Build ubuntu24 (JDK 21 / x86_64|aarch64)) — branch-protection required checks need a one-time update. The added job runs in parallel, so wall-clock CI time is unchanged.
  • 29 files change under the wholesale-migration exception to the 10-file guideline (build scripts, wrapper, verification metadata, docs, CI). Only 5 production Java files are touched: the two MathWrapper variants (one renamed, one deleted), plus dead-code removal in FullNode, Arch and TronError.
  • The minimum-version policy is not a certification of every intermediate release, vendor build or future JDK; verification in this PR extends to JDK 21 (with JDK 25 exercised locally).

@codeant-ai

codeant-ai Bot commented Jul 30, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed 969b215 Aug 04, 2026 · 06:59 07:00
✅ Reviewed your PR 0b97f99 Jul 30, 2026 · 02:13 02:17

@codeant-ai

codeant-ai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added the size:XL This PR changes 500-999 lines, ignoring generated files label Jul 30, 2026
Comment thread install_dependencies.sh Outdated
Comment thread install_dependencies.sh
Comment thread gradlew

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0b97f995fa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread gradle/wrapper/gradle-wrapper.properties
Migrate deprecated Gradle APIs while retaining JDK 8 compatibility.
Bump protobuf-gradle-plugin 0.9.1 -> 0.9.6 for Gradle 8 support.
Move protobuf generation from src/ to build/generated and exclude legacy
generated sources so incremental builds cannot compile duplicate
classes. Update the custom actuator guides for the relocated codegen
path and lifecycle.
Declare jacocoTestReport dependency on classes so Gradle 8 task
validation holds when test is excluded from the graph.
Refresh dependency verification metadata for the upgraded build tooling.
Accept JDK 8 or newer on x86_64 and JDK 17 or newer on ARM64 while
continuing to emit Java 8 bytecode. Select VM options from the build JVM
and remove runtime gates that previously required exact JDK versions.
Rework install_dependencies.sh to keep any JDK meeting the architecture
minimum, and drop the now-dead gate code and its tests.
Make JDK 21 static mocking work by excluding Mockito transitive Byte
Buddy 1.12.19 and declaring 1.17.7 directly while retaining JDK 8
runtime compatibility. Remove the obsolete 1.12.19 verification entries.
Upgrade JaCoCo, Lombok, AspectJ runtime/weaver, and the Gradle
test-retry plugin. Remove the unused JDK 17-only AspectJ compiler tools
and refresh strict dependency verification metadata, including the
required plugin POM checksum.
Move the legacy-compatible MathWrapper into the platform common source set and remove the x86 Math implementation. This keeps transcendental results deterministic across JDKs and architectures.
@codeant-ai

codeant-ai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels Aug 4, 2026
Exercise every supported architecture and JDK combination in pull
requests: x86_64 on JDK 8, 17 and 21, and ARM64 on JDK 17 and 21,
covering Linux for both plus macOS on JDK 21. This guards the
architecture minimums as well as newer-JDK compatibility.

Pin JDK 17 explicitly on Rocky Linux and assert the active version:
"Development Tools" pulls in java-1.8.0-openjdk-headless, whose
alternatives priority outranks the JDK 17 package and would otherwise
leave the build on a JRE without javac.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant