Skip to content

Commit 4addef8

Browse files
SONARJAVA-4662 Update Rules Metadata and External Linters Metadata (#4527)
1 parent 77b3db2 commit 4addef8

16 files changed

Lines changed: 374 additions & 95 deletions

File tree

external-reports/src/main/resources/org/sonar/l10n/java/rules/spotbugs/spotbugs-rules.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2276,7 +2276,8 @@
22762276
},
22772277
{
22782278
"key": "PI_DO_NOT_REUSE_PUBLIC_IDENTIFIERS_INNER_CLASS_NAMES",
2279-
"name": "Do not reuse public identifiers from JSL as inner name",
2279+
"name": "Bad practice - Do not reuse public identifiers from JSL as inner name",
2280+
"type": "CODE_SMELL",
22802281
"severity": "MAJOR",
22812282
"url": "https://spotbugs.readthedocs.io/en/latest/bugDescriptions.html#pi-do-not-reuse-public-identifiers-inner-class-names"
22822283
},

java-checks/src/main/resources/org/sonar/l10n/java/rules/java/S113.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<h2>Why is this an issue?</h2>
2-
<p>Some tools work better when files end with an empty line.</p>
2+
<p>Some tools work better when files end with a newline.</p>
33
<p>This rule simply generates an issue if it is missing.</p>
44
<p>For example, a Git diff looks like this if the empty line is missing at the end of the file:</p>
55
<pre>

java-checks/src/main/resources/org/sonar/l10n/java/rules/java/S113.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"title": "Files should contain an empty newline at the end",
2+
"title": "Files should end with a newline",
33
"type": "CODE_SMELL",
44
"code": {
55
"impacts": {
Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,34 @@
1+
<p>This rule raises an issue when a private method is never referenced in the code.</p>
12
<h2>Why is this an issue?</h2>
2-
<p><code>private</code> methods that are never executed are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code
3-
decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.</p>
4-
<p>Note that this rule does not take reflection into account, which means that issues will be raised on <code>private</code> methods that are only
5-
accessed using the reflection API.</p>
3+
<p>A method that is never called is dead code, and should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it
4+
easier to understand the program and preventing bugs from being introduced.</p>
5+
<p>This rule detects methods that are never referenced from inside a translation unit, and cannot be referenced from the outside.</p>
6+
<h3>Code examples</h3>
67
<h3>Noncompliant code example</h3>
7-
<pre>
8+
<pre data-diff-id="1" data-diff-type="noncompliant">
89
public class Foo implements Serializable
910
{
10-
private Foo(){} //Compliant, private empty constructor intentionally used to prevent any direct instantiation of a class.
11-
public static void doSomething(){
11+
public static void doSomething() {
1212
Foo foo = new Foo();
1313
...
1414
}
15-
private void unusedPrivateMethod(){...}
16-
private void writeObject(ObjectOutputStream s){...} //Compliant, relates to the java serialization mechanism
17-
private void readObject(ObjectInputStream in){...} //Compliant, relates to the java serialization mechanism
15+
16+
private void unusedPrivateMethod() {...}
17+
private void writeObject(ObjectOutputStream s) {...} //Compliant, relates to the java serialization mechanism
18+
private void readObject(ObjectInputStream in) {...} //Compliant, relates to the java serialization mechanism
1819
}
1920
</pre>
2021
<h3>Compliant solution</h3>
21-
<pre>
22+
<pre data-diff-id="1" data-diff-type="compliant">
2223
public class Foo implements Serializable
2324
{
24-
private Foo(){} //Compliant, private empty constructor intentionally used to prevent any direct instantiation of a class.
2525
public static void doSomething(){
2626
Foo foo = new Foo();
2727
...
2828
}
2929

30-
private void writeObject(ObjectOutputStream s){...} //Compliant, relates to the java serialization mechanism
31-
32-
private void readObject(ObjectInputStream in){...} //Compliant, relates to the java serialization mechanism
30+
private void writeObject(ObjectOutputStream s) {...} //Compliant, relates to the java serialization mechanism
31+
private void readObject(ObjectInputStream in) {...} //Compliant, relates to the java serialization mechanism
3332
}
3433
</pre>
3534
<h3>Exceptions</h3>
@@ -38,4 +37,6 @@ <h3>Exceptions</h3>
3837
<li> annotated methods </li>
3938
<li> methods with parameters that are annotated with <code>@javax.enterprise.event.Observes</code> </li>
4039
</ul>
40+
<p>The rule does not take reflection into account, which means that issues will be raised on <code>private</code> methods that are only accessed using
41+
the reflection API.</p>
4142

java-checks/src/main/resources/org/sonar/l10n/java/rules/java/S1144.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"status": "ready",
1111
"remediation": {
1212
"func": "Constant\/Issue",
13-
"constantCost": "5min"
13+
"constantCost": "2min"
1414
},
1515
"tags": [
1616
"unused"

java-checks/src/main/resources/org/sonar/l10n/java/rules/java/S1860.html

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,34 @@
11
<h2>Why is this an issue?</h2>
2-
<p>Instances of value-based classes, which are pooled and potentially reused, should not be used for synchronization. If they are, it can cause
3-
unrelated threads to deadlock with unhelpful stacktraces.</p>
2+
<p>In Java, value-based classes are those for which instances are final and immutable, like <code>String</code>, <code>Integer</code> and so on, and
3+
their identity relies on their value and not their reference. When a variable of one of these types is instantiated, the JVM caches its value, and the
4+
variable is just a reference to that value. For example, multiple <code>String</code> variables with the same value "Hello world!" will refer to the
5+
same cached string literal in memory.</p>
6+
<p>The <code>synchronized</code> keyword tells the JVM to only allow the execution of the code contained in the following block to one
7+
<code>Thread</code> at a time. This mechanism relies on the identity of the object that is being synchronized between threads, to prevent that if
8+
object X is locked, it will still be possible to lock another object Y.</p>
9+
<p>It means that the JVM will fail to correctly synchronize threads on instances of the aforementioned value-based classes, for instance:</p>
10+
<pre>
11+
// These variables "a" and "b" will effectively reference the same object in memory
12+
Integer a = 0;
13+
Integer b = 0;
14+
15+
// This means that in the following code, the JVM could try to lock and execute
16+
// on the variable "a" because "b" was notified to be released, as the two Integer variables
17+
// are the same object to the JVM
18+
void syncMethod(int x) {
19+
synchronized (a) {
20+
if (a == x) {
21+
// ... do something here
22+
}
23+
}
24+
synchronized (b) {
25+
if (b == x) {
26+
// ... do something else
27+
}
28+
}
29+
}
30+
</pre>
31+
<p>This behavior can cause unrelated threads to deadlock with unclear stacktraces.</p>
432
<p>Within the JDK, types which should not be used for synchronization include:</p>
533
<ul>
634
<li> <code>String</code> literals </li>
@@ -21,8 +49,8 @@ <h2>Why is this an issue?</h2>
2149
</ul>
2250
<h2>How to fix it</h2>
2351
<p>Replace instances of value-based classes with a new object instance to synchronize on.</p>
24-
<h2>Code examples</h2>
25-
<h3>Noncompliant code example</h3>
52+
<h3>Code examples</h3>
53+
<h4>Noncompliant code example</h4>
2654
<pre data-diff-id="1" data-diff-type="noncompliant">
2755
private static final Boolean bLock = Boolean.FALSE;
2856
private static final Integer iLock = Integer.valueOf(0);
@@ -44,33 +72,33 @@ <h3>Noncompliant code example</h3>
4472
...
4573
}
4674
</pre>
47-
<h3>Compliant solution</h3>
75+
<h4>Compliant solution</h4>
4876
<pre data-diff-id="1" data-diff-type="compliant">
4977
private static final Object lock1 = new Object();
50-
private static final Object lock2 = new Object();
51-
private static final Object lock3 = new Object();
52-
private static final Object lock4 = new Object();
78+
private static final Integer iLock = new Integer(42);
79+
private static final String sLock = new String("A brand new string in memory!");
80+
private static final List&lt;String&gt; listLock = new ArrayList&lt;&gt;();
5381

5482
public void doSomething() {
5583

5684
synchronized(lock1) { // Compliant
5785
...
5886
}
59-
synchronized(lock2) { // Compliant
87+
synchronized(iLock) { // Compliant
6088
...
6189
}
62-
synchronized(lock3) { // Compliant
90+
synchronized(sLock) { // Compliant
6391
...
6492
}
65-
synchronized(lock4) { // Compliant
93+
synchronized(listLock) { // Compliant
6694
...
6795
}
6896
</pre>
6997
<h2>Resources</h2>
7098
<ul>
71-
<li> <a href="https://wiki.sei.cmu.edu/confluence/x/1zdGBQ">Do not synchronize on objects that may be reused - CERT, LCK01-J.</a> </li>
72-
<li> <a href="https://openjdk.java.net/jeps/390">JEP 390: Warnings for Value-Based Classes - OpenJDK</a> </li>
73-
<li> <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/doc-files/ValueBased.html">Value-based Classes - Java SE 17 API
74-
Documentation</a> </li>
99+
<li> CERT - <a href="https://wiki.sei.cmu.edu/confluence/x/1zdGBQ">Do not synchronize on objects that may be reused</a> </li>
100+
<li> OpenJDK - <a href="https://openjdk.java.net/jeps/390">JEP 390: Warnings for Value-Based Classes</a> </li>
101+
<li> Java Documentation - <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/doc-files/ValueBased.html">Value-based
102+
Classes</a> </li>
75103
</ul>
76104

java-checks/src/main/resources/org/sonar/l10n/java/rules/java/S1871.html

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
11
<h2>Why is this an issue?</h2>
2+
<p>When the same code is duplicated in two or more separate branches of a conditional, it can make the code harder to understand, maintain, and can
3+
potentially introduce bugs if one instance of the code is changed but others are not.</p>
24
<p>Having two <code>cases</code> in a <code>switch</code> statement or two branches in an <code>if</code> chain with the same implementation is at
35
best duplicate code, and at worst a coding error.</p>
46
<pre data-diff-id="1" data-diff-type="noncompliant">
7+
if (a &gt;= 0 &amp;&amp; a &lt; 10) {
8+
doFirstThing();
9+
doTheThing();
10+
}
11+
else if (a &gt;= 10 &amp;&amp; a &lt; 20) {
12+
doTheOtherThing();
13+
}
14+
else if (a &gt;= 20 &amp;&amp; a &lt; 50) {
15+
doFirstThing();
16+
doTheThing(); // Noncompliant; duplicates first condition
17+
}
18+
else {
19+
doTheRest();
20+
}
21+
</pre>
22+
<pre data-diff-id="2" data-diff-type="noncompliant">
523
switch (i) {
624
case 1:
725
doFirstThing();
@@ -18,27 +36,11 @@ <h2>Why is this an issue?</h2>
1836
doTheRest();
1937
}
2038
</pre>
21-
<pre data-diff-id="2" data-diff-type="noncompliant">
22-
if (a &gt;= 0 &amp;&amp; a &lt; 10) {
23-
doFirstThing();
24-
doTheThing();
25-
}
26-
else if (a &gt;= 10 &amp;&amp; a &lt; 20) {
27-
doTheOtherThing();
28-
}
29-
else if (a &gt;= 20 &amp;&amp; a &lt; 50) {
30-
doFirstThing();
31-
doTheThing(); // Noncompliant; duplicates first condition
32-
}
33-
else {
34-
doTheRest();
35-
}
36-
</pre>
3739
<p>If the same logic is truly needed for both instances, then:</p>
3840
<ul>
3941
<li> in an <code>if</code> chain they should be combined </li>
4042
</ul>
41-
<pre data-diff-id="2" data-diff-type="compliant">
43+
<pre data-diff-id="1" data-diff-type="compliant">
4244
if ((a &gt;= 0 &amp;&amp; a &lt; 10) || (a &gt;= 20 &amp;&amp; a &lt; 50)) { // Compliant
4345
doFirstThing();
4446
doTheThing();
@@ -51,9 +53,9 @@ <h2>Why is this an issue?</h2>
5153
}
5254
</pre>
5355
<ul>
54-
<li> for a <code>switch</code>, one should fall through to the other. </li>
56+
<li> for a <code>switch</code>, one should fall through to the other </li>
5557
</ul>
56-
<pre data-diff-id="1" data-diff-type="compliant">
58+
<pre data-diff-id="2" data-diff-type="compliant">
5759
switch (i) {
5860
case 1:
5961
case 3: // Compliant
@@ -74,7 +76,7 @@ <h3>Exceptions</h3>
7476
<code>switch</code> statement that contains a single line of code with or without a following <code>break</code>.</p>
7577
<pre>
7678
if (a == 1) {
77-
doSomething(); //no issue, usually this is done on purpose to increase the readability
79+
doSomething(); // Compliant, usually this is done on purpose to increase the readability
7880
} else if (a == 2) {
7981
doSomethingElse();
8082
} else {

java-checks/src/main/resources/org/sonar/l10n/java/rules/java/S1905.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<h2>Why is this an issue?</h2>
22
<p>Casting expressions are utilized to convert one data type to another, such as transforming an integer into a string. This is especially crucial in
3-
strongly typed languages like <code>C</code>, <code>C++</code>, <code>C#</code>, <code>Java</code>, <code>Python</code>, and others.</p>
3+
strongly typed languages like C, C++, C#, Java, Python, and others.</p>
44
<p>However, there are instances where casting expressions are not needed. These include situations like:</p>
55
<ul>
66
<li> casting a variable to its own type </li>

0 commit comments

Comments
 (0)