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

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.
  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.
  5. ci: matrix now covers x86_64×{8,17} and aarch64×{17,21} without adding jobs (rockylinux 8→17, macos 17→21).

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 (param 87) is active, so new blocks use StrictMathWrapper and this change only affects historical replay, which the patch table reproduces exactly (validated by every ARM64 node syncing from genesis). Private chains that have not activated param 87 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 (3207 tests, 0 failures; retried flakes are load-related and disjoint between runs)
  • 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
    • 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 by the build JDK (<17 → CMS file, ≥17 → ZGC file), so a dist 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)) — branch-protection required checks need a one-time update.
  • File count exceeds the 10-file guideline under the wholesale-migration exception (build scripts + wrapper + metadata; only 3 production Java files change, two of which are deletions).

CodeAnt-AI Description

Expand JDK compatibility and standardize cross-platform runtime behavior

What Changed

  • x86_64 builds now support JDK 8 and newer, while ARM64 builds support JDK 17 and newer; generated output remains compatible with Java 8.
  • FullNode no longer rejects supported newer JDK versions at startup, and the dependency installer keeps any JDK that meets the architecture minimum.
  • Mathematical power calculations now produce consistent results across architectures and JDKs, including known mainnet values.
  • Gradle is upgraded to 8.14.5, with protobuf generation handled automatically in the build output and updated instructions for regenerating sources.
  • Build verification now covers x86_64 on JDK 8 and 17 and ARM64 on JDK 17 and 21.

Impact

✅ JDK 21 support on ARM64
✅ Fewer startup failures with supported JDK versions
✅ Consistent calculations 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.

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 Jul 30, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ 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
Comment on lines +105 to +107
if ! command -v java &> /dev/null; then
return 2
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The installer validates only the java executable and treats any matching major version as a complete JDK. A JRE-only installation, or a PATH where java and javac come from different installations, therefore sets SKIP_JAVA_INSTALL and can leave the user unable to compile the project. Verify that javac exists and belongs to the selected Java installation before skipping JDK installation. [api mismatch]

Severity Level: Major ⚠️
- ❌ Installer can report a usable JDK without a compiler.
- ❌ Gradle Java compilation fails after successful setup.
- ⚠️ Existing JAVA_HOME and PATH may select different Java installations.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** install_dependencies.sh
**Line:** 105:107
**Comment:**
	*Api Mismatch: The installer validates only the `java` executable and treats any matching major version as a complete JDK. A JRE-only installation, or a PATH where `java` and `javac` come from different installations, therefore sets `SKIP_JAVA_INSTALL` and can leave the user unable to compile the project. Verify that `javac` exists and belongs to the selected Java installation before skipping JDK installation.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment thread install_dependencies.sh
Comment on lines +185 to +186
recommended_jdk="JDK 8"
minimum_java_major=8

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The new minimum-version check accepts JDK 8 on x86_64 and consequently skips installation, but the updated Gradle 8.14.5 distribution requires Java 17 or newer to run. A machine with only the recommended JDK 8 will therefore pass this installer and then fail when invoking gradlew; use a Java 17+ runtime for Gradle while configuring Java 8 only as a compilation toolchain if required. [api mismatch]

Severity Level: Critical 🚨
- ❌ Fresh x86_64 installations cannot run `./gradlew`.
- ❌ Build, test, and CI-like commands fail before compilation.
- ⚠️ Installer success message contradicts Gradle runtime requirements.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** install_dependencies.sh
**Line:** 185:186
**Comment:**
	*Api Mismatch: The new minimum-version check accepts JDK 8 on x86_64 and consequently skips installation, but the updated Gradle 8.14.5 distribution requires Java 17 or newer to run. A machine with only the recommended JDK 8 will therefore pass this installer and then fail when invoking `gradlew`; use a Java 17+ runtime for Gradle while configuring Java 8 only as a compilation toolchain if required.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment thread gradlew
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The wrapper is launched with -jar, but Gradle wrapper JARs are intended to be launched by putting the JAR on the classpath and invoking org.gradle.wrapper.GradleWrapperMain; they do not provide the executable-JAR entry point required by -jar. POSIX builds will therefore fail before Gradle starts with a missing-main-manifest error. Use the wrapper main class invocation, and apply the same correction to gradlew.bat. [api mismatch]

Severity Level: Critical 🚨
- ❌ All POSIX Gradle wrapper commands fail before Gradle starts.
- ❌ Windows wrapper commands fail through `gradlew.bat`.
- ⚠️ Builds and CI cannot resolve or execute Gradle.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** gradlew
**Line:** 216:216
**Comment:**
	*Api Mismatch: The wrapper is launched with `-jar`, but Gradle wrapper JARs are intended to be launched by putting the JAR on the classpath and invoking `org.gradle.wrapper.GradleWrapperMain`; they do not provide the executable-JAR entry point required by `-jar`. POSIX builds will therefore fail before Gradle starts with a missing-main-manifest error. Use the wrapper main class invocation, and apply the same correction to `gradlew.bat`.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@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".

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Use JDK 17+ to launch the Gradle 8 wrapper

Gradle 8.14.5 requires Java 17 or newer to run, so every workflow that invokes this wrapper under JDK 8 exits before the build script is evaluated. This breaks the docker-build-debian11 job in .github/workflows/pr-build.yml, both single- and multi-node integration workflows, and CodeQL; the dependency installer also continues to select JDK 8 on x86_64. Run Gradle with JDK 17+ and use JDK 8 only for artifact runtime verification/toolchains, or retain a Gradle version that can launch on JDK 8.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Gradle 8.14.5 can run in JDK 8; you can see the CI is successful

Exercise ARM64 builds on JDK 17 and JDK 21 and x86_64 builds on JDK 8
and JDK 17. This guards both architecture minimums and newer-JDK
compatibility in pull requests.
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