From 83fa5fb811fe66d868300edccd1468f3681624f6 Mon Sep 17 00:00:00 2001
From: daniel-teuchert-sonarsource
The Spring Framework provides several specializations of the generic Spring provides specialized stereotype annotations ( Replace The Spring Framework provides several specializations of the generic Explicitly specify Choose your approach based on the exception’s meaning: This is an issue when a Spring Spring Framework uses CGLIB proxies to enforce singleton semantics for beans defined in The Java @Component stereotype annotation which better express the programmer's intent. Using them should be preferred.Why is this an issue?
-@Service, @Repository, @Controller, and @RestController) that make code more expressive and provide additional semantics. When a class name suggests it should use one of these specialized annotations but uses @Component instead, it reduces code clarity.How to fix it
-@Component with the appropriate specialized annotation based on the class's role in the application.Code examples
-Noncompliant code example
-
-@Component // Noncompliant
+
@Component stereotype annotation which better express the
+programmer’s intent. Using them should be preferred.Noncompliant code example
+
+@Component // Noncompliant; class name suggests it's a @Service
public class CustomerServiceImpl {
// ...
}
-@Component // Noncompliant
+@Component // Noncompliant; class name suggests it's a @Repository
public class ProductRepository {
// ...
}
-@Component // Noncompliant
+@Component // Noncompliant; class name suggests it's a @Controller or @RestController
public class FooBarRestController {
// ...
}
-Compliant solution
-
+
Compliant solution
+
@Service // Compliant
public class CustomerServiceImpl {
// ...
@@ -37,9 +34,15 @@
Compliant solution
public class FooBarRestController {
// ...
}
+
+@Component // Compliant
+public class SomeOtherComponent {
+ // ...
+}
Resources
-Documentation
-
+
diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S5673.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S5673.json
index 66e17c3344f..2070e52a0f0 100644
--- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S5673.json
+++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S5673.json
@@ -3,14 +3,14 @@
"type": "CODE_SMELL",
"code": {
"impacts": {
- "MAINTAINABILITY": "LOW"
+ "MAINTAINABILITY": "MEDIUM"
},
"attribute": "CLEAR"
},
"status": "ready",
"remediation": {
- "func": "Constant/Issue",
- "constantCost": "2min"
+ "func": "Constant\/Issue",
+ "constantCost": "5min"
},
"tags": [
"spring"
diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S6418.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S6418.json
index 6c5dda39b59..ae2a46a6ef9 100644
--- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S6418.json
+++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S6418.json
@@ -14,9 +14,10 @@
},
"quickfix": "infeasible",
"tags": [
- "cwe",
"cert",
- "former-hotspot"
+ "cwe",
+ "former-hotspot",
+ "secret"
],
"defaultSeverity": "Blocker",
"ruleSpecification": "RSPEC-6418",
diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S6437.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S6437.json
index 757d768d07a..70c5fa9904b 100644
--- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S6437.json
+++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S6437.json
@@ -13,7 +13,8 @@
"constantCost": "60min"
},
"tags": [
- "cwe"
+ "cwe",
+ "secret"
],
"defaultSeverity": "Blocker",
"ruleSpecification": "RSPEC-6437",
diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8989.html b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8989.html
index a69c9b41f48..9c26daf2292 100644
--- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8989.html
+++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8989.html
@@ -49,6 +49,14 @@ Difficult Debugging
How to fix it in Spring
rollbackFor to include the checked exceptions that should trigger a rollback. This is the most common fix, as most
checked exceptions represent error conditions that should prevent the transaction from committing.
+
rollbackFor with specific exception types when you know exactly which exceptions represent failures requiring rollbackrollbackFor = Exception.class when the method throws Exception or multiple checked exception types that all
+ represent failuresnoRollbackFor only when a checked exception represents an expected, recoverable condition where you intentionally want the
+ transaction to commit (such as a notification failure after successfully saving core data)Code examples
Noncompliant code example
@@ -107,10 +115,9 @@
Compliant solution
Resources
Documentation
-
diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8989.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8989.json
index 30a5819853d..85e109a98f6 100644
--- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8989.json
+++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8989.json
@@ -15,7 +15,7 @@
"ruleSpecification": "RSPEC-8989",
"sqKey": "S8989",
"scope": "Main",
- "quickfix": "unknown",
+ "quickfix": "partial",
"code": {
"impacts": {
"RELIABILITY": "MEDIUM",
diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9021.html b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9021.html
index 3ade16fe3cd..9da81884b9e 100644
--- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9021.html
+++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9021.html
@@ -1,12 +1,14 @@
+@Configuration class is declared final. Spring needs to create CGLIB proxies for
+configuration classes that contain @Bean methods, and the final modifier prevents the necessary subclassing.Why is this an issue?
@Configuration classes. When you call a
@Bean method from within another @Bean method, Spring intercepts the call through a proxy to return the singleton instance
rather than creating a new object.final keyword prevents class inheritance, which blocks CGLIB from creating the necessary subclass proxy. Without this proxy,
-inter-bean method calls create new instances instead of retrieving the singleton, breaking Spring's container management.
This typically manifests as a ConfigurationClassPostProcessor exception during application startup, preventing the Spring context from
initializing.
When Spring @Configuration classes are marked final, the application fails to start. The
ConfigurationClassPostProcessor throws an exception because CGLIB cannot create the required proxy subclass.
If this check were bypassed, the impact would be more subtle: inter-bean method calls would create duplicate instances instead of using singletons, @@ -16,7 +18,11 @@
If you see this issue but your configuration class genuinely doesn’t call other @Bean methods directly, consider using
+@Configuration(proxyBeanMethods = false) instead of suppressing the issue. This makes the intent explicit and improves startup
+performance. Mark this as a false positive only if the class is not actually a @Configuration class or if the final modifier
+is required by a framework constraint you cannot control.
Remove the final modifier from the @Configuration class. This allows Spring to create the CGLIB proxy needed to enforce
singleton semantics for inter-bean method calls.
If you don't need inter-bean method calls and want to optimize startup performance, use @Configuration(proxyBeanMethods = false). This
+
If you don’t need inter-bean method calls and want to optimize startup performance, use @Configuration(proxyBeanMethods = false). This
disables CGLIB proxying, allowing the class to be final. However, you must use dependency injection instead of calling @Bean
methods directly.