Skip to content

Commit

Permalink
Merge branch 'master' into rule/modify-S6856
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardo-pilastri-sonarsource authored Jan 28, 2025
2 parents c6b6332 + 1e62d9f commit e1f9735
Show file tree
Hide file tree
Showing 16 changed files with 369 additions and 2 deletions.
10 changes: 8 additions & 2 deletions frontend/public/covered_rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -2226,7 +2226,10 @@
"S122": "sonar-go 1.17.0.123",
"S126": "sonar-go 1.17.0.123",
"S131": "sonar-go 1.17.0.123",
"S1313": "sonar-go 1.17.0.123",
"S1313": {
"since": "sonar-go 1.17.0.123",
"until": "sonar-go 1.18.0.240"
},
"S1314": "sonar-go 1.17.0.123",
"S134": "sonar-go 1.17.0.123",
"S138": "sonar-go 1.17.0.123",
Expand All @@ -2239,7 +2242,10 @@
"S1862": "sonar-go 1.17.0.123",
"S1871": "sonar-go 1.17.0.123",
"S1940": "sonar-go 1.17.0.123",
"S2068": "sonar-go 1.17.0.123",
"S2068": {
"since": "sonar-go 1.17.0.123",
"until": "sonar-go 1.18.0.240"
},
"S2260": "sonar-go 1.17.0.123",
"S2757": "sonar-go 1.17.0.123",
"S3776": "sonar-go 1.17.0.123",
Expand Down
24 changes: 24 additions & 0 deletions rules/S7177/java/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"title": "Use appropriate @DirtiesContext modes",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"spring"
],
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-7177",
"sqKey": "S7177",
"scope": "Tests",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "unknown",
"code": {
"impacts": {
"RELIABILITY": "MEDIUM"
},
"attribute": "LOGICAL"
}
}
42 changes: 42 additions & 0 deletions rules/S7177/java/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
== Why is this an issue?

The `@DirtiesContext` annotation marks the ApplicationContext as dirty and indicates that it should be cleared and recreated.
This is important in tests that modify the context, such as altering the state of singleton beans or databases.

Misconfiguring `@DirtiesContext` by setting the `methodMode` at the class level or the `classMode` at the method level will make the annotation have no effect.

This rule will raise an issue when the incorrect mode is configured on a @DirtiesContext annotation targeting a different scope.

== How to fix it

=== Code examples

==== Noncompliant code example

[source,java,diff-id=1,diff-type=noncompliant]
----
@ContextConfiguration
@DirtiesContext(methodMode = MethodMode.AFTER_METHOD) // Noncompliant, for class-level control, use classMode instead.
public class TestClass {
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) // Non compliant, for method-level control use methodMode instead
public void test() {...}
}
----

==== Compliant solution

[source,java,diff-id=1,diff-type=compliant]
----
@ContextConfiguration
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class TestClass {
@DirtiesContext(methodMode = MethodMode.AFTER_METHOD)
public void test() {...}
}
----

== Resources

=== Documentation

* Spring documentation - https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/annotation/DirtiesContext.html[@DirtiesContext]
2 changes: 2 additions & 0 deletions rules/S7177/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
26 changes: 26 additions & 0 deletions rules/S7178/java/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"title": "Injecting data into static fields is not supported by Spring",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"spring"
],
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-7178",
"sqKey": "S7178",
"scope": "Main",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "unknown",
"code": {
"impacts": {
"MAINTAINABILITY": "LOW",
"RELIABILITY": "HIGH",
"SECURITY": "LOW"
},
"attribute": "LOGICAL"
}
}
46 changes: 46 additions & 0 deletions rules/S7178/java/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
== Why is this an issue?

Spring dependency injection framework does not support injecting data into static fields. When @Value, @Inject, or @Autowired are applied to static fields, they are ignored.

=== What is the potential impact?

* *Null Values*: Uninitialized static fields annotated with @Value, @Inject, or @Autowired will not be initialized by Spring, potentially causing NullPointerException at runtime.
* *Confusing Code*: The presence of injection annotations on static fields can mislead developers into believing that the fields will be populated by Spring.

This rule raises an issue when a static field is annotated with @Value, @Inject, or @Autowired.

== How to fix it

Either use an instance field instead of a static field or remove the @Value, @Inject, or @Autowired annotation and initialize the field.

=== Code examples

==== Noncompliant code example

[source,java,diff-id=1,diff-type=noncompliant]
----
@Component
public class MyComponent {
@Value("${my.app.prop}")
private static SomeDependency dependency; // non compliant, @Value will be ignored and no value will be injected
// ...
}
----

==== Compliant solution

[source,java,diff-id=1,diff-type=compliant]
----
@Component
public class MyComponent {
@Value("${my.app.prop}")
private final SomeDependency dependency;
// ...
}
----

== Resources
=== Articles & blog posts
* Java Guides - https://www.baeldung.com/spring-inject-static-field[Injecting a Value in a Static Field in Spring]
2 changes: 2 additions & 0 deletions rules/S7178/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
24 changes: 24 additions & 0 deletions rules/S7179/java/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"title": "@Cacheable and @CachePut should not be combined",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"spring"
],
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-7179",
"sqKey": "S7179",
"scope": "Tests",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "unknown",
"code": {
"impacts": {
"RELIABILITY": "MEDIUM"
},
"attribute": "LOGICAL"
}
}
38 changes: 38 additions & 0 deletions rules/S7179/java/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
== Why is this an issue?

`@Cacheable` annotation is used to store the result of a method and avoid executing it for the same inputs.
`@CachePut` instead is used to force the execution of a method and store the result in the cache.
Annotating a method with both will produce unreliable behavior, except for specific corner-cases when their `condition()` or `unless()` expressions are mutually exclusive.
Hence this pattern is strongly discouraged and an issue will be raised on such cases.

== How to fix it

=== Code examples

==== Noncompliant code example

[source,java,diff-id=1,diff-type=noncompliant]
----
@Cacheable
@CachePut
void getBook(String isbn){ // Non compliant, methods annotated with both @Cacheable and @CachePut will not behave as intended
...
}
----

==== Compliant solution

[source,java,diff-id=1,diff-type=compliant]
----
@Cacheable
void getBook(String isbn){
...
}
----

== Resources

=== Documentation

* Spring Documentation - https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/cache/annotation/CachePut.html[@CachePut]
* Spring Documentation - https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/cache/annotation/Cacheable.html[@Cacheable]
2 changes: 2 additions & 0 deletions rules/S7179/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
26 changes: 26 additions & 0 deletions rules/S7180/java/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"title": "\"@Cache*\" annotations should only be applied on concrete classes",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"spring"
],
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-7180",
"sqKey": "S7180",
"scope": "Main",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "unknown",
"code": {
"impacts": {
"MAINTAINABILITY": "LOW",
"RELIABILITY": "MEDIUM",
"SECURITY": "LOW"
},
"attribute": "LOGICAL"
}
}
45 changes: 45 additions & 0 deletions rules/S7180/java/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
== Why is this an issue?

Annotating interfaces or interface methods with ``++@Cache*++`` annotations is not recommended. When using CGLIB-based proxies, these annotations will be ignored, and no caching proxy will be created.

=== What is the potential impact?

* *Confusing Code*: Developers may mistakenly believe that caching is in effect, leading to confusion and incorrect assumptions about application performance.

This rule raises an issue when an interface or an interface method is annotated with a ``++@Cache*++`` annotation.

== How to fix it

Move ``++@Cache*++`` annotation from interface or interface method to the concrete class.

=== Code examples

==== Noncompliant code example

[source,java,diff-id=1,diff-type=noncompliant]
----
public interface ExampleService {
@Cacheable("exampleCache") //non compliant, interface method is annotated with @Cacheable
String getData(String id);
}
----

==== Compliant solution

[source,java,diff-id=1,diff-type=compliant]
----
@Service
public class ExampleServiceImpl implements ExampleService {
@Cacheable("exampleCache")
@Override
public String getData(String id) {
// Implementation here
}
}
----

== Resources
=== Documentation
* Spring - https://docs.spring.io/spring-framework/reference/integration/cache/annotations.html#cache-annotation-enable[Declarative Annotation-based Caching]
2 changes: 2 additions & 0 deletions rules/S7180/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
25 changes: 25 additions & 0 deletions rules/S7183/java/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"title": "@InitBinder methods should have void return type",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"spring"
],
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-7183",
"sqKey": "S7183",
"scope": "All",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "unknown",
"code": {
"impacts": {
"RELIABILITY": "MEDIUM",
"SECURITY": "LOW"
},
"attribute": "LOGICAL"
}
}
55 changes: 55 additions & 0 deletions rules/S7183/java/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
== Why is this an issue?

Spring provides the `@InitBinder` annotation to initialize a `WebDataBinder` instance for controllers.
This is useful to bind request parameters to a model object, and to plug converters and formatters into this process.

Methods annotated with `@InitBinder` must not have a return value, otherwise the controller containing them will throw an exception when invoked.

This rule raises an issue when a method annotated with `@InitBinder` does not have a `void` return type

== How to fix it

=== Code examples

==== Noncompliant code example

[source,java,diff-id=1,diff-type=noncompliant]
----
@Controller
public class MyController {
@InitBinder
public String initBinder(WebDataBinder binder) { // Non compliant, make the @InitBinder method return void
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
return "OK";
}
// ...
}
----

==== Compliant solution

[source,java,diff-id=1,diff-type=compliant]
----
@Controller
public class MyController {
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
// ...
}
----

== Resources
=== Documentation

* Spring api - https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/InitBinder.html[@InitBinder api]
* String documentation - https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-initbinder.html[@InitBinder docs]
Loading

0 comments on commit e1f9735

Please sign in to comment.