Skip to content

feat(build): support JDK 21 - #139

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

feat(build): support JDK 21#139
halibobo1205 wants to merge 6 commits into
developfrom
java/JDK21

Conversation

@halibobo1205

@halibobo1205 halibobo1205 commented Jul 30, 2026

Copy link
Copy Markdown
Owner

User description

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 Description

Support newer JDKs while keeping builds and runtime behavior compatible across architectures

What Changed

  • x86_64 builds now accept JDK 8 or newer, while ARM64 builds accept JDK 17 or newer; generated output remains compatible with Java 8.
  • FullNode no longer exits because the runtime JDK is newer than an exact required version.
  • The dependency installer preserves any supported JDK, checks the same Java installation used by Gradle, requires javac, and reports failure when the environment cannot build.
  • Power calculations now use consistent results across CPU architectures and supported JDK versions.
  • Pull-request builds now cover JDK 21 on both x86_64 and ARM64, including an x86_64 RocksDB test.
  • Gradle is upgraded to 8.14.5, with protobuf generation handled automatically in the build and generated files kept out of source directories.

Impact

✅ JDK 21 builds on x86_64 and ARM64
✅ Fewer setup failures from incompatible or incomplete Java installations
✅ Consistent power results across architectures

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@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 3b03d7d Aug 07, 2026 · 09:50 09:50
✅ Incremental review completed 1c05cca Aug 06, 2026 · 04:13 04:14
✅ 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
@halibobo1205
halibobo1205 force-pushed the java/JDK21 branch 2 times, most recently from 8c4d2e5 to 969b215 Compare August 4, 2026 06:59
@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
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.
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.
@codeant-ai

codeant-ai Bot commented Aug 6, 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 6, 2026

@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: 1c05cca949

ℹ️ 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 build.gradle
Error Prone 2.42.0 ships Java 17 class files, so enabling it on JDK 11 through 16 fails while loading the compiler plugin. Skip the custom checker below JDK 17 and keep it enabled for supported newer JDKs.
@codeant-ai

codeant-ai Bot commented Aug 7, 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 7, 2026
@halibobo1205 halibobo1205 changed the title feat(build): upgrade to Gradle 8.14.5 and support JDK 21 builds feat(build): support JDK 25 Aug 12, 2026
@halibobo1205 halibobo1205 changed the title feat(build): support JDK 25 feat(build): support JDK 21 Aug 13, 2026
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