SONARJAVA-6491: Implement S8911 - Methods annotated with @Startup should be non-static, non-producer, and parameter-free#5694
Conversation
7474c91 to
f20a9ac
Compare
b6d365b to
93ac858
Compare
… with individual diff files
…eporting count from 20 to 19
rombirli
left a comment
There was a problem hiding this comment.
LGTM. Please be careful about https://github.com/SonarSource/rspec/pull/7152#discussion_r3472686968 during validation
There was a problem hiding this comment.
Rspec PR says it's only in Sonar-Way which seems correct. Could you update rule metadata to exclude it from agentic ai profile
| assertThat(actualProfile.isDefault()).isFalse(); | ||
| assertThat(actualProfile.rules()) | ||
| .hasSize(465) | ||
| .hasSize(466) |
| private static final String STARTUP_FQN = "io.quarkus.runtime.Startup"; | ||
| private static final String PRODUCES_FQN = "jakarta.enterprise.inject.Produces"; |
There was a problem hiding this comment.
Usually we prefer matchers
There was a problem hiding this comment.
I don't know if it's possible, I never did it for annotations. Optional : let's give it a try with an agent
There was a problem hiding this comment.
After exploring the codebase, the current pattern of using symbolType().is(FQN) for annotation checking is actually the standard approach used throughout the java-checks module.
MethodMatchers is specifically designed for matching method invocations by type, name, and parameters - it doesn't support annotation matching. For annotation checks, the codebase consistently uses either:
annotation.annotationType().symbolType().is(FQN)when working withAnnotationTree(syntax tree level)symbol.metadata().isAnnotatedWith(FQN)for simple presence checks
The current implementation follows pattern #1, which is appropriate here since we need to create secondary locations pointing to the specific AnnotationTree objects. Examples using the same pattern include:
TransactionalMethodVisibilityCheck.java:69-74NullableInjectedFieldsHaveDefaultValueCheck.java:161-165
Given that your follow-up comment indicates this is optional and you're uncertain if matchers work for annotations, I believe the current implementation is correct as-is.
There was a problem hiding this comment.
After searching the codebase, there doesn't appear to be a built-in annotation matcher utility (like MethodMatchers for method calls). Other similar annotation-based checks (e.g., ScheduledOnlyOnNoArgMethodCheck.java:66) use the same pattern: .filter(annotation -> annotation.annotationType().symbolType().is(FQN)).
Creating an annotation matcher would be a larger architectural addition. Since this is marked optional, I'm keeping the current approach which follows the established pattern in the codebase.
| .map(annotation -> | ||
| new JavaFileScannerContext.Location("Triggered by this annotation", annotation.annotationType())) |
There was a problem hiding this comment.
code style suggestion
| .map(annotation -> | |
| new JavaFileScannerContext.Location("Triggered by this annotation", annotation.annotationType())) | |
| .map(annotation -> | |
| new JavaFileScannerContext.Location("Triggered by this annotation", annotation.annotationType()) | |
| ) |
| reportIssue( | ||
| methodTree.simpleName(), | ||
| "\"@Startup\" annotation should not be applied to producer methods", | ||
| secondaryLocations, | ||
| null); |
There was a problem hiding this comment.
code style suggestion
| reportIssue( | |
| methodTree.simpleName(), | |
| "\"@Startup\" annotation should not be applied to producer methods", | |
| secondaryLocations, | |
| null); | |
| reportIssue( | |
| methodTree.simpleName(), | |
| "\"@Startup\" annotation should not be applied to producer methods", | |
| secondaryLocations, | |
| null | |
| ); |
| reportIssue( | ||
| methodTree.simpleName(), | ||
| "\"@Startup\" annotation should only be applied to no-arg methods", | ||
| secondaryLocations, | ||
| null); |
There was a problem hiding this comment.
| reportIssue( | |
| methodTree.simpleName(), | |
| "\"@Startup\" annotation should only be applied to no-arg methods", | |
| secondaryLocations, | |
| null); | |
| reportIssue( | |
| methodTree.simpleName(), | |
| "\"@Startup\" annotation should only be applied to no-arg methods", | |
| secondaryLocations, | |
| null | |
| ); |
| reportIssue( | ||
| methodTree.simpleName(), | ||
| "\"@Startup\" annotation should not be applied to static methods", | ||
| secondaryLocations, | ||
| null); |
There was a problem hiding this comment.
| reportIssue( | |
| methodTree.simpleName(), | |
| "\"@Startup\" annotation should not be applied to static methods", | |
| secondaryLocations, | |
| null); | |
| reportIssue( | |
| methodTree.simpleName(), | |
| "\"@Startup\" annotation should not be applied to static methods", | |
| secondaryLocations, | |
| null | |
| ); |
…sources/org/sonar/l10n/java/rules/java/Sonar_agentic_AI_profile.json Comment: [Rspec PR](https://github.com/SonarSource/rspec/pull/7152/changes#diff-de722320e2e762504eb80a52f56b8891ffe8c3076d3524802ac0208edd9e33adR19) says it's only in Sonar-Way which seems correct. Could you update rule metadata to exclude it from agentic ai profile
…/sonar/java/checks/StartupAnnotationCheck.java
Comment: code style suggestion
```suggestion
.map(annotation ->
new JavaFileScannerContext.Location("Triggered by this annotation", annotation.annotationType())
)
```
…/sonar/java/checks/StartupAnnotationCheck.java
Comment: code style suggestion
```suggestion
reportIssue(
methodTree.simpleName(),
"\"@startup\" annotation should not be applied to producer methods",
secondaryLocations,
null
);
```
…/sonar/java/checks/StartupAnnotationCheck.java
Comment: ```suggestion
reportIssue(
methodTree.simpleName(),
"\"@startup\" annotation should not be applied to static methods",
secondaryLocations,
null
);
```
|
Code Review ✅ Approved 4 resolved / 4 findingsImplements rule S8911 to detect non-compliant Quarkus ✅ 4 resolved✅ Bug: S8911 not added to Sonar_way_profile.json
✅ Quality: activateLicense() removed only from AutoScanTest, inconsistent with other ITs
✅ Quality: Build artifacts (MANIFEST.MF, .class files) committed to source control
✅ Quality: S6813 false-negative baseline increased (65->66) without explanation
OptionsAuto-apply is off → Gitar will not commit updates to this branch. Comment with these commands to change:
Was this helpful? React with 👍 / 👎 | Gitar |




Summary
This PR implements rule S8911 to detect methods annotated with
@Startup(fromio.quarkus.runtime.Startup) that violate CDI initialization requirements by being static, having parameters, or being annotated with@Produces.Rule Behavior
The rule detects methods annotated with
@Startupthat:static(static methods cannot be managed by CDI lifecycle)@Produces(producer methods serve a different purpose than initialization)Implementation Approach
The implementation follows the pattern established by
ScheduledOnlyOnNoArgMethodCheck(S7184):IssuableSubscriptionVisitorto subscribe toTree.Kind.METHODnodes@Startupannotation (io.quarkus.runtime.Startup)@Startupis present, checks for three violations:methodTree.symbol().isStatic())!methodTree.parameters().isEmpty())@Producesannotation (checking forjakarta.enterprise.inject.Produces)@Startupannotation for contextTest Coverage
The test file covers:
Noncompliant patterns:
@Startup@Startupand parameters@Startupand@ProducesCompliant patterns:
@Startup(valid usage)@Injectfields) instead of parameters@Startupannotation (static, producer, or parameterized methods are OK)@Startup(access level doesn't matter for this rule)Additional Changes
io.quarkus.runtime.Startupannotation injava-checks-test-sources/default/src/main/java/io/quarkus/runtime/Startup.javafollowing the pattern used for other external dependencies (similar toio.realm.RealmConfiguration)jakarta.enterprise.cdi-apiandjavax.inject) already available in the test sources pomResources
🤖 Generated with Claude Code