Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -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"
}
}
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,106 @@
<h2>Why is this an issue?</h2>
<p>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.</p>
<p>This rule raises an issue for each <code>Runnable</code>, and use of the <code>synchronized</code> keyword.</p>
<h3>Noncompliant code example</h3>
<pre>
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// ...

Runnable r = new Runnable() { // Noncompliant
public void run() {
<p>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.</p>
<p>This rule raises an issue for each <code>Runnable</code>, and use of the <code>synchronized</code> keyword in Jakarta EE applications.</p>
<h2>How to fix it</h2>
<p>Instead of creating unmanaged threads, use the Concurrency Utilities for Jakarta EE. Injecting a <code>ManagedExecutorService</code> lets the
container manage the thread pool and preserves the container context (CDI, security, transactions). If you are using EJBs, annotate a method with
<code>@Asynchronous</code> to run it in a container-managed background thread, with no need to manage threads or submit tasks explicitly.</p>
<p>For shared mutable state that would otherwise require <code>synchronized</code>, use container-managed concurrency instead. In EJBs, the container
serializes access to <code>@Singleton</code> beans by default (via <code>@Lock(WRITE)</code>), eliminating the need for explicit synchronization.
Outside EJBs, use the concurrency utilities from <code>java.util.concurrent</code> such as <code>AtomicInteger</code> or
<code>ConcurrentHashMap</code>, which are safe to use in Jakarta EE.</p>
<h3>Code examples</h3>
<h4>Noncompliant code example</h4>
<pre data-diff-id="1" data-diff-type="noncompliant">
@RequestScoped
public class DataProcessor {

public void processData() {
Runnable task = () -&gt; { // Noncompliant
// ...
};
new Thread(task).start();
}
}
</pre>
<h4>Compliant solution</h4>
<p>Using <code>ManagedExecutorService</code></p>
<pre data-diff-id="1" data-diff-type="compliant">
@RequestScoped
public class DataProcessor {

@Resource
private ManagedExecutorService executor;

public void processData() {
executor.submit(() -&gt; { // Compliant
// ...
}
};
new Thread(r).start();
});
}
}
</pre>
<h4>Noncompliant code example</h4>
<pre data-diff-id="2" data-diff-type="noncompliant">
@Stateless
public class OrderService {

public void dispatchOrder(Long orderId) {
Runnable r = new Runnable() { // Noncompliant
public void run() {
// ...
}
};
new Thread(r).start();
}
}
</pre>
<h4>Compliant solution</h4>
<p>Using <code>@Asynchronous</code></p>
<pre data-diff-id="2" data-diff-type="compliant">
@Stateless
public class OrderService {

@Asynchronous // Compliant
public void dispatchOrder(Long orderId) {
// ...
}
}
</pre>
<h4>Noncompliant code example</h4>
<pre data-diff-id="3" data-diff-type="noncompliant">
@Singleton
public class CounterService {

private int count = 0;

public synchronized void increment() { // Noncompliant
count++;
}

public synchronized int getCount() { // Noncompliant
return count;
}
}
</pre>
<h4>Compliant solution</h4>
<p>Using <code>@Singleton</code> with <code>@Lock(…​)</code></p>
<pre data-diff-id="3" data-diff-type="compliant">
@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;
}
}
</pre>
<h2>Resources</h2>
<ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@
"func": "Constant\/Issue",
"constantCost": "45min"
},
"code": {
"impacts": {
"RELIABILITY": "HIGH"
},
"attribute": "TRUSTWORTHY"
},
"tags": [
"cwe",
"multi-threading",
"jakarta",
"jee"
],
"defaultSeverity": "Critical",
Expand All @@ -21,5 +28,5 @@
574
]
},
"quickfix": "unknown"
"quickfix": "infeasible"
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ <h2>Why is this an issue?</h2>
secure by the cryptography community.</p>
<p>For AES, the weakest mode is ECB (Electronic Codebook). Repeated blocks of data are encrypted to the same value, making them easy to identify and
reducing the difficulty of recovering the original cleartext.</p>
<p>Unauthenticated modes such as CBC (Cipher Block Chaining) may be used but are prone to attacks that manipulate the ciphertext. They must be used
with caution.</p>
<p>For RSA, the weakest algorithms are either using it without padding or using the PKCS1v1.5 padding scheme.</p>
<h3>What is the potential impact?</h3>
<p>The cleartext of an encrypted message might be recoverable. Additionally, it might be possible to modify the cleartext of an encrypted message.</p>
Expand Down Expand Up @@ -103,16 +101,12 @@ <h4>For AES: use authenticated encryption modes</h4>
<li>IAPM: <code>Integer Authenticated Parallelizable Mode</code></li>
<li>OCB: <code>Offset Codebook Mode</code></li>
</ul>
<p>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.</p>
<h4>For RSA: use the OAEP scheme</h4>
<p>The Optimal Asymmetric Encryption Padding scheme (OAEP) adds randomness and a secure hash function that strengthens the regular inner workings of
RSA.</p>
<h2>Resources</h2>
<h3>Articles &amp; blog posts</h3>
<ul>
<li><a href="https://learn.microsoft.com/en-us/dotnet/standard/security/vulnerabilities-cbc-mode">Microsoft, Timing vulnerabilities with CBC-mode
symmetric decryption using padding</a></li>
<li><a href="https://en.wikipedia.org/wiki/Padding_oracle_attack">Wikipedia, Padding Oracle Attack</a></li>
<li><a href="https://en.wikipedia.org/wiki/Chosen-ciphertext_attack">Wikipedia, Chosen-Ciphertext Attack</a></li>
<li><a href="https://en.wikipedia.org/wiki/Chosen-plaintext_attack">Wikipedia, Chosen-Plaintext Attack</a></li>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<p>This rule raises an issue when at least 3 test methods could be refactored into a single parameterized test with less than 4 parameters.</p>
<h2>Why is this an issue?</h2>
<p>When multiple tests differ only by a few hardcoded values they should be refactored as a single "parameterized" test. This reduces the chances of
adding a bug and makes them more readable. Parameterized tests exist in most test frameworks (JUnit, TestNG, etc…​).</p>
<p>The right balance needs of course to be found. There is no point in factorizing test methods when the parameterized version is a lot more complex
than initial tests.</p>
<p>This rule raises an issue when at least 3 tests could be refactored as one parameterized test with less than 4 parameters. Only test methods which
have at least one duplicated statement are considered.</p>
<p>When multiple tests differ only by a few hardcoded values, they should be refactored into a single parameterized test. This reduces duplication,
makes the tests easier to read, and lowers the risk of introducing bugs when the test logic needs to change.</p>
<p>Parameterized tests are supported by most testing frameworks.</p>
<p>The right balance still needs to be found. There is little value in parameterizing tests when the resulting test becomes significantly more complex
than the original versions.</p>
<h3>Noncompliant code example</h3>
<p>with JUnit 5</p>
<pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,4 @@ <h2>Resources</h2>
<ul>
<li><a href="https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-8.10">Records specification</a></li>
</ul>

Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ <h2>Why is this an issue?</h2>
<p>When you mark a method for startup execution, the dependency injection framework generates initialization hooks that trigger the method when the
application starts. For this mechanism to work correctly, the method must meet three requirements:</p>
<ul>
<li> <strong>Non-static</strong>: The method must be an instance method. Dependency injection frameworks work by creating managed component
instances and invoking methods on those instances. A static method belongs to the class itself, not to an instance, so the framework cannot properly
manage its lifecycle or invoke it as part of component initialization. </li>
<li> <strong>Non-producer</strong>: The method cannot be a producer method (one that creates and provides instances for other components to
consume). Producer methods are designed to create and provide component instances, not to perform initialization logic. Combining startup execution
markers with producer functionality creates a conflict in the intended purpose of the method. </li>
<li> <strong>No arguments</strong>: The method must not accept any parameters. The framework invokes these methods automatically at startup and has
no mechanism to provide argument values. If a method requires parameters, the framework cannot call it. </li>
<li><strong>Non-static</strong>: The method must be an instance method. Dependency injection frameworks work by creating managed component instances
and invoking methods on those instances. A static method belongs to the class itself, not to an instance, so the framework cannot properly manage
its lifecycle or invoke it as part of component initialization.</li>
<li><strong>Non-producer</strong>: The method cannot be a producer method (one that creates and provides instances for other components to consume).
Producer methods are designed to create and provide component instances, not to perform initialization logic. Combining startup execution markers
with producer functionality creates a conflict in the intended purpose of the method.</li>
<li><strong>No arguments</strong>: The method must not accept any parameters. The framework invokes these methods automatically at startup and has
no mechanism to provide argument values. If a method requires parameters, the framework cannot call it.</li>
</ul>
<h3>What is the potential impact?</h3>
<p>When methods designated for startup execution don’t follow the required signature, the initialization logic will not execute at application
startup. This can lead to:</p>
<ul>
<li> Missing configuration or setup steps that are essential for the application to function correctly </li>
<li> Uninitialized resources or connections that other parts of the application depend on </li>
<li> Runtime errors when the application tries to use components that were supposed to be initialized at startup </li>
<li> Silent failures where the method is simply not called, making the problem difficult to diagnose </li>
<li>Missing configuration or setup steps that are essential for the application to function correctly</li>
<li>Uninitialized resources or connections that other parts of the application depend on</li>
<li>Runtime errors when the application tries to use components that were supposed to be initialized at startup</li>
<li>Silent failures where the method is simply not called, making the problem difficult to diagnose</li>
</ul>
<h2>How to fix it</h2>
<p>Remove the <code>static</code> modifier from the method to make it an instance method. Ensure the method has no parameters and is not annotated
Expand Down Expand Up @@ -53,8 +53,9 @@ <h4>Compliant solution</h4>
<h2>Resources</h2>
<h3>Documentation</h3>
<ul>
<li> Quarkus - Application Initialization and Termination - <a href="https://quarkus.io/guides/lifecycle">Official Quarkus guide on using @Startup
and other lifecycle annotations</a> </li>
<li> Jakarta CDI Specification - <a href="https://jakarta.ee/specifications/cdi/">The specification for Contexts and Dependency Injection in Jakarta
EE</a> </li>
<li>Quarkus - Application Initialization and Termination - <a href="https://quarkus.io/guides/lifecycle">Official Quarkus guide on using @Startup
and other lifecycle annotations</a></li>
<li>Jakarta CDI Specification - <a href="https://jakarta.ee/specifications/cdi/">The specification for Contexts and Dependency Injection in Jakarta
EE</a></li>
</ul>

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<p>This rule raises an issue when Mockito core methods are called with the <code>Mockito.</code> prefix instead of being statically imported.</p>
<p>This applies to commonly used Mockito methods such as:</p>
<p>This applies to the following Mockito methods:</p>
<ul>
<li><code>mock()</code></li>
<li><code>when()</code></li>
Expand All @@ -9,19 +9,19 @@
<li><code>doThrow()</code></li>
<li><code>times()</code></li>
<li><code>never()</code></li>
<li><code>any()</code></li>
<li><code>eq()</code></li>
</ul>
<h2>Why is this an issue?</h2>
<p>Mockito was designed with static imports in mind to create a more readable, fluent testing DSL (Domain-Specific Language). When you use the
<code>Mockito.</code> prefix for method calls, the test code becomes more verbose and harder to read.</p>
<p>Compare these two examples:</p>
<pre>
Mockito.when(Mockito.mock(MyService.class).getValue()).thenReturn(42);
var myMock = Mockito.mock(MyService.class);
Mockito.when(myMock.getValue()).thenReturn(42);
</pre>
<p>versus:</p>
<pre>
when(mock(MyService.class).getValue()).thenReturn(42);
var myMock = mock(MyService.class);
when(myMock.getValue()).thenReturn(42);
</pre>
<p>The second version reads more naturally, almost like plain English, which is the intent of Mockito’s API design. This readability improvement
becomes even more significant in larger test files with many mock interactions.</p>
Expand Down Expand Up @@ -51,7 +51,8 @@ <h4>Noncompliant code example</h4>
</pre>
<h4>Compliant solution</h4>
<pre data-diff-id="1" data-diff-type="compliant">
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;

public class MyServiceTest {
private MyService myService = mock(MyService.class);
Expand All @@ -73,3 +74,13 @@ <h3>Documentation</h3>
<li>Mockito Documentation - How do I import Mockito? - <a
href="https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html">Official Mockito documentation</a></li>
</ul>
<hr>
<h2>Implementation Specification</h2>
<p>(visible only on this page)</p>
<h3>Message</h3>
<p>Use a static import for "{method name}".</p>
<h3>Highlighting</h3>
<ul>
<li>Primary: Mockito prefix and method name</li>
</ul>

Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,6 @@
"S8465",
"S8469",
"S8696",
"S8714",
"S8715",
"S8745",
"S8786"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -123,7 +123,8 @@ void profile_is_registered_as_expected() {
"S6837",
"S6912",
"S8491",
"S8692"
"S8692",
"S8714"
));
}

Expand Down
2 changes: 1 addition & 1 deletion sonarpedia.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading