Skip to content

Comments

Add Java 21 Compilation Support#453

Open
Zeta201 wants to merge 4 commits intowso2:masterfrom
Zeta201:java21
Open

Add Java 21 Compilation Support#453
Zeta201 wants to merge 4 commits intowso2:masterfrom
Zeta201:java21

Conversation

@Zeta201
Copy link

@Zeta201 Zeta201 commented Feb 17, 2026

Purpose

Describe the problems, issues, or needs driving this feature/fix and include links to related issues in the following format: Resolves issue1, issue2, etc.

Goals

Describe the solutions that this feature/fix will introduce to resolve the problems described above

Approach

Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here.

User stories

Summary of user stories addressed by this change>

Developer Checklist (Mandatory)

  • Complete the Developer Checklist in the related product-is issue to track any behavioral change or migration impact.

Release note

Brief description of the new feature or bug fix as it will appear in the release notes

Documentation

Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact

Training

Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable

Certification

Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why.

Marketing

Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable

Automation tests

  • Unit tests

    Code coverage information

  • Integration tests

    Details about the test cases and coverage

Security checks

Samples

Provide high-level details about the samples related to this feature

Related PRs

List any other related PRs

Migrations (if applicable)

Describe migration steps and platforms on which migration has been tested

Test environment

List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested

Learning

Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem.

Summary by CodeRabbit

  • Chores
    • Upgraded Java support to version 21 across build configs and CI workflows.
    • Updated CI actions and testing dependencies to newer releases.
    • Added/updated static-analysis tooling and adjusted build plugin configurations.
    • Simplified compiler plugin usage in sample/util modules and updated coverage tooling versions.
  • Tests
    • Refined test helpers to improve static state handling in unit tests.

@coderabbitai
Copy link

coderabbitai bot commented Feb 17, 2026

Warning

Rate limit exceeded

@Zeta201 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 25 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Upgrades CI toolchain to Java 21 and newer GitHub Actions, migrates FindBugs-related configuration toward SpotBugs, adjusts Maven plugin/dependency versions (including Mockito and Jacoco), removes module-level compiler plugin declarations, adds a SpotBugs exclude file, and changes test static-field reset logic.

Changes

Cohort / File(s) Summary
CI workflow updates
​.github/workflows/coverage-generator.yml, ​.github/workflows/pr-builder.yml
Updated GitHub Actions usage and step names; bumped Java toolchain inputs to JDK 21 and upgraded action versions (checkout, setup-java).
Top-level Maven build changes
pom.xml
Added/configured spotbugs-maven-plugin (pluginManagement + plugins), added a findbugs plugin block (executions set to none), updated bundle plugin version, bumped Java source/target to 21, updated Jacoco and Mockito version property names and values.
Module POM edits
modules/charon-core/pom.xml, modules/charon-samples/pom.xml, modules/charon-utils/pom.xml
Removed explicit maven-compiler-plugin declarations from module pom files; in charon-core changed Mockito test dependency from mockito-inlinemockito-core.
SpotBugs exclude file
modules/charon-core/spotbugs-exclude.xml
Added SpotBugs/FindBugs filter file containing a Match entry for package org.wso2.charon3.core.aParser.
Test changes for static fields
modules/charon-core/src/test/java/.../SCIMSystemSchemaExtensionBuilderTest.java
Replaced previous reflection-based static reset helper with Unsafe-based setter and map-clearing helpers; adjusted test setup to use new helpers.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through POMs and CI streams,
Switched to Java twenty-one in dreams,
SpotBugs tucked a tiny exclude sheet,
Tests now nudge fields with Unsafe feet,
A little hop, a build refreshed — hooray! 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description contains only the template structure with placeholder prompts and no actual implementation details, causing all sections to be incomplete or unfilled. Fill in all required sections with specific details: describe the problem and related issues, explain the goals, detail the implementation approach, provide test results and coverage information, add links to documentation, and confirm security checks and test environments.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: upgrading Java compilation support from version 8/11 to Java 21 across workflows and build configurations.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

@codecov
Copy link

codecov bot commented Feb 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 31.78%. Comparing base (f93447d) to head (a06eb46).
⚠️ Report is 3 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##             master     #453   +/-   ##
=========================================
  Coverage     31.78%   31.78%           
+ Complexity     1116     1114    -2     
=========================================
  Files           137      137           
  Lines         13551    13553    +2     
  Branches       2599     2599           
=========================================
+ Hits           4307     4308    +1     
- Misses         8712     8713    +1     
  Partials        532      532           
Flag Coverage Δ
unit 31.07% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

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

⚠️ Outside diff range comments (5)
modules/charon-core/src/test/java/org/wso2/charon3/core/config/SCIMSystemSchemaExtensionBuilderTest.java (1)

113-113: ⚠️ Potential issue | 🟡 Minor

Assertion message says "2 entries" but the expected count is 3.

The message string is inconsistent with the actual assertion value, which will be confusing on test failure.

🔧 Proposed fix
-        assertEquals(extensionConfig.size(), 3, "The extensionConfig map should contain 2 entries.");
+        assertEquals(extensionConfig.size(), 3, "The extensionConfig map should contain 3 entries.");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@modules/charon-core/src/test/java/org/wso2/charon3/core/config/SCIMSystemSchemaExtensionBuilderTest.java`
at line 113, Update the failing assertion message in
SCIMSystemSchemaExtensionBuilderTest so it matches the expected count: replace
the incorrect string "The extensionConfig map should contain 2 entries." used in
the assertEquals call that compares extensionConfig.size() to 3 with a message
that says "The extensionConfig map should contain 3 entries." (or use a dynamic
message referencing extensionConfig.size()) so the assertion message and
expected value are consistent.
modules/charon-core/pom.xml (1)

126-195: ⚠️ Potential issue | 🟠 Major

Duplicate jacoco-maven-plugin declarations in <plugins>.

There are two jacoco-maven-plugin plugin blocks (lines 126–176 and 177–195). Maven's last-declaration-wins behavior means the first block — which includes prepare-agent-integration, report-integration, and check goals — is effectively dead configuration. If those goals are needed, this is a silent regression; if not, the first block should be removed to avoid confusion.

♻️ Suggested fix — keep only one declaration

Remove lines 126–176 (the first declaration) if the integration/check goals are not needed, or merge the two blocks into one if they are.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/charon-core/pom.xml` around lines 126 - 195, The POM contains
duplicate jacoco-maven-plugin blocks which causes the first declaration (with
executions id default-prepare-agent, default-prepare-agent-integration,
default-report, default-report-integration, default-check) to be ignored; either
remove the redundant first plugin block or merge its needed executions
(prepare-agent-integration, report-integration, check) into the remaining
jacoco-maven-plugin definition so all required goals are declared once under a
single plugin entry.
pom.xml (2)

281-337: ⚠️ Potential issue | 🟠 Major

Triplicate jacoco-maven-plugin in <pluginManagement>.

Three identical jacoco-maven-plugin blocks appear in pluginManagement (lines 281–299, 300–318, 319–337). Only one is needed — the last one wins, making the first two dead configuration. This adds significant noise and maintenance burden.

♻️ Proposed fix — keep one declaration

Remove the first two blocks (lines 281–318) and keep only one:

-            <plugin>
-                <groupId>org.jacoco</groupId>
-                <artifactId>jacoco-maven-plugin</artifactId>
-                <version>${jacoco.version}</version>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>prepare-agent</goal>
-                        </goals>
-                    </execution>
-                    <execution>
-                        <id>report</id>
-                        <phase>test</phase>
-                        <goals>
-                            <goal>report</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-                <plugin>
-                <groupId>org.jacoco</groupId>
-                <artifactId>jacoco-maven-plugin</artifactId>
-                <version>${jacoco.version}</version>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>prepare-agent</goal>
-                        </goals>
-                    </execution>
-                    <execution>
-                        <id>report</id>
-                        <phase>test</phase>
-                        <goals>
-                            <goal>report</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
                 <plugin>
                     <groupId>org.jacoco</groupId>
                     <artifactId>jacoco-maven-plugin</artifactId>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pom.xml` around lines 281 - 337, The pom contains three identical
jacoco-maven-plugin declarations under pluginManagement; remove the duplicate
blocks and keep a single jacoco-maven-plugin entry (the one with artifactId
jacoco-maven-plugin and the executions prepare-agent + report) so only one
pluginManagement declaration for jacoco remains, eliminating the redundant
copies.

135-149: ⚠️ Potential issue | 🟠 Major

Triplicate jacoco-maven-plugin dependency in <dependencyManagement>.

The jacoco-maven-plugin dependency is declared three times (lines 135–139, 140–144, 145–149) with the same GAV. Only one declaration is needed. Additionally, jacoco-maven-plugin is a Maven plugin — declaring it as a <dependency> (rather than only as a <plugin>) is unusual and typically unnecessary unless it's used for programmatic access.

♻️ Proposed fix — deduplicate
             <dependency>
                 <groupId>org.jacoco</groupId>
                 <artifactId>jacoco-maven-plugin</artifactId>
                 <version>${jacoco.version}</version>
             </dependency>
-            <dependency>
-                <groupId>org.jacoco</groupId>
-                <artifactId>jacoco-maven-plugin</artifactId>
-                <version>${jacoco.version}</version>
-            </dependency>
-                <dependency>
-                <groupId>org.jacoco</groupId>
-                <artifactId>jacoco-maven-plugin</artifactId>
-                <version>${jacoco.version}</version>
-            </dependency>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pom.xml` around lines 135 - 149, The pom currently declares the same
dependency three times under dependencyManagement for
org.jacoco:jacoco-maven-plugin; remove the duplicate entries so there is only a
single declaration (or remove the dependency entirely if you intend to manage it
only as a Maven plugin). Locate the repeated <dependency> blocks for artifactId
jacoco-maven-plugin and either keep one or delete them all and instead declare
jacoco-maven-plugin under <build><plugins> as a <plugin> (artifactId
jacoco-maven-plugin) if you need plugin behavior; ensure no duplicate entries
remain in dependencyManagement.
.github/workflows/pr-builder.yml (1)

39-55: ⚠️ Potential issue | 🟠 Major

Duplicate "Generate coverage report" and "Upload coverage reports" steps.

Lines 41–46 and 47–54 duplicate the coverage report generation and Codecov upload. The first upload (lines 43–46) lacks files and flags, so it will scan and upload all reports found, while the second (lines 50–54) targets a specific file with the unit flag. Running mvn test twice is also wasteful since tests already ran in mvn clean install on Line 40.

Remove the duplicate steps and keep only the targeted upload:

🐛 Proposed fix
       - name: Build with Maven
         run: mvn clean install -U -B
       - name: Generate coverage report
         run: mvn test jacoco:report
-      - name: Upload coverage reports to Codecov
-        uses: codecov/codecov-action@v4
-        with:
-          token: ${{ secrets.CODECOV_TOKEN }}
-      - name: Generate coverage report
-        run: mvn test jacoco:report
-
       - name: Upload coverage reports to Codecov
         uses: codecov/codecov-action@v4
         with:
           token: ${{ secrets.CODECOV_TOKEN }}
-          files : target/site/jacoco/jacoco.xml
+          files: target/site/jacoco/jacoco.xml
           flags: unit
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr-builder.yml around lines 39 - 55, Remove the duplicated
Jacoco/report and Codecov steps: delete the first "Generate coverage report" run
(mvn test jacoco:report) and the first "Upload coverage reports to Codecov"
action that lacks files/flags, leaving a single jacoco report generation and a
single codecov/codecov-action@v4 step; keep the upload step that includes files:
target/site/jacoco/jacoco.xml and flags: unit so tests from the earlier mvn
clean install are not re-run and only the targeted report is uploaded.
🧹 Nitpick comments (2)
.github/workflows/pr-builder.yml (1)

29-29: Inconsistent actions/cache version — v3 here vs v4 in coverage-generator.yml.

Consider upgrading to actions/cache@v4 for consistency with the other workflow file.

♻️ Proposed fix
-        uses: actions/cache@v3
+        uses: actions/cache@v4
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr-builder.yml at line 29, The workflow uses the older
cache action version "uses: actions/cache@v3" which is inconsistent with
coverage-generator.yml; update that uses entry to "actions/cache@v4" so both
workflows match—locate the line containing "uses: actions/cache@v3" in the
pr-builder workflow and change the version to `@v4`.
pom.xml (1)

461-462: Upgrade maven-surefire-plugin to 3.x for Java 21 compatibility.

Version 2.22.0 (2018) predates Java Platform Module System maturity and has known incompatibilities with Java 21, including module patching failures and outdated JUnit Platform integration (junit-platform-launcher 1.3.1, Byte Buddy 1.8.x). Since the project targets Java 21 and this property is used in modules/charon-core/pom.xml, upgrading to 3.5.4 or later is recommended.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pom.xml` around lines 461 - 462, The pom property
maven.surefire.plugin.version is set to 2.22.0 which is incompatible with Java
21; update this property to a 3.x release (recommend 3.5.4 or later) so the
modules (e.g., modules/charon-core/pom.xml) that reference
${maven.surefire.plugin.version} will pick up the Java‑21-compatible surefire
plugin; ensure any pluginManagement or direct plugin declarations that hardcode
the older version are similarly updated or rely on the updated property.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/coverage-generator.yml:
- Around line 17-21: The workflow step named "Set up Adopt JDK 21" uses
actions/setup-java@v4 with distribution "adopt" which doesn't provide JDK 21;
change the distribution value to "temurin" so the setup-java action can install
JDK 21 (update the distribution string from "adopt" to "temurin" in the step
that uses actions/setup-java@v4).

In @.github/workflows/pr-builder.yml:
- Around line 22-26: The workflow step named "Set up Adopt JDK 21" uses
actions/setup-java@v4 with distribution: "adopt", but JDK 21 isn't available
under that distribution; update the step (the block with name "Set up Adopt JDK
21" and the uses: actions/setup-java@v4 configuration) to set with:
java-version: 21 and distribution: "temurin" (and optionally rename the step to
"Set up Temurin JDK 21" for clarity).

In `@modules/charon-core/spotbugs-exclude.xml`:
- Around line 1-5: The XML root element is incorrect: change the top-level
<spotbugs> element to <FindBugsFilter> so the SpotBugs filter file is parsable
by spotbugs-maven-plugin; keep the existing <Match> and <Package
name="org.wso2.charon3.core.aParser" /> content intact under the new
<FindBugsFilter> root.

In
`@modules/charon-core/src/test/java/org/wso2/charon3/core/config/SCIMSystemSchemaExtensionBuilderTest.java`:
- Around line 173-179: The helper clearStaticMapField in
SCIMSystemSchemaExtensionBuilderTest directly casts field.get(null) to Map and
calls clear(), which can NPE if the static field is uninitialized; update
clearStaticMapField to retrieve the value via Field.get(null), check for null
before casting/clearing, and if you need the map cleared ensure initialization
(e.g., set a new HashMap into the static field using field.set(null, new
HashMap<>()) or simply return when null). Reference: method clearStaticMapField
and class SCIMSystemSchemaExtensionBuilder.
- Around line 181-191: The assertion message in
SCIMSystemSchemaExtensionBuilderTest is wrong: update the message text used in
the failing assertion (the one that reads "The extensionConfig map should
contain 2 entries.") to reflect the actual expected size 3 so it matches the
assert checking size() == 3; locate the assertion in the test (around line 113)
and change the literal message to "The extensionConfig map should contain 3
entries." Also leave the setStaticField helper (which uses sun.misc.Unsafe)
as-is for test-only manipulation of static/final fields or, if you must avoid
internal APIs long-term, add a package-private reset method to
SCIMSystemSchemaExtensionBuilder instead.

In `@pom.xml`:
- Around line 469-470: The pom.xml defines the Maven property jacoco.version
twice (both set to 0.8.12); remove the duplicate declaration so there is only a
single <jacoco.version> property to avoid future divergence — locate both
occurrences of the property name jacoco.version in the properties block and
delete the redundant one (keep the original or the one in the canonical
properties section), ensuring no other property names are changed and references
to jacoco.version remain intact.
- Around line 353-365: The pom currently disables findbugs by binding
findbugs-maven-plugin executions to phase:none but only declares
spotbugs-maven-plugin inside pluginManagement, so SpotBugs never runs; to fix,
add the spotbugs-maven-plugin entry from pluginManagement into the active
<build><plugins> section (mirror the configuration and executions you want to
run) so spotbugs-maven-plugin becomes an active plugin for the project, leaving
findbugs-maven-plugin executions unchanged or removed as desired.

---

Outside diff comments:
In @.github/workflows/pr-builder.yml:
- Around line 39-55: Remove the duplicated Jacoco/report and Codecov steps:
delete the first "Generate coverage report" run (mvn test jacoco:report) and the
first "Upload coverage reports to Codecov" action that lacks files/flags,
leaving a single jacoco report generation and a single codecov/codecov-action@v4
step; keep the upload step that includes files: target/site/jacoco/jacoco.xml
and flags: unit so tests from the earlier mvn clean install are not re-run and
only the targeted report is uploaded.

In `@modules/charon-core/pom.xml`:
- Around line 126-195: The POM contains duplicate jacoco-maven-plugin blocks
which causes the first declaration (with executions id default-prepare-agent,
default-prepare-agent-integration, default-report, default-report-integration,
default-check) to be ignored; either remove the redundant first plugin block or
merge its needed executions (prepare-agent-integration, report-integration,
check) into the remaining jacoco-maven-plugin definition so all required goals
are declared once under a single plugin entry.

In
`@modules/charon-core/src/test/java/org/wso2/charon3/core/config/SCIMSystemSchemaExtensionBuilderTest.java`:
- Line 113: Update the failing assertion message in
SCIMSystemSchemaExtensionBuilderTest so it matches the expected count: replace
the incorrect string "The extensionConfig map should contain 2 entries." used in
the assertEquals call that compares extensionConfig.size() to 3 with a message
that says "The extensionConfig map should contain 3 entries." (or use a dynamic
message referencing extensionConfig.size()) so the assertion message and
expected value are consistent.

In `@pom.xml`:
- Around line 281-337: The pom contains three identical jacoco-maven-plugin
declarations under pluginManagement; remove the duplicate blocks and keep a
single jacoco-maven-plugin entry (the one with artifactId jacoco-maven-plugin
and the executions prepare-agent + report) so only one pluginManagement
declaration for jacoco remains, eliminating the redundant copies.
- Around line 135-149: The pom currently declares the same dependency three
times under dependencyManagement for org.jacoco:jacoco-maven-plugin; remove the
duplicate entries so there is only a single declaration (or remove the
dependency entirely if you intend to manage it only as a Maven plugin). Locate
the repeated <dependency> blocks for artifactId jacoco-maven-plugin and either
keep one or delete them all and instead declare jacoco-maven-plugin under
<build><plugins> as a <plugin> (artifactId jacoco-maven-plugin) if you need
plugin behavior; ensure no duplicate entries remain in dependencyManagement.

---

Nitpick comments:
In @.github/workflows/pr-builder.yml:
- Line 29: The workflow uses the older cache action version "uses:
actions/cache@v3" which is inconsistent with coverage-generator.yml; update that
uses entry to "actions/cache@v4" so both workflows match—locate the line
containing "uses: actions/cache@v3" in the pr-builder workflow and change the
version to `@v4`.

In `@pom.xml`:
- Around line 461-462: The pom property maven.surefire.plugin.version is set to
2.22.0 which is incompatible with Java 21; update this property to a 3.x release
(recommend 3.5.4 or later) so the modules (e.g., modules/charon-core/pom.xml)
that reference ${maven.surefire.plugin.version} will pick up the
Java‑21-compatible surefire plugin; ensure any pluginManagement or direct plugin
declarations that hardcode the older version are similarly updated or rely on
the updated property.

Comment on lines +17 to 21
- name: Set up Adopt JDK 21
uses: actions/setup-java@v4
with:
java-version: 11
java-version: 21
distribution: "adopt"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

actions/setup-java adopt distribution JDK 21 support

💡 Result:

actions/setup-java still accepts distribution: adopt / adopt-hotspot (and adopt-openj9), but AdoptOpenJDK is no longer updated (it moved to Eclipse Adoptium), so you should not rely on it for JDK 21—use temurin for HotSpot JDK 21 (or semeru for OpenJ9) instead. [1], [2]

Example:

- uses: actions/setup-java@v5
  with:
    distribution: temurin
    java-version: '21'
``` [1]

---

🌐 Web query:

`AdoptOpenJDK JDK 21 available latest version`

💡 Result:

AdoptOpenJDK builds are now published under **Eclipse Temurin (Adoptium)**.

As of **February 17, 2026**, the latest available **JDK 21 (LTS)** release is:

- **Eclipse Temurin 21.0.10+7** (announced **February 5, 2026**) [1]  
  (Also reflected by downstream package metadata such as Homebrew’s `temurin@21` cask showing **21.0.10,7**.) [2]

**Download:** use the Adoptium/Temurin downloads (or their API), not the old AdoptOpenJDK site. [1]

**Sources:** [1] ([adoptium.net](https://adoptium.net/news/2026/02/eclipse-temurin-8u482-11030-17018-21010-2502-available/?utm_source=openai)), [2] ([formulae.brew.sh](https://formulae.brew.sh/cask/temurin%4021?utm_source=openai))

Citations:

- 1: https://adoptium.net/news/2026/02/eclipse-temurin-8u482-11030-17018-21010-2502-available/?utm_source=openai
- 2: https://formulae.brew.sh/cask/temurin%4021?utm_source=openai

---

🌐 Web query:

`Eclipse Temurin JDK 21 actions/setup-java`

💡 Result:

To set up **Eclipse Temurin JDK 21** in GitHub Actions with **`actions/setup-java`**, use `distribution: temurin` and `java-version: 21` (recommended: `@v5`). ([github.com](https://github.com/actions/setup-java?utm_source=openai))

```yaml
steps:
  - uses: actions/checkout@v5
  - uses: actions/setup-java@v5
    with:
      distribution: temurin
      java-version: '21'
  - run: java -version

Optional (dependency caching + always fetch latest matching JDK build): (github.com)

- uses: actions/setup-java@v5
  with:
    distribution: temurin
    java-version: '21'
    cache: gradle   # or: maven / sbt
    check-latest: true

Citations:


Change adopt distribution to temurin—JDK 21 is not available from AdoptOpenJDK.

AdoptOpenJDK is no longer maintained and has not released builds since JDK 16. JDK 21 is only available from Eclipse Temurin (the Adoptium successor). The workflow will fail trying to locate JDK 21 with the adopt distribution.

🐛 Proposed fix
-      - name: Set up Adopt JDK 21
+      - name: Set up Temurin JDK 21
         uses: actions/setup-java@v4
         with:
           java-version: 21
-          distribution: "adopt"
+          distribution: "temurin"
📝 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
- name: Set up Adopt JDK 21
uses: actions/setup-java@v4
with:
java-version: 11
java-version: 21
distribution: "adopt"
- name: Set up Temurin JDK 21
uses: actions/setup-java@v4
with:
java-version: 21
distribution: "temurin"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/coverage-generator.yml around lines 17 - 21, The workflow
step named "Set up Adopt JDK 21" uses actions/setup-java@v4 with distribution
"adopt" which doesn't provide JDK 21; change the distribution value to "temurin"
so the setup-java action can install JDK 21 (update the distribution string from
"adopt" to "temurin" in the step that uses actions/setup-java@v4).

Comment on lines +22 to 26
- name: Set up Adopt JDK 21
uses: actions/setup-java@v4
with:
java-version: "8"
java-version: 21
distribution: "adopt"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Same adopt distribution issue — JDK 21 is not available under adopt.

Same as in coverage-generator.yml: use temurin instead of adopt for JDK 21.

🐛 Proposed fix
-      - name: Set up Adopt JDK 21
-        uses: actions/setup-java@v4
+      - name: Set up Temurin JDK 21
+        uses: actions/setup-java@v4
         with:
           java-version: 21
-          distribution: "adopt"
+          distribution: "temurin"
📝 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
- name: Set up Adopt JDK 21
uses: actions/setup-java@v4
with:
java-version: "8"
java-version: 21
distribution: "adopt"
- name: Set up Temurin JDK 21
uses: actions/setup-java@v4
with:
java-version: 21
distribution: "temurin"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr-builder.yml around lines 22 - 26, The workflow step
named "Set up Adopt JDK 21" uses actions/setup-java@v4 with distribution:
"adopt", but JDK 21 isn't available under that distribution; update the step
(the block with name "Set up Adopt JDK 21" and the uses: actions/setup-java@v4
configuration) to set with: java-version: 21 and distribution: "temurin" (and
optionally rename the step to "Set up Temurin JDK 21" for clarity).

Comment on lines +173 to +179
@SuppressWarnings("unchecked")
private void clearStaticMapField(String fieldName) throws NoSuchFieldException, IllegalAccessException {

Field field = SCIMSystemSchemaExtensionBuilder.class.getDeclaredField(fieldName);
field.setAccessible(true);
((Map<?, ?>) field.get(null)).clear();
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Potential NullPointerException if the static map field is null.

field.get(null) is cast directly to Map and .clear() is called without a null guard. If the field hasn't been initialized yet (e.g., due to a class-loading order change), this will throw an NPE.

🛡️ Proposed fix
     private void clearStaticMapField(String fieldName) throws NoSuchFieldException, IllegalAccessException {
 
         Field field = SCIMSystemSchemaExtensionBuilder.class.getDeclaredField(fieldName);
         field.setAccessible(true);
-        ((Map<?, ?>) field.get(null)).clear();
+        Map<?, ?> map = (Map<?, ?>) field.get(null);
+        if (map != null) {
+            map.clear();
+        }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@modules/charon-core/src/test/java/org/wso2/charon3/core/config/SCIMSystemSchemaExtensionBuilderTest.java`
around lines 173 - 179, The helper clearStaticMapField in
SCIMSystemSchemaExtensionBuilderTest directly casts field.get(null) to Map and
calls clear(), which can NPE if the static field is uninitialized; update
clearStaticMapField to retrieve the value via Field.get(null), check for null
before casting/clearing, and if you need the map cleared ensure initialization
(e.g., set a new HashMap into the static field using field.set(null, new
HashMap<>()) or simply return when null). Reference: method clearStaticMapField
and class SCIMSystemSchemaExtensionBuilder.

Comment on lines +181 to 191
private void setStaticField(String fieldName, Object newValue) throws NoSuchFieldException,
IllegalAccessException {

field.set(null, newValue);
Field unsafeField = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
sun.misc.Unsafe unsafe = (sun.misc.Unsafe) unsafeField.get(null);

Field field = SCIMSystemSchemaExtensionBuilder.class.getDeclaredField(fieldName);
long offset = unsafe.staticFieldOffset(field);
unsafe.putObject(SCIMSystemSchemaExtensionBuilder.class, offset, newValue);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the full test file to understand the context and check line 113
cd modules/charon-core && find . -name "SCIMSystemSchemaExtensionBuilderTest.java" -type f

Repository: wso2/charon

Length of output: 141


🌐 Web query:

Java 21 sun.misc.Unsafe deprecation removal JEP 471

💡 Result:

In Java 21 (JDK 21), JEP 471 is not present—so there is no new “deprecated for removal” change in sun.misc.Unsafe specifically due to JEP 471 in that release.

What JEP 471 actually does (and when):

  • JEP 471 = “Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal” and its release target is JDK 23 (status: Delivered). It deprecates (for removal) the memory-access methods in sun.misc.Unsafe (on-heap, off-heap, and “bimodal”), but does not remove them yet. It also introduces the launcher option --sun-misc-unsafe-memory-access={allow|warn|debug|deny} (default allow in JDK 23). [1], [2]

  • The JEP describes a phased plan: (1) deprecate (JDK 23), (2) runtime warnings (planned “in or before JDK 25”), (3) exceptions by default (JDK 26 or later), then eventual removal in releases following JDK 26. [1]

Related follow-up:

  • JEP 498 is the follow-up that adds runtime warnings upon first use, and it was targeted to / delivered in JDK 24. [3]

Sources:
[1] https://openjdk.org/jeps/471
[2] https://mail.openjdk.org/pipermail/core-libs-dev/2024-May/123193.html
[3] https://inside.java/2024/11/28/jep498-target-jdk24/


🌐 Web query:

Java VarHandle set static final field test

💡 Result:

To test that a static final field cannot be mutated via VarHandle, assert that the write access mode is unsupported and that set(...) throws UnsupportedOperationException (because VarHandles treat final fields as read-only). [1][2]

import static org.junit.jupiter.api.Assertions.*;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import org.junit.jupiter.api.Test;

class VarHandleStaticFinalTest {

  static class C {
    static final int X = 1;
  }

  `@Test`
  void cannotSetStaticFinalViaVarHandle() throws Throwable {
    VarHandle vh = MethodHandles.lookup()
        .findStaticVarHandle(C.class, "X", int.class); // ok to obtain [2]

    assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); // final => no write modes [1][2]
    assertThrows(UnsupportedOperationException.class, () -> vh.set(2)); // write throws UOE [1]
    assertEquals(1, (int) vh.get()); // reads still work [1]
  }
}

Notes

  • This is by design: if a VarHandle references a final field, write/atomic update modes are unsupported and throw UnsupportedOperationException. [1][2]

Sources: VarHandle spec (final fields are read-only for VarHandle write/update modes) [1]; MethodHandles.Lookup.findStaticVarHandle (final fields => write/update modes unsupported) [2].


🏁 Script executed:

# Read the test file to check line 113 and the full context of the methods
cat -n modules/charon-core/src/test/java/org/wso2/charon3/core/config/SCIMSystemSchemaExtensionBuilderTest.java | sed -n '100,200p'

Repository: wso2/charon

Length of output: 5543


Fix assertion message on line 113 — expected size is 3, not 2.

Line 113 states "The extensionConfig map should contain 2 entries." but asserts size() == 3. Update the message to match the expected count.

Regarding sun.misc.Unsafe usage: This approach is pragmatic for test code. While sun.misc.Unsafe is targeted for deprecation in JDK 23 (not JDK 21), it remains functional and is a common pattern for manipulating static final fields in tests when reflection alone is insufficient. If Java 21+ compatibility without internal APIs is a strict requirement, refactor the production code to provide a test-friendly reset mechanism (e.g., a package-private reset method on SCIMSystemSchemaExtensionBuilder). VarHandle is not a viable alternative here because it intentionally prevents writes to final fields by design.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@modules/charon-core/src/test/java/org/wso2/charon3/core/config/SCIMSystemSchemaExtensionBuilderTest.java`
around lines 181 - 191, The assertion message in
SCIMSystemSchemaExtensionBuilderTest is wrong: update the message text used in
the failing assertion (the one that reads "The extensionConfig map should
contain 2 entries.") to reflect the actual expected size 3 so it matches the
assert checking size() == 3; locate the assertion in the test (around line 113)
and change the literal message to "The extensionConfig map should contain 3
entries." Also leave the setStaticField helper (which uses sun.misc.Unsafe)
as-is for test-only manipulation of static/final fields or, if you must avoid
internal APIs long-term, add a package-private reset method to
SCIMSystemSchemaExtensionBuilder instead.

Comment on lines +353 to +365
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<executions>
<execution>
<id>analyze-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>findbugs</id>
<phase>none</phase>
</execution>
</executions>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

FindBugs disabled correctly, but SpotBugs is not activated in <plugins>.

The findbugs-maven-plugin executions are correctly disabled by binding them to phase: none. However, the replacement spotbugs-maven-plugin is only declared in <pluginManagement> (lines 243–263), not in the active <plugins> section. This means SpotBugs will not run for any module unless that module explicitly adds the plugin. If the intent is to replace FindBugs project-wide, add SpotBugs to <build><plugins> as well.

♻️ Proposed fix — activate SpotBugs in build/plugins
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>findbugs-maven-plugin</artifactId>
                 <executions>
                     <execution>
                         <id>analyze-compile</id>
                         <phase>none</phase>
                     </execution>
                     <execution>
                         <id>findbugs</id>
                         <phase>none</phase>
                     </execution>
                 </executions>
             </plugin>
+            <plugin>
+                <groupId>com.github.spotbugs</groupId>
+                <artifactId>spotbugs-maven-plugin</artifactId>
+            </plugin>
📝 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
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<executions>
<execution>
<id>analyze-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>findbugs</id>
<phase>none</phase>
</execution>
</executions>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<executions>
<execution>
<id>analyze-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>findbugs</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
</plugin>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pom.xml` around lines 353 - 365, The pom currently disables findbugs by
binding findbugs-maven-plugin executions to phase:none but only declares
spotbugs-maven-plugin inside pluginManagement, so SpotBugs never runs; to fix,
add the spotbugs-maven-plugin entry from pluginManagement into the active
<build><plugins> section (mirror the configuration and executions you want to
run) so spotbugs-maven-plugin becomes an active plugin for the project, leaving
findbugs-maven-plugin executions unchanged or removed as desired.

Comment on lines +469 to +470
<jacoco.version>0.8.12</jacoco.version>
<mockito-core.version>5.3.1</mockito-core.version>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Duplicate jacoco.version property — defined on both Line 469 and Line 477.

The jacoco.version property is declared twice. While both currently have the same value (0.8.12), this is error-prone — a future update might change only one, causing subtle version mismatches.

♻️ Proposed fix — remove the duplicate
         <jacoco.version>0.8.12</jacoco.version>
         <mockito-core.version>5.3.1</mockito-core.version>
 
         <sonar.projectKey>wso2_charon</sonar.projectKey>
         <sonar.moduleKey>${artifactId}</sonar.moduleKey>
         <sonar.organization>wso2</sonar.organization>
         <sonar.host.url>https://sonarcloud.io</sonar.host.url>
-    
-        <jacoco.version>0.8.12</jacoco.version>
     </properties>

Also applies to: 477-477

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pom.xml` around lines 469 - 470, The pom.xml defines the Maven property
jacoco.version twice (both set to 0.8.12); remove the duplicate declaration so
there is only a single <jacoco.version> property to avoid future divergence —
locate both occurrences of the property name jacoco.version in the properties
block and delete the redundant one (keep the original or the one in the
canonical properties section), ensuring no other property names are changed and
references to jacoco.version remain intact.

@jenkins-is-staging
Copy link

PR builder started
Link: https://github.com/wso2/product-is/actions/runs/22207618615

@jenkins-is-staging
Copy link

PR builder completed
Link: https://github.com/wso2/product-is/actions/runs/22207618615
Status: success

Copy link

@jenkins-is-staging jenkins-is-staging left a comment

Choose a reason for hiding this comment

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

Approving the pull request based on the successful pr build https://github.com/wso2/product-is/actions/runs/22207618615

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