Skip to content

Migrate to Gradle 9.5.1 and Java 25#2630

Open
Thevakumar-Luheerathan wants to merge 16 commits into
masterfrom
java-25-migration
Open

Migrate to Gradle 9.5.1 and Java 25#2630
Thevakumar-Luheerathan wants to merge 16 commits into
masterfrom
java-25-migration

Conversation

@Thevakumar-Luheerathan

@Thevakumar-Luheerathan Thevakumar-Luheerathan commented May 24, 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 plugin; 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-SNAPSHOT; 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
  • SpotBugs 6.5.1: Upgrade from 6.0.x to 6.5.1 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 — these are pre-existing code patterns now surfaced by the updated analysis engine

Test plan

  • ./gradlew clean build -x test passes green across all subprojects
  • .bala artifact is created as ballerina-http-java25-2.17.0.bala
  • SpotBugs passes on http-native and http-compiler-plugin-tests
  • Run full test suite (./gradlew build) in CI

This PR migrates the build and runtime toolchain to Gradle 9.5.1 and Java 25, updates related plugins and CI references, modernizes Gradle usage, and applies packaging and static-analysis adjustments to ensure compatibility with the new toolchain.

  • Build system and tooling

    • Upgrade Gradle wrapper to 9.5.1 and replace legacy buildDir usage with layout.buildDirectory across build scripts (SpotBugs, JaCoCo, artifact registrations, etc.).
    • Replace the Gradle Enterprise plugin with the Develocity plugin and adapt build-scan configuration keys.
    • Update CI workflow templates to reference the java-25-migration branch and add workflow concurrency to cancel duplicate PR runs.
  • Java and Ballerina platform migration

    • Configure Java 25 toolchain for Java projects (languageVersion = 25).
    • Update Ballerina packaging/configuration to target platform.java25 (replacing platform.java21) and bump the distribution to 2201.14.0-SNAPSHOT.
  • API modernization and task wiring

    • Replace direct project.exec() usage with injected ExecOperations via new helper abstractions (BallerinaExecHelper, IntegrationTestsExecHelper, BallerinaTestsExecHelper).
    • Convert task declarations to use tasks.named(...) where appropriate and adjust task dependency wiring.
  • Packaging changes

    • Add PatchBallerinaScriptsTask to post-process unpacked Ballerina tool scripts: remove an obsolete JVM flag for Java 25, inject a JAVA_HOME override into jballerina tool binaries, and fix executable permissions; integrate the task into the unpack/build graph.
  • Dependency and plugin updates

    • Ballerina Gradle plugin → 4.0.0 and ballerinaLangVersion → 2201.14.0-SNAPSHOT.
    • SpotBugs Gradle plugin → 6.5.1 (with SpotBugs 4.9.x/ASM compatibility).
    • net.researchgate.release → 3.1.0; bump JaCoCo and other build-version properties.
  • Static analysis adjustments

    • Extend SpotBugs exclusion filters (additions for THROWS, AT, USELESS_STRING) to suppress pre-existing findings surfaced by the upgraded SpotBugs engine.

Test plan

  • ./gradlew clean build -x test should succeed across subprojects.
  • Produce .bala artifact named ballerina-http-java25-2.17.0.bala.
  • SpotBugs should pass for http-native and compiler-plugin tests.
  • Run full test suite (./gradlew build) in CI.

Impact: modernizes build and runtime targets for improved compatibility and maintainability, updates plugins and dependencies for Java 25 and Gradle 9.5.1, refactors task execution to use modern Gradle APIs, and adds packaging and analysis adjustments to keep builds and tooling working under the new toolchain.

- 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
- 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-SNAPSHOT
- 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)
@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Switch platform targets and distribution to Java 25 across Ballerina toml and dependency files, bump build/tool versions, modernize Gradle APIs (layout.buildDirectory, toolchains), replace direct exec calls with injected ExecOperations helpers, add PatchBallerinaScriptsTask, update CI workflow references, and adjust TLS ciphers and related tests.

Changes

Java 25 Platform Migration and Gradle Modernization

Layer / File(s) Summary
Toolchain and version configuration
gradle.properties, gradle/wrapper/gradle-wrapper.properties, build.gradle
Updated distribution and tooling versions, Gradle wrapper to 9.5.1, and configured Java toolchain languageVersion = 25 for subprojects using java.
Main platform and resource templates
ballerina/Ballerina.toml, build-config/resources/Ballerina.toml, build-config/resources/BallerinaTest.toml
Bumped distribution version and replaced [platform.java21] with [platform.java25] (keeping graalvmCompatible = true) and moved platform-specific dependency stanzas accordingly.
HTTP test modules platform migration
ballerina-tests/*/Ballerina.toml
All HTTP test modules migrated their platform blocks from java21 to java25, preserving graalvmCompatible and dependency entries.
Dependency lock updates
*/Dependencies.toml, ballerina/Dependencies.toml
Updated distribution-version and bumped several package versions in auto-generated dependency lock files to align with the new distribution.
Gradle layout.buildDirectory modernization
build-config/checkstyle/build.gradle, compiler-plugin-tests/build.gradle, compiler-plugin/build.gradle, native/build.gradle
Replaced legacy buildDir usages with layout.buildDirectory for task outputs and artifact registrations; updated Jacoco and SpotBugs destinations.
SpotBugs filters and report flags
compiler-plugin-tests/spotbugs-exclude.xml, native/spotbugs-exclude.xml, compiler-plugin-tests/build.gradle, compiler-plugin/build.gradle
Extended SpotBugs exclusion filters (e.g., THROWS, AT, USELESS_STRING) and switched SpotBugs report flags to .required with layout-based output directories.
Injected ExecOperations helpers & task updates
ballerina-tests/build.gradle, integration-tests/build.gradle, ballerina/build.gradle
Added abstract helper classes that inject ExecOperations and replaced project.exec/exec usages by calling execHelper.execOperations.exec { ... } in commit/publish/test/docker tasks.
Ballerina script patching task
ballerina/build.gradle
Added PatchBallerinaScriptsTask to inject JAVA_HOME into unpacked tool scripts and filter an unsafe flag; wired task into unpack/copy flow and added mavenLocal() to buildscript repos.
CI workflows & build-scan plugin migration
.github/workflows/*, settings.gradle
Updated reusable workflow references to java-25-migration, added workflow concurrency settings, and replaced Gradle Enterprise with Develocity, migrating build-scan terms keys.
Native tests: TLS ciphers and test fixes
native/src/test/java/..., ballerina-tests/http-security-tests/tests/ssl_cipher_strength_test.bal
Replaced deprecated/weak TLS cipher strings with modern ECDHE/GCM suites and applied small test/server setup fixes and data-provider corrections.

🎯 4 (Complex) | ⏱️ ~45 minutes

  • daneshk
  • lnash94
  • shafreenAnfar

"🐰
I hopped from twenty-one to twenty-five,
Patching scripts so builds can thrive,
Gradle trimmed and tests aligned,
CI hums and ciphers redefined,
A carrot-shaped commit — joyous dive!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main changes: upgrading to Gradle 9.5.1 and Java 25, which are the core objectives of this pull request.
Description check ✅ Passed The description covers the main changes (Gradle 9.5.1, Java 25, SpotBugs 6.5.1) with detailed bullet points and includes a test plan checklist. However, it does not follow the repository's pull request template structure with clearly labeled 'Purpose' and 'Examples' sections.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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

Choose a reason for hiding this comment

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

Pull request overview

This PR upgrades the build to Gradle 9.5.1 and migrates the project to Java 25, updating Gradle build scripts, Ballerina TOML platform sections, and static analysis tooling to remain compatible with the newer toolchain.

Changes:

  • Upgraded Gradle wrapper to 9.5.1 and migrated Gradle APIs (buildDirlayout.buildDirectory, updated task wiring, Develocity plugin migration).
  • Introduced Java 25 toolchains across Java subprojects and updated Ballerina platform TOMLs from java21 to java25.
  • Upgraded tooling versions (SpotBugs 6.5.1, ResearchGate release plugin 3.1.0) and added SpotBugs exclusions for newly surfaced detector categories.

Reviewed changes

Copilot reviewed 27 out of 28 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
settings.gradle Migrates from Gradle Enterprise plugin to Develocity and updates Build Scan ToS fields.
gradle/wrapper/gradle-wrapper.properties Updates wrapper distribution to Gradle 9.5.1.
gradle.properties Updates Ballerina/Gradle/tooling versions (Ballerina lang/plugin, SpotBugs, release plugin).
build.gradle Adds Java 25 toolchain configuration for Java subprojects; updates build task configuration style.
native/build.gradle Updates SpotBugs reports output configuration to use layout.buildDirectory and new report properties.
native/spotbugs-exclude.xml Adds exclusions for newly surfaced SpotBugs bug codes.
compiler-plugin/build.gradle Updates SpotBugs output configuration and replaces buildDir usage with layout.buildDirectory.
compiler-plugin-tests/build.gradle Updates JaCoCo and SpotBugs output configuration to use layout.buildDirectory.
compiler-plugin-tests/spotbugs-exclude.xml Adds exclusion for SpotBugs bug code newly surfaced by updated engine.
build-config/checkstyle/build.gradle Replaces buildDir usage with layout.buildDirectory for downloaded Checkstyle artifacts.
build-config/resources/Ballerina.toml Updates distribution version and renames platform tables from java21 to java25.
build-config/resources/BallerinaTest.toml Renames platform tables from java21 to java25 for test resources.
build-config/resources/BallerinaIntegrationTest.toml Renames platform dependency tables from java21 to java25.
ballerina/build.gradle Adds script patching task for Java 25; switches git commit exec to ExecOperations; adds mavenLocal() to buildscript repos.
ballerina/Ballerina.toml Updates distribution version and renames platform tables from java21 to java25.
ballerina/Dependencies.toml Updates Ballerina distribution version.
integration-tests/build.gradle Switches git commit exec to ExecOperations; (still contains other exec {} usage).
integration-tests/Ballerina.toml Renames platform dependency tables from java21 to java25.
ballerina-tests/build.gradle Switches git commit exec to ExecOperations; updates tests build scripts (still contains other exec {} usage).
ballerina-tests/http2-tests/Ballerina.toml Renames platform tables from java21 to java25.
ballerina-tests/http-service-tests/Ballerina.toml Renames platform tables from java21 to java25.
ballerina-tests/http-security-tests/Ballerina.toml Renames platform tables from java21 to java25.
ballerina-tests/http-resiliency-tests/Ballerina.toml Renames platform tables from java21 to java25.
ballerina-tests/http-misc-tests/Ballerina.toml Renames platform tables from java21 to java25.
ballerina-tests/http-interceptor-tests/Ballerina.toml Renames platform tables from java21 to java25.
ballerina-tests/http-dispatching-tests/Ballerina.toml Renames platform tables from java21 to java25.
ballerina-tests/http-client-tests/Ballerina.toml Renames platform tables from java21 to java25.
ballerina-tests/http-advanced-tests/Ballerina.toml Renames platform tables from java21 to java25.
Comments suppressed due to low confidence (2)

integration-tests/build.gradle:99

  • This file still uses Gradle's Project.exec { ... } later (e.g., inside ballerinaIntegrationTests.doLast { exec { ... } }). Since this PR is migrating away from Project.exec() for Gradle 9 compatibility, those remaining exec {} usages should be updated to use ExecOperations as well to avoid deprecation/removal issues.
task commitTomlFiles {
    def execHelper = project.objects.newInstance(IntegrationTestsExecHelper)
    doLast {
        def files = [
            "${project.projectDir}/Ballerina.toml",
            "${project.projectDir}/Dependencies.toml"
        ]
        execHelper.execOperations.exec {
            ignoreExitValue true
            if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                commandLine(['cmd', '/c', 'git', 'commit', '-m', '[Automated] Update the native jar versions'] + files)
            } else {
                commandLine(['git', 'commit', '-m', '[Automated] Update the native jar versions'] + files)
            }
        }

ballerina-tests/build.gradle:121

  • Although commitTomlFiles now uses ExecOperations, this build script still invokes Gradle's Project.exec { ... } in multiple tasks (e.g., publishTestCommonPackageToLocal, ballerinaTest, LDAP server tasks). For Gradle 9 migration completeness, these remaining exec {} calls should also be migrated to ExecOperations (e.g., via an injected helper/task type) to avoid relying on APIs that are deprecated/removed.
task commitTomlFiles {
    def execHelper = project.objects.newInstance(BallerinaTestsExecHelper)
    doLast {
        def files = "${testCommonPackage}/Ballerina.toml ${testCommonPackage}/Dependencies.toml "
        testPackages.each{ testPackage ->
            files += "${testPackage}/Ballerina.toml ${testPackage}/Dependencies.toml "
        }

        execHelper.execOperations.exec {
            ignoreExitValue true
            if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                commandLine 'cmd', '/c', "git commit -m \"[Automated] Update the native jar versions\" ${files}"
            } else {
                commandLine 'sh', '-c', "git commit -m '[Automated] Update the native jar versions' ${files}"
            }
        }

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

Comment thread ballerina/build.gradle Outdated
Comment on lines +50 to +53
// Inject JAVA_HOME override immediately after the shebang line
def shebangIdx = lines.findIndexOf { it.startsWith('#!') }
if (shebangIdx >= 0) {
lines.add(shebangIdx + 1, "export JAVA_HOME='${java25Home}'")

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ballerina-tests/build.gradle (1)

106-123: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Incomplete Exec migration—remaining exec { } blocks still use Project.exec (removed in Gradle 9).

commitTomlFiles already migrated to injected ExecOperations, but the following tasks still use bare exec { ... }:

  • publishTestCommonPackageToLocal (around lines 180-196)
  • ballerinaTest (around lines 217-238)
  • startLdapServer (around lines 264-273)
  • stopLdapServer (around lines 290-299)

Since Project.exec/Project.javaexec are removed in Gradle 9, these tasks will break; migrate them to ExecOperations.exec the same way as commitTomlFiles.

🤖 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-tests/build.gradle` around lines 106 - 123, The remaining tasks use
the removed Project.exec/exec { } API and must be migrated to use the injected
ExecOperations like commitTomlFiles does: in each task
(publishTestCommonPackageToLocal, ballerinaTest, startLdapServer,
stopLdapServer) create or reuse a BallerinaTestsExecHelper instance via
project.objects.newInstance(BallerinaTestsExecHelper) and replace the exec { ...
} block with execHelper.execOperations.exec { ... }, preserving settings such as
commandLine and ignoreExitValue; ensure the helper is instantiated inside the
task (e.g., def execHelper =
project.objects.newInstance(BallerinaTestsExecHelper)) so the tasks call
execHelper.execOperations.exec with the same command strings/args as before.
🧹 Nitpick comments (4)
integration-tests/build.gradle (1)

85-101: ⚖️ Poor tradeoff

Same partial migration issue as ballerina-tests/build.gradle.

The ballerinaIntegrationTests task at lines 152-161 still uses a bare exec { } block. Apply the same IntegrationTestsExecHelper pattern for consistency.

🤖 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 `@integration-tests/build.gradle` around lines 85 - 101, The
ballerinaIntegrationTests task is still using a bare exec { } call—migrate it to
use the IntegrationTestsExecHelper pattern (like task commitTomlFiles uses
execHelper.exec) to ensure consistent exec behavior; locate the
ballerinaIntegrationTests task and replace its exec { ... } blocks with an
IntegrationTestsExecHelper instance
(project.objects.newInstance(IntegrationTestsExecHelper)) and call
execHelper.exec { ... } while preserving the same commandLine, ignoreExitValue,
and OS branch logic so behavior remains identical.
ballerina/build.gradle (1)

66-80: 💤 Low value

mavenLocal() in buildscript repositories may affect CI reproducibility.

Adding mavenLocal() allows resolving plugins from the local Maven cache, which can mask issues where CI fails but local builds succeed (or vice versa). This is acceptable for development but consider documenting the intent or adding it conditionally.

🤖 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 66 - 80, The buildscript block currently
includes mavenLocal(), which can cause CI reproducibility issues; update the
build.gradle buildscript repositories to remove or conditionally include
mavenLocal() (e.g., only when a DEV or LOCAL env var is set) and add a brief
comment explaining the intent; specifically modify the buildscript ->
repositories section (the mavenLocal() call) so CI uses only declared remote
repositories and ensure any conditional check reads an environment variable
(e.g., processEnv like PACKAGE_USE_LOCAL) or document why mavenLocal() is
required.
compiler-plugin-tests/spotbugs-exclude.xml (1)

53-56: Consider tracking the suppressed THROWS issues for future resolution.

The BugCode-level exclusion suppresses all instances of THROWS bugs (exception handling issues) across the module, including any new violations introduced in future changes. While pragmatic for unblocking the Java 25 migration, consider creating a tracking issue to review and address these pre-existing patterns, then migrate to more targeted class/method-specific exclusions.

🤖 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 `@compiler-plugin-tests/spotbugs-exclude.xml` around lines 53 - 56, The current
SpotBugs exclusion uses a broad BugCode-level match (<BugCode name="THROWS"/>)
which suppresses all THROWS warnings; create a TODO/tracking ticket and replace
this global suppression with targeted exclusions (class- or method-level <Match>
entries) for the specific pre-existing offenders so future THROWS regressions
are not silently ignored—add a comment in spotbugs-exclude.xml referencing the
tracking issue ID and then change the <Match> that references BugCode
name="THROWS" to one or more <Match> blocks targeting the exact classes or
methods that need suppression (or keep the global rule temporarily but document
the tracking ticket ID next to <BugCode name="THROWS"/>).
native/spotbugs-exclude.xml (1)

220-229: Consider tracking the suppressed bug categories for future resolution.

Three BugCode-level exclusions (THROWS, AT, USELESS_STRING) suppress all instances of exception handling, annotation/threading, and string manipulation issues across the native module. These broad exclusions will also mask any new violations introduced in future changes. While pragmatic for unblocking the Java 25 migration, consider:

  1. Creating a tracking issue to review and remediate these pre-existing patterns
  2. Migrating to more targeted class/method-specific exclusions once issues are understood
  3. Establishing a process to periodically review whether these can be narrowed or removed
🤖 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 `@native/spotbugs-exclude.xml` around lines 220 - 229, The SpotBugs exclusions
currently blanket three BugCode entries (THROWS, AT, USELESS_STRING) which will
hide all related violations; create a tracking issue referencing these BugCode
names (THROWS, AT, USELESS_STRING) to triage and document the rationale, add
TODO metadata in native/spotbugs-exclude.xml pointing to that issue, and plan a
follow-up to replace broad BugCode-level exclusions with targeted <Class> or
<Method> matches once individual instances are reviewed and remediated; include
a periodic review cadence in the tracking issue so the exclusions can be
narrowed or removed over time.
🤖 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 28-64: The patch task in PatchBallerinaScriptsTask.patch reads
file.text and uses split('\n') which leaves trailing '\r' on Windows CRLF files
and corrupts injected lines; update the line-splitting/normalization so it
handles both LF and CRLF (e.g., use a regex split that matches \r?\n or use a
platform-agnostic readLines()/normalize step) when building the lines list,
ensure injected "export JAVA_HOME..." is inserted without a trailing '\r', and
preserve existing newline semantics when joining back to produce patched before
comparing and writing to file.text.

In `@gradle/wrapper/gradle-wrapper.properties`:
- Line 3: The gradle-wrapper.properties update changed distributionUrl to Gradle
9.5.1 which crosses the 8→9 major boundary; either revert distributionUrl back
to the previous 8.11.1 wrapper or, if you intend to upgrade, run the Gradle 9
migration checklist: update the gradle wrapper (distributionUrl) intentionally,
ensure CI and local builds use Java 17+ for the Gradle daemon, verify embedded
Kotlin/toolchain settings and any Kotlin DSL code, audit Groovy 4
incompatibilities, and test Configuration Cache and any API/behavior removals
across the build; use the distributionUrl value in gradle-wrapper.properties and
the gradle wrapper task to apply the change only after these validations.

---

Outside diff comments:
In `@ballerina-tests/build.gradle`:
- Around line 106-123: The remaining tasks use the removed Project.exec/exec { }
API and must be migrated to use the injected ExecOperations like commitTomlFiles
does: in each task (publishTestCommonPackageToLocal, ballerinaTest,
startLdapServer, stopLdapServer) create or reuse a BallerinaTestsExecHelper
instance via project.objects.newInstance(BallerinaTestsExecHelper) and replace
the exec { ... } block with execHelper.execOperations.exec { ... }, preserving
settings such as commandLine and ignoreExitValue; ensure the helper is
instantiated inside the task (e.g., def execHelper =
project.objects.newInstance(BallerinaTestsExecHelper)) so the tasks call
execHelper.execOperations.exec with the same command strings/args as before.

---

Nitpick comments:
In `@ballerina/build.gradle`:
- Around line 66-80: The buildscript block currently includes mavenLocal(),
which can cause CI reproducibility issues; update the build.gradle buildscript
repositories to remove or conditionally include mavenLocal() (e.g., only when a
DEV or LOCAL env var is set) and add a brief comment explaining the intent;
specifically modify the buildscript -> repositories section (the mavenLocal()
call) so CI uses only declared remote repositories and ensure any conditional
check reads an environment variable (e.g., processEnv like PACKAGE_USE_LOCAL) or
document why mavenLocal() is required.

In `@compiler-plugin-tests/spotbugs-exclude.xml`:
- Around line 53-56: The current SpotBugs exclusion uses a broad BugCode-level
match (<BugCode name="THROWS"/>) which suppresses all THROWS warnings; create a
TODO/tracking ticket and replace this global suppression with targeted
exclusions (class- or method-level <Match> entries) for the specific
pre-existing offenders so future THROWS regressions are not silently ignored—add
a comment in spotbugs-exclude.xml referencing the tracking issue ID and then
change the <Match> that references BugCode name="THROWS" to one or more <Match>
blocks targeting the exact classes or methods that need suppression (or keep the
global rule temporarily but document the tracking ticket ID next to <BugCode
name="THROWS"/>).

In `@integration-tests/build.gradle`:
- Around line 85-101: The ballerinaIntegrationTests task is still using a bare
exec { } call—migrate it to use the IntegrationTestsExecHelper pattern (like
task commitTomlFiles uses execHelper.exec) to ensure consistent exec behavior;
locate the ballerinaIntegrationTests task and replace its exec { ... } blocks
with an IntegrationTestsExecHelper instance
(project.objects.newInstance(IntegrationTestsExecHelper)) and call
execHelper.exec { ... } while preserving the same commandLine, ignoreExitValue,
and OS branch logic so behavior remains identical.

In `@native/spotbugs-exclude.xml`:
- Around line 220-229: The SpotBugs exclusions currently blanket three BugCode
entries (THROWS, AT, USELESS_STRING) which will hide all related violations;
create a tracking issue referencing these BugCode names (THROWS, AT,
USELESS_STRING) to triage and document the rationale, add TODO metadata in
native/spotbugs-exclude.xml pointing to that issue, and plan a follow-up to
replace broad BugCode-level exclusions with targeted <Class> or <Method> matches
once individual instances are reviewed and remediated; include a periodic review
cadence in the tracking issue so the exclusions can be narrowed or removed over
time.
🪄 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: 1453f984-b756-4e86-aef9-5fa328597f5f

📥 Commits

Reviewing files that changed from the base of the PR and between 9b84a8b and 5352ef6.

📒 Files selected for processing (28)
  • ballerina-tests/build.gradle
  • ballerina-tests/http-advanced-tests/Ballerina.toml
  • ballerina-tests/http-client-tests/Ballerina.toml
  • ballerina-tests/http-dispatching-tests/Ballerina.toml
  • ballerina-tests/http-interceptor-tests/Ballerina.toml
  • ballerina-tests/http-misc-tests/Ballerina.toml
  • ballerina-tests/http-resiliency-tests/Ballerina.toml
  • ballerina-tests/http-security-tests/Ballerina.toml
  • ballerina-tests/http-service-tests/Ballerina.toml
  • ballerina-tests/http2-tests/Ballerina.toml
  • ballerina/Ballerina.toml
  • ballerina/Dependencies.toml
  • ballerina/build.gradle
  • build-config/checkstyle/build.gradle
  • build-config/resources/Ballerina.toml
  • build-config/resources/BallerinaIntegrationTest.toml
  • build-config/resources/BallerinaTest.toml
  • build.gradle
  • compiler-plugin-tests/build.gradle
  • compiler-plugin-tests/spotbugs-exclude.xml
  • compiler-plugin/build.gradle
  • gradle.properties
  • gradle/wrapper/gradle-wrapper.properties
  • integration-tests/Ballerina.toml
  • integration-tests/build.gradle
  • native/build.gradle
  • native/spotbugs-exclude.xml
  • settings.gradle

Comment thread ballerina/build.gradle
Comment on lines +28 to +64
abstract class PatchBallerinaScriptsTask extends DefaultTask {
@Inject abstract JavaToolchainService getJavaToolchainService()

@TaskAction
void patch() {
def launcher = javaToolchainService.launcherFor { spec ->
spec.languageVersion.set(JavaLanguageVersion.of(25))
}.get()
def java25Home = launcher.executablePath.asFile.parentFile.parentFile.absolutePath

def binDirs = [
project.layout.buildDirectory.dir("jballerina-tools-${project.ballerinaLangVersion}/bin").get().asFile,
new File("${project.rootDir}/target/ballerina-runtime/bin")
]
binDirs.each { binDir ->
if (binDir.exists()) {
binDir.eachFile { file ->
file.setExecutable(true)
if (!file.name.endsWith('.bat') && !file.name.endsWith('.cmd')) {
def original = file.text
def lines = original.split('\n').toList()
lines = lines.findAll { !it.contains('--sun-misc-unsafe-memory-access=allow') }
// Inject JAVA_HOME override immediately after the shebang line
def shebangIdx = lines.findIndexOf { it.startsWith('#!') }
if (shebangIdx >= 0) {
lines.add(shebangIdx + 1, "export JAVA_HOME='${java25Home}'")
}
def patched = lines.join('\n') + '\n'
if (patched != original) {
file.text = patched
}
}
}
}
}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

CRLF line endings not handled in script patching.

Line 48 uses split('\n') which doesn't strip \r from lines if scripts have Windows-style CRLF endings. This would result in malformed scripts with trailing carriage returns.

Consider using a regex that handles both:

🛡️ Proposed fix for cross-platform line ending handling
-                        def lines = original.split('\n').toList()
+                        def lines = original.split(/\r?\n/).toList()
🤖 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 28 - 64, The patch task in
PatchBallerinaScriptsTask.patch reads file.text and uses split('\n') which
leaves trailing '\r' on Windows CRLF files and corrupts injected lines; update
the line-splitting/normalization so it handles both LF and CRLF (e.g., use a
regex split that matches \r?\n or use a platform-agnostic readLines()/normalize
step) when building the lines list, ensure injected "export JAVA_HOME..." is
inserted without a trailing '\r', and preserve existing newline semantics when
joining back to produce patched before comparing and writing to file.text.

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Has Gradle 9.5.1 been released and is it stable?

💡 Result:

Yes—Gradle 9.5.1 has been released (tag v9.5.1 on GitHub, published 2026-05-12) [1] and it’s available for download from Gradle’s distribution site (bin/all/docs/src artifacts dated 12-May-2026) [2]. On whether it’s stable: Gradle 9.5.1 is a patch release (the first patch release for the 9.5.0 line) [3] and the official release notes explicitly recommend upgrading to 9.5.1 [3]. The release notes also describe it as a fixes/improvements release (“issues were resolved”) rather than a major-version change [3].

Citations:


🌐 Web query:

Gradle 9 migration guide breaking changes from Gradle 8 to Gradle 9

💡 Result:

Gradle 9 migration (Gradle 8 → Gradle 9): key breaking changes to check 1) Minimum Java requirement (Gradle daemon) Gradle 9.0.0 requires running the Gradle daemon on JVM 17+ (breaking vs earlier Gradle 8.x that supported JVM 8+). [1] 2) Kotlin DSL / embedded Kotlin upgrade The Kotlin DSL is upgraded to the embedded Kotlin 2.2.x runtime and uses Kotlin language version 2.2 across the toolchain (a shift from Gradle 8.x’s embedded Kotlin 2.0 with Kotlin language version 1.8 for compatibility). [1] 3) Groovy upgrade to Groovy 4 Gradle 9.0.0 upgrades Groovy from 3.0.x to 4.0.27, which includes many breaking language-level changes (e.g., removal of legacy packages, module structure changes, parser rewrite, bytecode output changes). [1] 4) Configuration Cache / API removals theme Gradle 9 removed many previously deprecated APIs and behaviors that were incompatible with Configuration Cache, replacing them with alternatives compatible with it. [2] 5) Kotlin/JSpecify + stricter nullability in Gradle API (binary/signature impact) Starting with Gradle 9, the Gradle API is annotated using JSpecify instead of the earlier JSR-305-based approach; Gradle 9 release notes call out stricter nullability handling and potential binary API changes due to Kotlin 2.1 + JSpecify. [3] 6) Plugin/build behavior changes called out in the 9.0.0 upgrade guide The Gradle 9.0.0 upgrade guide specifically highlights multiple categories of breaking changes including: - Plugin changes (including cases where test tasks may no longer execute expected tests / test failures when no tests are discovered). [4] - Build/cache behavior changes, such as “stale outputs outside the build directory are no longer deleted.” [4] - API/feature removals and “Removal of conventions.” [1] Where to look (most authoritative lists) - Primary migration guide for Gradle 8.14.x → Gradle 9.0.0: https://docs.gradle.org/current/userguide/upgrading_major_version_9.html [1] - Release notes for Gradle 9.0.0 (additional context/notes): https://docs.gradle.org/9.0.0/release-notes.html [3] - “What’s new in Gradle 9” overview (themes like Configuration Cache compatibility): https://gradle.org/whats-new/gradle-9/ [2] If you share which Gradle 8.x patchlevel you’re on (e.g., 8.5, 8.14.2, etc.) and whether you use Groovy or Kotlin DSL (plus any custom plugins), I can narrow this to the exact breaking sections most likely to affect your build.

Citations:


Gradle wrapper: Gradle 9.5.1 is released (patch); still review 8.11.1 → 9.x breaking changes

distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip

Gradle 9.5.1 is available and is published as a fixes/improvements (patch) release with release notes recommending the upgrade. Since this still jumps across the Gradle 9 major line from 8.11.1, review the Gradle 9 migration guide for breaking changes to your build scripts, especially:

  • Java 17+ requirement for the Gradle daemon
  • embedded Kotlin + toolchain upgrades
  • Groovy 4 language changes
  • API/behavior removals tied to Configuration Cache compatibility
🤖 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 `@gradle/wrapper/gradle-wrapper.properties` at line 3, The
gradle-wrapper.properties update changed distributionUrl to Gradle 9.5.1 which
crosses the 8→9 major boundary; either revert distributionUrl back to the
previous 8.11.1 wrapper or, if you intend to upgrade, run the Gradle 9 migration
checklist: update the gradle wrapper (distributionUrl) intentionally, ensure CI
and local builds use Java 17+ for the Gradle daemon, verify embedded
Kotlin/toolchain settings and any Kotlin DSL code, audit Groovy 4
incompatibilities, and test Configuration Cache and any API/behavior removals
across the build; use the distributionUrl value in gradle-wrapper.properties and
the gradle wrapper task to apply the change only after these validations.

Thevakumar-Luheerathan added 2 commits May 28, 2026 06:13
Update graalvm workflow to call the java-25-migration branch of
ballerina-library template instead of @main, so GraalVM checks use
Java 25 matching the module's compilation target.
Update pull-request workflow to call the java-25-migration branch of
ballerina-library template instead of @main, so PR builds use Java 25.
Also add concurrency group to cancel duplicate runs.

@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

🤖 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 @.github/workflows/build-with-bal-test-graalvm.yml:
- Line 43: Update the reusable workflow reference on the "uses:" line that
currently ends with "`@java-25-migration`" to a fixed commit SHA (replace
"`@java-25-migration`" with "@<full-commit-sha>") so CI is deterministic; locate
the "uses:
ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@java-25-migration"
entry in build-with-bal-test-graalvm.yml and swap the mutable ref for the full
commit SHA of the target repo/tag, commit the change, and verify the workflow
runs.

In @.github/workflows/pull-request.yml:
- Around line 13-14: The reusable workflow invocation currently uses a mutable
branch ref and forwards all secrets with "secrets: inherit", which is unsafe;
change the "uses:
ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java-25-migration"
to a specific immutable commit SHA (replace the `@java-25-migration` ref with the
exact commit SHA) and remove "secrets: inherit", instead explicitly pass only
the needed secrets (e.g., "secrets: MY_SECRET: ${{ secrets.MY_SECRET }}" for
each required secret) so that you pin the workflow version and limit secret
exposure.
🪄 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: 511dbdea-3bb3-4603-b5fd-4b7580419fbc

📥 Commits

Reviewing files that changed from the base of the PR and between 5352ef6 and 8abccc0.

📒 Files selected for processing (2)
  • .github/workflows/build-with-bal-test-graalvm.yml
  • .github/workflows/pull-request.yml

name: Run StdLib Workflow
if: ${{ github.event_name != 'schedule' || (github.event_name == 'schedule' && github.repository_owner == 'ballerina-platform') }}
uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@main
uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@java-25-migration

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify mutable workflow refs in repo workflows.
rg -nP '^\s*uses:\s*[^#\n]+@((main|master|[A-Za-z0-9._/-]+))\s*$' .github/workflows
# Expected: this line should be gone once pinned to a 40-char SHA.

Repository: ballerina-platform/module-ballerina-http

Length of output: 2936


Pin reusable workflow reference in build-with-bal-test-graalvm.yml to a commit SHA
./.github/workflows/build-with-bal-test-graalvm.yml line 43 references a reusable workflow with the mutable ref @java-25-migration—use the full commit SHA instead to keep CI behavior deterministic.

🔒 Suggested fix
-        uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@java-25-migration
+        uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@<full_commit_sha>
🧰 Tools
🪛 zizmor (1.25.2)

[error] 43-43: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 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 @.github/workflows/build-with-bal-test-graalvm.yml at line 43, Update the
reusable workflow reference on the "uses:" line that currently ends with
"`@java-25-migration`" to a fixed commit SHA (replace "`@java-25-migration`" with
"@<full-commit-sha>") so CI is deterministic; locate the "uses:
ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@java-25-migration"
entry in build-with-bal-test-graalvm.yml and swap the mutable ref for the full
commit SHA of the target repo/tag, commit the change, and verify the workflow
runs.

Comment on lines +13 to 14
uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java-25-migration
secrets: inherit

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find reusable workflow calls that are mutable and/or inherit all secrets.
rg -nP '^\s*uses:\s*[^#\n]+@([A-Za-z0-9._/-]+)\s*$|^\s*secrets:\s*inherit\s*$' .github/workflows
# Expected after fix:
# - `uses:` for external/reusable workflows pinned to full SHAs
# - no unconditional `secrets: inherit` unless explicitly justified

Repository: ballerina-platform/module-ballerina-http

Length of output: 3349


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE=".github/workflows/pull-request.yml"
echo "== File: $FILE =="
nl -ba "$FILE" | sed -n '1,80p'

Repository: ballerina-platform/module-ballerina-http

Length of output: 192


🌐 Web query:

GitHub Actions reusable workflow security pin commit SHA secrets: inherit

💡 Result:

In a GitHub Actions workflow that calls a reusable workflow, secrets: inherit is supported and it passes the caller workflow’s secrets to the directly called reusable workflow. Specifically, reusable workflow docs show secrets: inherit in a job that uses another workflow via uses: owner/repo/.github/workflows/<file>@<ref>, and they note that you can reference inherited secrets even when they’re not explicitly defined under the reusable workflow’s on: workflow_call secret list [1]. The workflow syntax reference also describes passing secrets and the jobs.<job_id>.secrets.inherit form for passing all calling-workflow secrets into the directly called workflow [2]. For security pinning: when referencing reusable workflows (and third-party actions), you should pin the uses: reference to a specific immutable identifier. GitHub’s “Secure use” guidance says using a full-length commit SHA is the only way to treat an action as an immutable release, and pinning to a full-length commit SHA mitigates the risk of a backdoor being added to the action’s repository [3]. The reusable-workflow docs explicitly state that the {ref} portion can be a SHA, release tag, or branch name, and that using the commit SHA is the safest option for stability and security [1]. So the best practice pattern is: - Pin the reusable workflow uses: ref to a full-length commit SHA (not a branch like main, not a moving tag) [1][3]. - If you need secrets from the caller, use secrets: inherit only when the called workflow is trusted and you intentionally want to pass all caller secrets through the workflow chain (note secrets are only passed to the directly called workflow, not implicitly further) [2][4]. Example (caller workflow job that pins reusable workflow and inherits secrets): - uses: ORG/REPO/.github/workflows/reusable.yml@<full-length-commit-sha> - secrets: inherit [1][2]. Security note on scope: GitHub docs clarify that in a workflow chain A > B > C, workflow C will only receive secrets from A if A passes secrets to B, and then B passes them to C; secrets: inherit does not automatically propagate beyond the directly called workflow [4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE=".github/workflows/pull-request.yml"
echo "== $FILE (lines 8-22) =="
awk 'NR>=8 && NR<=22 {printf "%d:%s\n", NR, $0}' "$FILE"

Repository: ballerina-platform/module-ballerina-http

Length of output: 412


🌐 Web query:

ballerina-platform/ballerina-library pull-request-build-template.yml java-25-migration secrets inherit

💡 Result:

I couldn’t locate the specific file path you mentioned (ballerina-platform/ballerina-library pull-request-build-template.yml java-25-migration secrets inherit). What I can confirm from authoritative sources is the following relevant parts: 1) How secrets: inherit works for reusable GitHub workflows - In GitHub Actions, you can call a reusable workflow and pass secrets implicitly using secrets: inherit. The called (reusable) workflow can then reference those secrets even if they aren’t explicitly defined in the called workflow’s on inputs/keys. [1] - You can also pass all calling workflow secrets to a directly called workflow with jobs.<job_id>.secrets.inherit. [1] 2) Example showing secrets: inherit used with a Ballerina-library reusable workflow - In ballerina-platform/module-ballerinax-azure.ai.search, the repository’s .github/workflows/pull-request.yml calls a reusable workflow in ballerina-platform/ballerina-library and sets secrets: inherit. [2] 3) Evidence around “Java 25 migration” context (Ballerina-related) - There is an open issue about “Getting warnings when running in Java 25” in ballerina-platform/ballerina-lang, indicating Java 25-specific runtime warnings are a consideration in the Ballerina ecosystem. [3] - A Java 25 migration guide exists (OpenRewrite) but it’s about upgrading Java codebases broadly; it doesn’t directly confirm any specific pull-request-build-template.yml behavior in ballerina-library. [4] If you share the exact repo URL (or paste the relevant portion of the pull-request-build-template.yml and/or the java-25-migration job block), I can verify precisely whether and where secrets: inherit is used and how the Java 25 migration is wired in that template.

Citations:


Pin the reusable workflow ref to an immutable commit SHA and avoid secrets: inherit
.github/workflows/pull-request.yml calls ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java-25-migration and uses secrets: inherit, forwarding all caller secrets to the reusable workflow.

    uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java-25-migration
    secrets: inherit
🔐 Suggested hardening
-    uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java-25-migration
-    secrets: inherit
+    uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@<full_commit_sha>
+    secrets:
+      REQUIRED_SECRET_NAME: ${{ secrets.REQUIRED_SECRET_NAME }}
🧰 Tools
🪛 zizmor (1.25.2)

[error] 13-13: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[warning] 13-13: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow

(secrets-inherit)

🤖 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 @.github/workflows/pull-request.yml around lines 13 - 14, The reusable
workflow invocation currently uses a mutable branch ref and forwards all secrets
with "secrets: inherit", which is unsafe; change the "uses:
ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java-25-migration"
to a specific immutable commit SHA (replace the `@java-25-migration` ref with the
exact commit SHA) and remove "secrets: inherit", instead explicitly pass only
the needed secrets (e.g., "secrets: MY_SECRET: ${{ secrets.MY_SECRET }}" for
each required secret) so that you pin the workflow version and limit secret
exposure.

Thevakumar-Luheerathan and others added 4 commits May 28, 2026 10:31
…ests

- Bump jacocoVersion from 0.8.10 to 0.8.13 to support Java 25 class file version (major version 69)
- Replace bare exec {} with project.exec {} in DefaultTask doLast blocks (startLdapServer, stopLdapServer, publishTestCommonPackageToLocal, ballerinaTest) since Gradle 9 removed the implicit exec() method from DefaultTask
Replace all project.exec { } closure calls with ExecOperations injection
pattern (BallerinaTestsExecHelper) in publishTestCommonPackageToLocal,
ballerinaTest, startLdapServer, and stopLdapServer tasks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
gradle.properties (2)

30-33: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Verify Java 25 / Gradle 9.5.1 compatibility for SpotBugs 6.5.1 and researchgate release 3.1.0

  • githubSpotbugsVersion=6.5.1 by itself doesn’t provide evidence for Java 25 / ASM 9.7 support; the Java 25 handling depends on the actual SpotBugs version you run (configured via the SpotBugs toolVersion/spotbugs config). Resolve the final SpotBugs + ASM versions from the Gradle dependency graph.
  • researchgateReleaseVersion=3.1.0 documentation only claims “Gradle 6.0 and beyond” and doesn’t explicitly mention Gradle 9.5.1; validate the upgrade path for 9.5.1 during the migration.
🤖 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 `@gradle.properties` around lines 30 - 33, Verify compatibility for Java 25 /
Gradle 9.5.1 by resolving the actual SpotBugs runtime and ASM versions pulled in
by the project: inspect the Gradle dependency graph (for example via ./gradlew
dependencies or dependencyInsight) to confirm that the effective SpotBugs
toolVersion and ASM are compatible with Java 25 rather than relying solely on
githubSpotbugsVersion=6.5.1, and update the SpotBugs toolVersion/spotbugs config
or bump githubSpotbugsVersion accordingly if ASM < 9.7 is selected; similarly
validate researchgateReleaseVersion=3.1.0 works with Gradle 9.5.1 by testing the
release plugin tasks with Gradle 9.5.1 and, if incompatible, pick a newer
compatible release plugin version or add compatibility notes in the migration
docs.

19-19: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Confirm io.ballerina:plugin-gradle:4.0.0 exists and that Java 25 support is actually provided

  • gradle.properties sets ballerinaGradlePluginVersion=4.0.0, and ballerina/build.gradle resolves io.ballerina:plugin-gradle:${project.ballerinaGradlePluginVersion}.
  • No public evidence/release/tag found for plugin-gradle 4.0.0 (repo latest appears to be v0.9.1), so this bump risks an unresolved dependency.
  • Java 25 support generally depends on using Gradle 9.1.0+ (toolchains/JVM); there’s no source tying plugin-gradle 4.0.0 specifically to Java 25—please confirm the repo’s Gradle/JDK/toolchain matrix and the documented reason this exact version is required.
🤖 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 `@gradle.properties` at line 19, The property
ballerinaGradlePluginVersion=4.0.0 may point to a non‑existent artifact and you
must confirm Java 25 support; verify that the Maven artifact groupId
io.ballerina artifactId plugin-gradle version 4.0.0 is published (or pick the
latest published tag, e.g., v0.9.1) and update the ballerinaGradlePluginVersion
accordingly, or revert to the known-good published version used in
ballerina/build.gradle; additionally, document or assert in the build config
which Gradle and JDK/toolchain versions support Java 25 (e.g., require Gradle
9.1.0+ and appropriate toolchain settings) and include that rationale next to
the ballerinaGradlePluginVersion so future readers know why a specific plugin
version is required.
🤖 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 `@gradle.properties`:
- Line 4: The ballerinaLangVersion in gradle.properties is set to a timestamped
snapshot which may not be available in Maven Central and may lack Java 25
support; update the ballerinaLangVersion property to a published,
repository-available Ballerina release (or the specific release that documents
Java 25 support) instead of the snapshot (refer to the ballerinaLangVersion key
in gradle.properties), and verify the chosen version exists in Maven
Central/Ballerina staging before committing.
- Line 25: The jacocoVersion property is set to 0.8.13 which lacks official Java
25 support; update the jacocoVersion property value to 0.8.14 or later in
gradle.properties (the jacocoVersion variable) so the build uses a JaCoCo
release with official Java 25 support; after changing jacocoVersion, run your
Gradle build/tests to verify instrumentation and adjust any CI JDK matrix to use
a compatible JaCoCo version if necessary.

---

Outside diff comments:
In `@gradle.properties`:
- Around line 30-33: Verify compatibility for Java 25 / Gradle 9.5.1 by
resolving the actual SpotBugs runtime and ASM versions pulled in by the project:
inspect the Gradle dependency graph (for example via ./gradlew dependencies or
dependencyInsight) to confirm that the effective SpotBugs toolVersion and ASM
are compatible with Java 25 rather than relying solely on
githubSpotbugsVersion=6.5.1, and update the SpotBugs toolVersion/spotbugs config
or bump githubSpotbugsVersion accordingly if ASM < 9.7 is selected; similarly
validate researchgateReleaseVersion=3.1.0 works with Gradle 9.5.1 by testing the
release plugin tasks with Gradle 9.5.1 and, if incompatible, pick a newer
compatible release plugin version or add compatibility notes in the migration
docs.
- Line 19: The property ballerinaGradlePluginVersion=4.0.0 may point to a
non‑existent artifact and you must confirm Java 25 support; verify that the
Maven artifact groupId io.ballerina artifactId plugin-gradle version 4.0.0 is
published (or pick the latest published tag, e.g., v0.9.1) and update the
ballerinaGradlePluginVersion accordingly, or revert to the known-good published
version used in ballerina/build.gradle; additionally, document or assert in the
build config which Gradle and JDK/toolchain versions support Java 25 (e.g.,
require Gradle 9.1.0+ and appropriate toolchain settings) and include that
rationale next to the ballerinaGradlePluginVersion so future readers know why a
specific plugin version is required.
🪄 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: d60f80fb-0cdd-4073-8fc4-9f91d6e49342

📥 Commits

Reviewing files that changed from the base of the PR and between c99be7d and 5b76bb4.

📒 Files selected for processing (2)
  • ballerina-tests/build.gradle
  • gradle.properties

Comment thread gradle.properties
group=io.ballerina.stdlib
version=2.17.0-SNAPSHOT
ballerinaLangVersion=2201.13.3
ballerinaLangVersion=2201.14.0-20260527-050400-74f7e6bf

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify that the Ballerina snapshot version exists in Maven repositories

# Check Maven Central
echo "Checking Maven Central..."
curl -s "https://repo1.maven.org/maven2/org/ballerinalang/jballerina-tools/2201.14.0-20260527-050400-74f7e6bf/" | grep -q "jballerina-tools" && echo "✓ Found in Maven Central" || echo "✗ Not found in Maven Central"

# Check Ballerina's staging repository
echo "Checking Ballerina staging repository..."
curl -s "https://maven.pkg.github.com/ballerina-platform/ballerina-lang/org/ballerinalang/jballerina-tools/2201.14.0-20260527-050400-74f7e6bf/" | grep -q "jballerina-tools" && echo "✓ Found in staging" || echo "✗ Not found in staging"

# List recent versions from Maven Central for comparison
echo -e "\nRecent versions available:"
curl -s "https://repo1.maven.org/maven2/org/ballerinalang/jballerina-tools/" | grep -oP '2201\.\d+\.\d+(-\d+)?' | sort -V | tail -10

Repository: ballerina-platform/module-ballerina-http

Length of output: 231


🌐 Web query:

Does Ballerina 2201.14.0 support Java 25 runtime?

💡 Result:

No definitive evidence found that Ballerina 2201.14.0 (Swan Lake) explicitly supports “Java 25 runtime.” What the official Ballerina sources do show is: 1) Ballerina runtime support jumped to Java 21 in Swan Lake Update 11 (2201.11.0), and the runtime is described as “now supports Java 21”.[1][2] 2) There are issues showing Ballerina running on newer Java (e.g., Java 25) with runtime warnings, indicating it may run but is not presented as an officially supported target in the cited official release notes.[3] Therefore, based on cited official documentation, Ballerina 2201.14.0 should be expected to support up through Java 21 (as the latest explicitly documented LTS support in Swan Lake Update 11). Any Java 25 compatibility is not confirmed as “supported” for 2201.14.0 in the sources retrieved; only warnings are evidenced for Java 25 in later Ballerina versions.[1][3]

Citations:


Pin ballerinaLangVersion to a published release; current snapshot risks build breakage and lacks Java 25 support evidence

gradle.properties: ballerinaLangVersion=2201.14.0-20260527-050400-74f7e6bf is a timestamped snapshot. The expected org/ballerinalang/jballerina-tools/<version> path is not present in the checked Maven Central or Ballerina staging listings, so CI/builds may fail when resolving the dependency.

Also, Java 25 support is not documented as supported for the 2201.14.x line (Swan Lake Update 11 release notes explicitly state Java 21 support as the latest documented target), so using Java 25 may be unsupported.

  • Recommend switching to a published, repository-available Ballerina version (or the exact version that is documented to support Java 25), rather than an unverified snapshot.
🤖 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 `@gradle.properties` at line 4, The ballerinaLangVersion in gradle.properties
is set to a timestamped snapshot which may not be available in Maven Central and
may lack Java 25 support; update the ballerinaLangVersion property to a
published, repository-available Ballerina release (or the specific release that
documents Java 25 support) instead of the snapshot (refer to the
ballerinaLangVersion key in gradle.properties), and verify the chosen version
exists in Maven Central/Ballerina staging before committing.

Comment thread gradle.properties Outdated

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

🧹 Nitpick comments (1)
ballerina-tests/http-security-tests/tests/ssl_cipher_strength_test.bal (1)

62-62: 💤 Low value

Consider renaming weakCipherConfig for clarity.

The cipher suite was updated to TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, which is cryptographically strong (256-bit AES, GCM mode, ECDHE key exchange). The "weak" label appears to refer to cipher incompatibility for the negative test case rather than cryptographic weakness. While this works correctly for the test (client cipher at line 90 won't match, triggering the expected handshake failure), the naming may confuse future maintainers.

🤖 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-tests/http-security-tests/tests/ssl_cipher_strength_test.bal` at
line 62, Rename the misleading variable weakCipherConfig to a clearer name like
incompatibleCipherConfig or nonMatchingCipherConfig to reflect that the test
uses a crypto-strong but non-matching cipher suite; update the declaration
(weakCipherConfig) and all references/usages (e.g., the client config that
expects a mismatch/handshake failure) in ssl_cipher_strength_test.bal so the new
identifier is used consistently throughout the test.
🤖 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.

Nitpick comments:
In `@ballerina-tests/http-security-tests/tests/ssl_cipher_strength_test.bal`:
- Line 62: Rename the misleading variable weakCipherConfig to a clearer name
like incompatibleCipherConfig or nonMatchingCipherConfig to reflect that the
test uses a crypto-strong but non-matching cipher suite; update the declaration
(weakCipherConfig) and all references/usages (e.g., the client config that
expects a mismatch/handshake failure) in ssl_cipher_strength_test.bal so the new
identifier is used consistently throughout the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bf351313-16c4-4747-82cf-dd7e6439552d

📥 Commits

Reviewing files that changed from the base of the PR and between 5b76bb4 and 2a331fa.

📒 Files selected for processing (11)
  • ballerina-tests/http-advanced-tests/Dependencies.toml
  • ballerina-tests/http-security-tests/tests/ssl_cipher_strength_test.bal
  • ballerina-tests/http-test-common/Dependencies.toml
  • ballerina-tests/http2-tests/Dependencies.toml
  • ballerina/Dependencies.toml
  • native/src/test/java/io/ballerina/stdlib/http/transport/certificatevalidation/Utils.java
  • native/src/test/java/io/ballerina/stdlib/http/transport/http2/frameleveltests/client/Http2TcpServerGoAway100ContinueScenarioTest.java
  • native/src/test/java/io/ballerina/stdlib/http/transport/https/CipherSuitesTest.java
  • native/src/test/java/io/ballerina/stdlib/http/transport/https/CipherSuiteswithCertsTest.java
  • native/src/test/java/io/ballerina/stdlib/http/transport/util/Http2Util.java
  • native/src/test/java/io/ballerina/stdlib/http/transport/util/server/HttpsServer.java
✅ Files skipped from review due to trivial changes (4)
  • native/src/test/java/io/ballerina/stdlib/http/transport/util/Http2Util.java
  • ballerina-tests/http-test-common/Dependencies.toml
  • ballerina-tests/http2-tests/Dependencies.toml
  • ballerina-tests/http-advanced-tests/Dependencies.toml

Thevakumar-Luheerathan added 2 commits June 4, 2026 13:59
Java 25 changed the JSSE error message format to include the alert name in
parentheses (e.g. "(handshake_failure) Received fatal alert: ..."), breaking
the exact assertEquals check in ssl_cipher_strength_test.bal. Also, on
Windows Java 25, a TLSv1.3 client connecting to a TLSv1.2-only server
produces a different error message that doesn't contain "SSL connection
failed", breaking testSslProtocolConflict in http2_ssl_protocol_test.bal.

Replace exact string equality with flexible strings:includes checks that
accept the known error message variants across platforms and Java versions.
@sonarqubecloud

sonarqubecloud Bot commented Jun 5, 2026

Copy link
Copy Markdown

@codecov

codecov Bot commented Jun 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.32%. Comparing base (9b84a8b) to head (1c9f68b).
⚠️ Report is 2 commits behind head on master.

❌ Your project check has failed because the head coverage (79.32%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #2630      +/-   ##
============================================
+ Coverage     79.21%   79.32%   +0.11%     
- Complexity        0      915     +915     
============================================
  Files           376      441      +65     
  Lines         21636    24556    +2920     
  Branches       3382     3929     +547     
============================================
+ Hits          17138    19480    +2342     
- Misses         3547     3876     +329     
- Partials        951     1200     +249     

☔ 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.

Applied fixes: A1+B1+B4, 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)
@sonarqubecloud

Copy link
Copy Markdown

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