Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/coverage-generator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Adopt JDK 11
- name: Set up Adopt JDK 21
uses: actions/setup-java@v4
with:
java-version: 11
java-version: 21
distribution: "adopt"
Comment on lines +17 to 21
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).


- name: Build with Maven
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/pr-builder.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This workflow will build the project on pull requests with tests
# Uses:
# OS: ubuntu-latest
# JDK: Adopt JDK 8
# JDK: Adopt JDK 21

name: PR Builder

Expand All @@ -18,11 +18,11 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up Adopt JDK 8
uses: actions/setup-java@v3
- uses: actions/checkout@v4
- name: Set up Adopt JDK 21
uses: actions/setup-java@v4
with:
java-version: "8"
java-version: 21
distribution: "adopt"
Comment on lines +22 to 26
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).

- name: Cache local Maven repository
id: cache-maven-m2
Expand Down
5 changes: 0 additions & 5 deletions modules/charon-core/findbugs-exclude.xml

This file was deleted.

13 changes: 1 addition & 12 deletions modules/charon-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -90,17 +90,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<configuration>
<excludeFilterFile>findbugs-exclude.xml</excludeFilterFile>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public class CharonConfiguration implements Configuration {
//default count value for pagination
private int count;

private CharonConfiguration() {
}

/*
* set documentationURL
* @param documentationURL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public class SCIMAgentSchemaExtensionBuilder extends ExtensionBuilder {
private static final SCIMAgentSchemaExtensionBuilder INSTANCE = new SCIMAgentSchemaExtensionBuilder();
private static final String EXTENSION_ROOT_ATTRIBUTE_URI = AGENT_SCHEMA_URI;

private SCIMAgentSchemaExtensionBuilder() {

}

/**
* Get the instance of the SCIMAgentSchemaExtensionBuilder.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public class SCIMSystemSchemaExtensionBuilder extends ExtensionBuilder {
private static final String EXTENSION_ROOT_ATTRIBUTE_URI = SYSTEM_USER_SCHEMA_URI;
private static final String DELIMITER = "\\A";

private SCIMSystemSchemaExtensionBuilder() {

}

/**
* Get the instance of the SCIMSystemSchemaExtensionBuilder.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public class SCIMUserSchemaExtensionBuilder extends ExtensionBuilder {
// extension root attribute schema
private AttributeSchema extensionSchema = null;

private SCIMUserSchemaExtensionBuilder() {

}

public static SCIMUserSchemaExtensionBuilder getInstance() {
return configReader;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public class SCIMResourceSchemaManager {
private static SCIMResourceSchemaManager manager = new SCIMResourceSchemaManager();
private static final Logger log = LoggerFactory.getLogger(SCIMResourceSchemaManager.class);

private SCIMResourceSchemaManager() {

}

public static SCIMResourceSchemaManager getInstance() {
return manager;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import static org.testng.Assert.assertEquals;
Expand Down Expand Up @@ -163,26 +162,32 @@ void setUp() throws NoSuchFieldException, IllegalAccessException, NoSuchMethodEx
constructor.setAccessible(true);
SCIMSystemSchemaExtensionBuilder newBuilderInstance = constructor.newInstance();

resetSingletonField("EXTENSION_ROOT_ATTRIBUTE_URI", SYSTEM_USER_SCHEMA_URI);
resetSingletonField("instance", newBuilderInstance);
resetSingletonField("extensionConfig", new HashMap<>());
resetSingletonField("attributeSchemas", new HashMap<>());
setStaticField("instance", newBuilderInstance);
clearStaticMapField("extensionConfig");
clearStaticMapField("attributeSchemas");

setInstanceField("extensionSchema", null);
setInstanceField("extensionRootAttributeName", null);
}

private void resetSingletonField(String fieldName, Object newValue) throws NoSuchFieldException,
IllegalAccessException {
@SuppressWarnings("unchecked")
private void clearStaticMapField(String fieldName) throws NoSuchFieldException, IllegalAccessException {

Field field = SCIMSystemSchemaExtensionBuilder.class.getDeclaredField(fieldName);
field.setAccessible(true);
((Map<?, ?>) field.get(null)).clear();
}
Comment on lines +173 to +179
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.


Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~java.lang.reflect.Modifier.FINAL);
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);
}
Comment on lines +181 to 191
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.


private void setInstanceField(String fieldName, Object value) throws NoSuchFieldException,
Expand Down
5 changes: 0 additions & 5 deletions modules/charon-samples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
Expand Down
4 changes: 0 additions & 4 deletions modules/charon-utils/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,6 @@

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
Expand Down
55 changes: 47 additions & 8 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>${mockito.version}</version>
<artifactId>mockito-core</artifactId>
<version>${mockito-core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -239,6 +239,27 @@
<SCM-Revision>${buildNumber}</SCM-Revision>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>${spotbugs-maven-plugin.version}</version>
<configuration>
<excludeFilterFile>spotbugs-exclude.xml</excludeFilterFile>
<effort>Max</effort>
<threshold>Low</threshold>
<failOnError>true</failOnError>
<maxHeap>1024</maxHeap>
</configuration>
<executions>
<execution>
<id>analyze-compile</id>
<phase>compile</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
Expand Down Expand Up @@ -328,6 +349,24 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
</plugin>
<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>
Comment on lines +353 to +365
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.

</plugin>
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
Expand Down Expand Up @@ -410,29 +449,29 @@
<compiler.plugin.version>3.8.1</compiler.plugin.version>

<war.plugin.version>3.2.3</war.plugin.version>
<bundle.plugin.version>4.2.0</bundle.plugin.version>
<bundle.plugin.version>5.1.9</bundle.plugin.version>

<maven.buildnumber.plugin.version>1.4</maven.buildnumber.plugin.version>

<src.java.version>1.8</src.java.version>
<target.java.version>1.8</target.java.version>
<src.java.version>21</src.java.version>
<target.java.version>21</target.java.version>

<msf4j.version>2.7.3</msf4j.version>
<fasterxml.jackson.core.version>2.12.6.1</fasterxml.jackson.core.version>
<commons.lang.version>2.6</commons.lang.version>
<commons-lang.wso2.osgi.version.range>[2.6.0, 3.0.0)</commons-lang.wso2.osgi.version.range>

<slf4j.version>1.7.26</slf4j.version>
<maven.findbugsplugin.version>3.0.4</maven.findbugsplugin.version>
<spotbugs-maven-plugin.version>4.9.8.2</spotbugs-maven-plugin.version>
<maven.surefire.plugin.version>2.22.0</maven.surefire.plugin.version>

<!-- Pax Logging Version -->
<pax.logging.api.version>1.10.1</pax.logging.api.version>

<log4j.api.version>2.12.0</log4j.api.version>
<testng.version>6.9.10</testng.version>
<jacoco.version>0.8.6</jacoco.version>
<mockito.version>3.10.0</mockito.version>
<jacoco.version>0.8.12</jacoco.version>
<mockito-core.version>5.3.1</mockito-core.version>
Comment on lines +473 to +474
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.


<sonar.projectKey>wso2_charon</sonar.projectKey>
<sonar.moduleKey>${artifactId}</sonar.moduleKey>
Expand Down
45 changes: 45 additions & 0 deletions spotbugs-exclude.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!--
~ Copyright (c) 2026, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->

<FindBugsFilter>
<!-- Exclude generated parser code -->
<Match>
<Package name="org.wso2.charon3.core.aParser" />
</Match>

<Match>
<Bug pattern="EI_EXPOSE_REP,EI_EXPOSE_REP2" />
</Match>

<Match>
<Bug pattern="MS_EXPOSE_REP" />
</Match>

<Match>
<Bug pattern="CT_CONSTRUCTOR_THROW" />
</Match>

<Match>
<Bug pattern="REFLC_REFLECTION_MAY_INCREASE_ACCESSIBILITY_OF_CLASS" />
</Match>

<Match>
<Bug pattern="UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" />
</Match>
</FindBugsFilter>