Skip to content

Migrate to Gradle 9.5.1 and Java 25 - #81

Open
Thevakumar-Luheerathan wants to merge 7 commits into
mainfrom
java-25-migration
Open

Migrate to Gradle 9.5.1 and Java 25#81
Thevakumar-Luheerathan wants to merge 7 commits into
mainfrom
java-25-migration

Conversation

@Thevakumar-Luheerathan

@Thevakumar-Luheerathan Thevakumar-Luheerathan commented May 27, 2026

Copy link
Copy Markdown
Member

Summary

  • Gradle 9.5.1: Upgrade wrapper; replace removed buildDir API with layout.buildDirectory; replace Project.exec() with ExecOperations injection; migrate from com.gradle.enterprise to com.gradle.develocity; upgrade net.researchgate.release to 3.1.0
  • Java 25: Add Java 25 toolchain to all subprojects; upgrade Ballerina Gradle plugin to 4.0.0 and ballerinaLangVersion to 2201.14.0-20260527-050400-74f7e6bf; update all [platform.java21] TOML sections to [platform.java25]; add patchBallerinaScripts task to remove the --sun-misc-unsafe-memory-access=allow JVM flag (removed in Java 25) from the extracted bal binary after unpack; wire test.dependsOn patchBallerinaScripts to ensure patching during split CI builds
  • SpotBugs 6.5.1: Upgrade for Java 25 class file support (requires SpotBugs 4.9.x / ASM 9.7+); add exclusions for THROWS, AT, and USELESS_STRING detectors introduced in SpotBugs 4.9.x
  • JaCoCo 0.8.13: Upgrade for Java 25 class file instrumentation support
  • CI workflow: Update to pull-request-build-template.yml@java-25-migration for JDK 25 runner support

Test plan

  • ./gradlew build passes green locally (full build including tests)
  • .bala artifact is created as ballerina-edi-any-1.5.4.bala
  • All 16 tests pass
  • CI passes on both Ubuntu and Windows
  • Migrated the build to Gradle 9.5.1 and Java 25, including wrapper updates, Java 25 toolchains, and Gradle API replacements for newer conventions.
  • Upgraded Ballerina-related tooling and artifacts, including the Gradle plugin, language version, package distribution metadata, and TOML platform targets.
  • Replaced the Gradle Enterprise plugin with Develocity and updated the CI workflow to use the Java 25 migration template.
  • Added build-time patching for bundled Ballerina scripts so split CI builds can run reliably on Java 25.
  • Updated quality tooling by bumping SpotBugs and JaCoCo, adding related exclusions/configuration, and aligning version properties across the build.
  • Refactored the Ballerina commit task to use injected Gradle exec operations and cleaned up build configuration paths and task wiring.

…27-050400-74f7e6bf

- Upgrade Gradle wrapper to 9.5.1
- Replace com.gradle.enterprise with com.gradle.develocity plugin
- Upgrade net.researchgate.release to 3.1.0 for Gradle 9 compatibility
- Replace all deprecated buildDir references with layout.buildDirectory
- Replace Project.exec() calls with ExecOperations injection pattern
- Remove deprecated sourceCompatibility/targetCompatibility (replaced by toolchain)
- Add Java 25 toolchain to all Java subprojects
- Upgrade Ballerina Gradle plugin to 4.0.0 (Java 25 + Gradle 9.5.1 compatible)
- Update ballerinaLangVersion to 2201.14.0-20260527-050400-74f7e6bf
- Update all platform.java21 TOML sections to platform.java25
- Add patchBallerinaScripts task to fix bal binary permissions and remove
  --sun-misc-unsafe-memory-access=allow flag (removed in Java 25)
- Upgrade SpotBugs Gradle plugin to 6.5.1 for Java 25 class file support
- Add SpotBugs exclusions for THROWS/AT/USELESS_STRING detectors introduced
  in SpotBugs 4.9.x (bundled in plugin >= 6.2.0)
- Update CI workflow to use pull-request-build-template.yml@java-25-migration
Copilot AI review requested due to automatic review settings May 27, 2026 11:43
@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Thevakumar-Luheerathan, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 59 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3c32817b-104b-4ace-80ee-57d5c244db31

📥 Commits

Reviewing files that changed from the base of the PR and between 65b8d4b and dcf917e.

📒 Files selected for processing (2)
  • ballerina/Ballerina.toml
  • build-config/resources/Ballerina.toml
📝 Walkthrough

Walkthrough

Updates the build toolchain to Java 25, bumps Ballerina distribution and Gradle plugin versions, upgrades the Gradle wrapper, adds a script-patching Gradle task, migrates Checkstyle output paths and the build-scan DSL to Develocity, and adds SpotBugs exclusions.

Changes

Java 25 and Gradle build infrastructure migration

Layer / File(s) Summary
Version bumps
.github/workflows/pull-request.yml, ballerina/Ballerina.toml, ballerina/Dependencies.toml, build-config/resources/Ballerina.toml, gradle.properties, gradle/wrapper/gradle-wrapper.properties
Updates Ballerina distribution version, bumps spotbugs/release/ballerina-gradle plugin versions, adds jacocoVersion, upgrades Gradle wrapper to 9.5.1, and repoints CI workflow to the java-25-migration branch.
Root build.gradle toolchain and task updates
build.gradle
Adds allprojects JaCoCo toolVersion config, conditionally sets Java toolchain to version 25 when the java plugin is applied, and migrates the build task to tasks.named('build').
Ballerina script patching and exec helper
ballerina/build.gradle
Adds BallerinaExecHelper and PatchBallerinaScriptsTask to fix script permissions, strip an unsafe-memory-access flag, and inject JAVA_HOME; wires the new patchBallerinaScripts task into build/test, adds mavenLocal(), and refactors commitTomlFiles to use injected ExecOperations.
Checkstyle output path migration
build-config/checkstyle/build.gradle
Migrates checkstyle rule download and artifact paths from legacy buildDir to the layout.buildDirectory API.
Develocity plugin migration and SpotBugs exclusions
settings.gradle, spotbugs-exclude.xml
Replaces com.gradle.enterprise with com.gradle.develocity, adds gradlePluginPortal(), renames build-scan terms-of-use properties, and adds SpotBugs BugCode exclusions for THROWS, AT, and USELESS_STRING.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Poem

A rabbit hops through Gradle's den,
Java 25 arrives again,
Scripts get patched, JAVA_HOME set right,
Develocity glows with new-found light,
Versions bumped, wrappers spun—
Hop hop hooray, the build is done! 🐇⚙️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description omits the required Purpose, Examples, and Checklist sections from the repository template. Add the missing template sections and fill the checklist items for issue link, changelog, tests, spec, and native-image compatibility.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: migrating the build to Gradle 9.5.1 and Java 25.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch java-25-migration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates the build and CI infrastructure for module-ballerina-edi to support Gradle 9.5.1 and Java 25, including required Gradle API migrations and dependency/plugin upgrades (Ballerina, SpotBugs, JaCoCo, Develocity).

Changes:

  • Upgrade Gradle wrapper to 9.5.1 and migrate build scripts away from removed Gradle APIs (e.g., buildDir, Project.exec()).
  • Migrate tooling and metadata to Java 25 (toolchains + TOML [platform.java25]/distribution updates) and add a task to patch extracted Ballerina launch scripts for Java 25.
  • Upgrade build plugins/tools (Develocity, Release plugin, SpotBugs exclusions, JaCoCo) and update CI workflow reference for Java 25 runners.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
spotbugs-exclude.xml Adds new SpotBugs bug-code exclusions for findings introduced by newer SpotBugs/ASM versions.
settings.gradle Adds pluginManagement repositories and migrates from Gradle Enterprise to Develocity configuration.
gradle/wrapper/gradle-wrapper.properties Upgrades Gradle wrapper distribution to 9.5.1.
gradle.properties Bumps SpotBugs, release plugin, Ballerina Gradle plugin, and Ballerina language version.
build.gradle Configures Java 25 toolchains for Java subprojects and updates build task wiring for Gradle 9.
build-config/resources/Ballerina.toml Updates Ballerina distribution version to the new lang version.
build-config/checkstyle/build.gradle Migrates away from removed buildDir usage to layout.buildDirectory.
ballerina/Dependencies.toml Updates distribution version and package version metadata.
ballerina/build.gradle Migrates exec usage, adds Java 25 patching task for Ballerina scripts, and updates repositories.
ballerina/Ballerina.toml Updates package version and distribution version metadata.
.github/workflows/pull-request.yml Updates called reusable workflow ref for Java 25 runner support.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ballerina/build.gradle Outdated
lines = lines.findAll { !it.contains('--sun-misc-unsafe-memory-access=allow') }
// Inject JAVA_HOME so the bal script picks up Java 25
def shebangIdx = lines.findIndexOf { it.startsWith('#!') }
if (shebangIdx >= 0) {
Comment thread ballerina/build.gradle

buildscript {
repositories {
mavenLocal()
Comment thread settings.gradle Outdated

pluginManagement {
repositories {
mavenLocal()
Comment thread spotbugs-exclude.xml
Comment on lines +20 to +29
<!-- Pre-existing issues surfaced by SpotBugs 4.9.x (bundled in plugin >= 6.2.0) -->
<Match>
<BugCode name="THROWS"/>
</Match>
<Match>
<BugCode name="AT"/>
</Match>
<Match>
<BugCode name="USELESS_STRING"/>
</Match>
name: Run PR Build Workflow
if: ${{ github.repository_owner == 'ballerina-platform' }}
uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@main
uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java-25-migration
Thevakumar-Luheerathan and others added 2 commits June 26, 2026 13:48
Applied fixes: A4, B3, B5+C1
- Make patchBallerinaScripts idempotent and add task @input properties (A1, B1)
- Use token-level JVM flag removal instead of line filter (B4)
- Remove mavenLocal() from plugin repositories (A4)
- Scope SpotBugs suppressions to module packages (A5)
- Add Gradle wrapper integrity checksum (B3)
- Wire jacocoVersion property to JaCoCo toolVersion (B5)
- Bump JaCoCo to 0.8.14 for stable Java 25 support (C1)
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.68%. Comparing base (e243822) to head (dcf917e).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #81      +/-   ##
==========================================
+ Coverage   80.67%   80.68%   +0.01%     
==========================================
  Files          13       13              
  Lines        1573     1574       +1     
  Branches      550      550              
==========================================
+ Hits         1269     1270       +1     
  Misses        304      304              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
spotbugs-exclude.xml (1)

20-30: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

SpotBugs exclusions are valid but broad.

The three <Match> entries with <BugCode> are syntactically correct FindBugsFilter XML. Excluding entire bug categories (THROWS, AT, USELESS_STRING) is pragmatic for the migration but risks masking legitimate findings long-term. Consider scoping these to specific classes/packages once the migration stabilizes, if not already planned per the commit messages.

The three separate <Match> blocks could also be consolidated into a single <Match> with <Or> for conciseness:

♻️ Optional consolidation
     <!-- Pre-existing issues surfaced by SpotBugs 4.9.x (bundled in plugin >= 6.2.0) -->
-    <Match>
-        <BugCode name="THROWS"/>
-    </Match>
-    <Match>
-        <BugCode name="AT"/>
-    </Match>
-    <Match>
-        <BugCode name="USELESS_STRING"/>
-    </Match>
+    <Match>
+        <Or>
+            <BugCode name="THROWS"/>
+            <BugCode name="AT"/>
+            <BugCode name="USELESS_STRING"/>
+        </Or>
+    </Match>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@spotbugs-exclude.xml` around lines 20 - 30, The SpotBugs exclusion rules in
spotbugs-exclude.xml are valid but overly broad; review the existing `<Match>`
entries for `THROWS`, `AT`, and `USELESS_STRING` and narrow them to specific
classes or packages once the migration is stable. If you want to clean up the
XML, consolidate the three separate `<Match>` blocks into a single `Match` using
`Or`, while keeping the same exclusion behavior.
ballerina/build.gradle (1)

46-46: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Scope trim() to lines where the flag was actually replaced.

trim() is applied to every line in the script, not just lines containing --sun-misc-unsafe-memory-access=allow. This strips leading indentation from all lines and, combined with findAll { !it.isEmpty() }, removes all empty lines — causing unnecessary modifications to unrelated lines. Only trim lines where the replacement actually changed the content.

♻️ Proposed refactor
-                    lines = lines.collect { it.replace('--sun-misc-unsafe-memory-access=allow', '').trim() }.findAll { !it.isEmpty() }
+                    lines = lines.collect { line ->
+                        def replaced = line.replace('--sun-misc-unsafe-memory-access=allow', '')
+                        replaced != line ? replaced.trim() : line
+                    }.findAll { !it.isEmpty() }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ballerina/build.gradle` at line 46, The line-processing in the build script
is over-applying trim() and findAll(), which alters unrelated lines and drops
empty lines. Update the logic around the lines.collect transformation so that
only entries where the --sun-misc-unsafe-memory-access=allow flag was actually
removed are trimmed, and leave all other lines unchanged; use the same
line-processing block in ballerina/build.gradle to localize the fix.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ballerina/build.gradle`:
- Around line 41-42: The bin directory iteration in the build script can hit
subdirectories and later fail when reading file contents, so add an isDirectory
guard inside the binDir.eachFile block before any file.text or executable
handling. Update the logic around the file iteration in the build.gradle script
so only regular files are processed, leaving directories untouched and
preventing IOException during the rewrite step.

In `@settings.gradle`:
- Around line 11-13: The Develocity plugin is still pinned to the old version in
the plugin management setup, so update the `com.gradle.develocity` version in
`settings.gradle` from `3.19.2` to `4.5.0` while keeping the existing migration
and repository configuration intact. Use the plugin declaration in the
`settings.gradle` plugin resolution block to make sure the build applies the
current stable release.

---

Nitpick comments:
In `@ballerina/build.gradle`:
- Line 46: The line-processing in the build script is over-applying trim() and
findAll(), which alters unrelated lines and drops empty lines. Update the logic
around the lines.collect transformation so that only entries where the
--sun-misc-unsafe-memory-access=allow flag was actually removed are trimmed, and
leave all other lines unchanged; use the same line-processing block in
ballerina/build.gradle to localize the fix.

In `@spotbugs-exclude.xml`:
- Around line 20-30: The SpotBugs exclusion rules in spotbugs-exclude.xml are
valid but overly broad; review the existing `<Match>` entries for `THROWS`,
`AT`, and `USELESS_STRING` and narrow them to specific classes or packages once
the migration is stable. If you want to clean up the XML, consolidate the three
separate `<Match>` blocks into a single `Match` using `Or`, while keeping the
same exclusion behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 987ac279-32fd-4dc6-bd54-0bdfed5c4afc

📥 Commits

Reviewing files that changed from the base of the PR and between e243822 and 65b8d4b.

⛔ Files ignored due to path filters (1)
  • .DS_Store is excluded by !**/.DS_Store
📒 Files selected for processing (11)
  • .github/workflows/pull-request.yml
  • ballerina/Ballerina.toml
  • ballerina/Dependencies.toml
  • ballerina/build.gradle
  • build-config/checkstyle/build.gradle
  • build-config/resources/Ballerina.toml
  • build.gradle
  • gradle.properties
  • gradle/wrapper/gradle-wrapper.properties
  • settings.gradle
  • spotbugs-exclude.xml

Comment thread ballerina/build.gradle
Comment on lines +41 to +42
binDir.eachFile { file ->
file.setExecutable(true)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Add isDirectory guard to prevent IOException on subdirectories.

binDir.eachFile iterates over both files and directories. If a subdirectory exists in bin/, file.text at line 44 will throw an IOException.

🛡️ Proposed fix
         binDir.eachFile { file ->
+            if (file.isDirectory()) return
             file.setExecutable(true)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
binDir.eachFile { file ->
file.setExecutable(true)
binDir.eachFile { file ->
if (file.isDirectory()) return
file.setExecutable(true)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ballerina/build.gradle` around lines 41 - 42, The bin directory iteration in
the build script can hit subdirectories and later fail when reading file
contents, so add an isDirectory guard inside the binDir.eachFile block before
any file.text or executable handling. Update the logic around the file iteration
in the build.gradle script so only regular files are processed, leaving
directories untouched and preventing IOException during the rewrite step.

Comment thread settings.gradle
Comment on lines +11 to +13
repositories {
gradlePluginPortal()
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

What is the latest version of the Gradle Develocity plugin (com.gradle.develocity)?

💡 Result:

The latest version of the Develocity Gradle plugin (com.gradle.develocity) is 4.5.0, released on June 30, 2026 [1][2][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate Develocity plugin references and the settings file context.
git ls-files | rg '(^|/)(settings\.gradle|settings\.gradle\.kts|build\.gradle(\.kts)?)$|develocity|gradle\.enterprise'

printf '\n--- settings.gradle ---\n'
if [ -f settings.gradle ]; then
  cat -n settings.gradle | sed -n '1,120p'
fi

printf '\n--- search for com.gradle.develocity / com.gradle.enterprise / 3.19.2 ---\n'
rg -n 'com\.gradle\.(develocity|enterprise)|3\.19\.2|develocity\s*\{' -S .

Repository: ballerina-platform/module-ballerina-edi

Length of output: 1943


Update the Develocity plugin version settings.gradle:23 — the migration is correct, but com.gradle.develocity is still pinned to 3.19.2; bump it to the current stable 4.5.0.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@settings.gradle` around lines 11 - 13, The Develocity plugin is still pinned
to the old version in the plugin management setup, so update the
`com.gradle.develocity` version in `settings.gradle` from `3.19.2` to `4.5.0`
while keeping the existing migration and repository configuration intact. Use
the plugin declaration in the `settings.gradle` plugin resolution block to make
sure the build applies the current stable release.

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.

2 participants