diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1110.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1110.json index 2b607b5003f..87cbe8691bb 100644 --- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1110.json +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1110.json @@ -1,23 +1,25 @@ { - "title": "Redundant pairs of parentheses should be removed", + "title": "Unnecessary parentheses should be removed", "type": "CODE_SMELL", - "code": { - "impacts": { - "MAINTAINABILITY": "MEDIUM" - }, - "attribute": "CLEAR" - }, "status": "ready", "remediation": { "func": "Constant\/Issue", - "constantCost": "1min" + "constantCost": "2 min" }, "tags": [ - "confusing" + "clippy", + "redundant", + "readability" ], - "defaultSeverity": "Major", + "defaultSeverity": "Minor", "ruleSpecification": "RSPEC-1110", "sqKey": "S1110", "scope": "All", - "quickfix": "unknown" + "quickfix": "unknown", + "code": { + "impacts": { + "MAINTAINABILITY": "LOW" + }, + "attribute": "CLEAR" + } } diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S2206.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S2206.json index 3e6c2d30eb9..a7c838a29c4 100644 --- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S2206.json +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S2206.json @@ -1,5 +1,5 @@ { - "title": "Either fields or getters should be annotated for persistence but not both", + "title": "Do not mix field and getter persistence annotations", "type": "BUG", "status": "ready", "remediation": { diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S2654.html b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S2654.html index 7f2832d9391..5b6762cbe6c 100644 --- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S2654.html +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S2654.html @@ -1,18 +1,106 @@

Why is this an issue?

-

Proper synchronization and thread management can be tricky under the best of circumstances, but it’s particularly difficult in JEE application, and -is even forbidden under some circumstances by the JEE standard.

-

This rule raises an issue for each Runnable, and use of the synchronized keyword.

-

Noncompliant code example

-
-public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-  // ...
-
-  Runnable r = new Runnable() {  // Noncompliant
-    public void run() {
+

Proper synchronization and thread management can be tricky under the best of circumstances, but it’s particularly difficult in Jakarta EE +application, and is even forbidden under some circumstances by the Jakarta EE standard.

+

This rule raises an issue for each Runnable, and use of the synchronized keyword in Jakarta EE applications.

+

How to fix it

+

Instead of creating unmanaged threads, use the Concurrency Utilities for Jakarta EE. Injecting a ManagedExecutorService lets the +container manage the thread pool and preserves the container context (CDI, security, transactions). If you are using EJBs, annotate a method with +@Asynchronous to run it in a container-managed background thread, with no need to manage threads or submit tasks explicitly.

+

For shared mutable state that would otherwise require synchronized, use container-managed concurrency instead. In EJBs, the container +serializes access to @Singleton beans by default (via @Lock(WRITE)), eliminating the need for explicit synchronization. +Outside EJBs, use the concurrency utilities from java.util.concurrent such as AtomicInteger or +ConcurrentHashMap, which are safe to use in Jakarta EE.

+

Code examples

+

Noncompliant code example

+
+@RequestScoped
+public class DataProcessor {
+
+  public void processData() {
+    Runnable task = () -> { // Noncompliant
+      // ...
+    };
+    new Thread(task).start();
+  }
+}
+
+

Compliant solution

+

Using ManagedExecutorService

+
+@RequestScoped
+public class DataProcessor {
+
+  @Resource
+  private ManagedExecutorService executor;
+
+  public void processData() {
+    executor.submit(() -> { // Compliant
       // ...
-    }
-  };
-  new Thread(r).start();
+    });
+  }
+}
+
+

Noncompliant code example

+
+@Stateless
+public class OrderService {
+
+  public void dispatchOrder(Long orderId) {
+    Runnable r = new Runnable() { // Noncompliant
+      public void run() {
+        // ...
+      }
+    };
+    new Thread(r).start();
+  }
+}
+
+

Compliant solution

+

Using @Asynchronous

+
+@Stateless
+public class OrderService {
+
+  @Asynchronous // Compliant
+  public void dispatchOrder(Long orderId) {
+    // ...
+  }
+}
+
+

Noncompliant code example

+
+@Singleton
+public class CounterService {
+
+  private int count = 0;
+
+  public synchronized void increment() { // Noncompliant
+    count++;
+  }
+
+  public synchronized int getCount() { // Noncompliant
+    return count;
+  }
+}
+
+

Compliant solution

+

Using @Singleton with @Lock(…​)

+
+@Singleton
+public class CounterService {
+
+  private int count = 0;
+
+  @Lock(LockType.WRITE) // Compliant - container manages concurrency
+  public void increment() {
+    count++;
+  }
+
+  @Lock(LockType.READ) // Compliant
+  public int getCount() {
+    return count;
+  }
+}
 

Resources

-

It is also possible to use AES-CBC with HMAC for integrity checks. However, it is considered more straightforward to use AES-GCM directly -instead.

For RSA: use the OAEP scheme

The Optimal Asymmetric Encryption Padding scheme (OAEP) adds randomness and a secure hash function that strengthens the regular inner workings of RSA.

Resources

Articles & blog posts

+
+

Implementation Specification

+

(visible only on this page)

+

Message

+

Use a static import for "{method name}".

+

Highlighting

+ + diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8924.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8924.json index 18d1e1fc381..4e3239d547c 100644 --- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8924.json +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8924.json @@ -11,14 +11,14 @@ "tests", "convention" ], - "defaultSeverity": "Major", + "defaultSeverity": "Minor", "ruleSpecification": "RSPEC-8924", "sqKey": "S8924", "scope": "Tests", "quickfix": "targeted", "code": { "impacts": { - "MAINTAINABILITY": "MEDIUM" + "MAINTAINABILITY": "LOW" }, "attribute": "CLEAR" } diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/Sonar_agentic_AI_profile.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/Sonar_agentic_AI_profile.json index 0f8b8e56c37..a669258ac60 100644 --- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/Sonar_agentic_AI_profile.json +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/Sonar_agentic_AI_profile.json @@ -463,7 +463,6 @@ "S8465", "S8469", "S8696", - "S8714", "S8715", "S8745", "S8786" diff --git a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaAgenticWayProfileTest.java b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaAgenticWayProfileTest.java index 16c0b03062b..5d255874ee4 100644 --- a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaAgenticWayProfileTest.java +++ b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaAgenticWayProfileTest.java @@ -53,7 +53,7 @@ void profile_is_registered_as_expected() { BuiltInQualityProfilesDefinition.BuiltInQualityProfile actualProfile = profilesPerLanguages.get("java").get("Sonar agentic AI"); assertThat(actualProfile.isDefault()).isFalse(); assertThat(actualProfile.rules()) - .hasSize(466) + .hasSize(465) .extracting(BuiltInQualityProfilesDefinition.BuiltInActiveRule::ruleKey) .doesNotContainAnyElementsOf(List.of( "S101", @@ -123,7 +123,8 @@ void profile_is_registered_as_expected() { "S6837", "S6912", "S8491", - "S8692" + "S8692", + "S8714" )); } diff --git a/sonarpedia.json b/sonarpedia.json index ce2fddcc2c0..39cc72ede1b 100644 --- a/sonarpedia.json +++ b/sonarpedia.json @@ -3,7 +3,7 @@ "languages": [ "JAVA" ], - "latest-update": "2026-06-18T09:33:18.987005213Z", + "latest-update": "2026-06-30T10:26:48.191927160Z", "options": { "no-language-in-filenames": true, "preserve-filenames": false