Skip to content

SONARJAVA-6492: Implement S8912 - CredentialsProvider implementations should be annotated with @Unremovable#5707

Open
romainbrenguier wants to merge 8 commits into
masterfrom
new-rule/SONARJAVA-6492-S8912
Open

SONARJAVA-6492: Implement S8912 - CredentialsProvider implementations should be annotated with @Unremovable#5707
romainbrenguier wants to merge 8 commits into
masterfrom
new-rule/SONARJAVA-6492-S8912

Conversation

@romainbrenguier

Copy link
Copy Markdown
Contributor

Summary

  • Implements rule S8912: Custom CredentialsProvider implementations in Quarkus should be annotated with @Unremovable when they have a CDI scope annotation, to prevent them from being removed by Quarkus's bean pruning mechanism.
  • Rule raises an issue on CDI-scoped classes implementing io.quarkus.credentials.CredentialsProvider that are missing the @io.quarkus.arc.Unremovable annotation.
  • Test sample uses mock stub types for io.quarkus.arc.Unremovable and io.quarkus.credentials.CredentialsProvider (no external library dependency added to pom.xml), following the same pattern as S8911.

Rspec PR: https://github.com/SonarSource/rspec/pull/7153

Test plan

  • Rule implementation correctly detects missing @Unremovable on CDI-scoped CredentialsProvider implementations
  • Compliant cases (with @Unremovable, or without CDI scope) are not flagged
  • withoutSemantic() test verifies no issues raised without semantic analysis
  • JavaAgenticWayProfileTest passes
  • CI ruling and autoscan tests pass (to be updated after CI run)

🤖 Generated with Claude Code

@hashicorp-vault-sonar-prod

hashicorp-vault-sonar-prod Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

SONARJAVA-6492

Comment thread sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8912.html Outdated
@romainbrenguier romainbrenguier force-pushed the new-rule/SONARJAVA-6492-S8912 branch from f1d1c88 to 5aefe2c Compare June 26, 2026 15:18
- Added diff_S8912.json and updated autoscan-diff-by-rules.json with the new rule S8912 (FN=8) and corrected FN counts for S1128 (30→31), S1168 (24→25), and S6813 (66→67)
- Fixed Sonar_way_profile.json by sorting rule keys numerically (by integer value) instead of lexicographically, as required by MetadataTest.ensure_sane_Sonar_way_profile
- Sorted ruleKeys in Sonar_way_profile.json by numeric value instead of lexicographic order to fix MetadataTest.ensure_sane_Sonar_way_profile
@gitar-bot

gitar-bot Bot commented Jun 29, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 2 resolved / 2 findings

Implements rule S8912 to enforce the use of @Unremovable on CDI-scoped CredentialsProvider implementations, ensuring consistency with Quarkus bean pruning requirements. Resolved formatting issues in the rule documentation and cleaned up unrelated rule additions in the profile configuration.

✅ 2 resolved
Quality: S8912.html is raw AsciiDoc wrapped in a single

tag

📄 sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8912.html:1-15
The new rule description S8912.html is written as raw AsciiDoc markup (=== Documentation, == Why is this an issue?, * bullet lists, bare URLs) enclosed inside one single <p>...</p> element. Every other rule description in this directory (e.g. the sibling rule S8911.html) is authored as proper HTML using <h2>, <h3>, <p>, <ul>/<li>, <a href>, <code>, etc.

Because the file is served verbatim to SonarQube/IDE clients (the GeneratedCheckListTest only checks that the file exists, not its structure), this rule's documentation will render as one unbroken paragraph: the ===/== headings, the * bullets and the raw URLs will all be displayed as literal text instead of headings, lists and links. The section ordering is also inverted relative to convention — === What is the potential impact? appears before == Why is this an issue?, and there is no How to fix it section.

Fix: convert the content to real HTML matching the S8911 structure — <h2>Why is this an issue?</h2>, <h2>How to fix it</h2>, <h2>Resources</h2>/<h3>Documentation</h3>, with <ul><li> lists and <a href="..."> links — and order the sections consistently with the other rules.

Quality: Profile commit re-sorts file and adds two unrelated rules

📄 sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/Sonar_way_profile.json:4-18 📄 sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/Sonar_way_profile.json:534-541
The diff_stats/delta only surfaced +S2206 and +S2654, but the actual commit (5aefe2c) does much more to Sonar_way_profile.json:

  1. Unrelated rule activations: Besides the intended S8912, this commit also activates S2206 and S2654 in the default Sonar way profile. Those rules were implemented in separate, already-merged PRs (SONARJAVA-6527 Implement rule S2206: Either fields or getters should be annotated for persistence but not both #5706 and SONARJAVA-6526 Implement rule S2654: JEE applications should not use threads or synchronization #5702) that did not add them to the profile. Activating two unrelated rules inside an S8912 PR is scope creep — it silently changes analysis results for every user on the default profile and should be a deliberate, separately reviewed change.

  2. Whole-file re-ordering: The commit re-orders a large block of entries, moving S107, S108, S110, S112, S114, S115, S116, S117, S119, S120, S125, S127, S128, S131, S135 and S899 from their original (numeric) positions to new (lexicographic) positions — e.g. S899 jumps to the very end after S8924. The repo's existing convention orders entries numerically (S106, S107, ... S135, S899, S1065); this commit switches the moved entries to lexicographic string ordering, inconsistent with the rest of the file and producing a noisy ~35-line diff that obscures the real change.

This strongly suggests the profile was regenerated with a tool that uses a different sort order than the repo convention. Suggested fix: regenerate the profile using the project's standard generator so ordering matches convention, and limit this PR to adding only S8912. If S2206/S2654 genuinely belong in Sonar way, add them in their own commit/PR with explicit justification.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

Comment on lines +32 to +36
"jakarta.enterprise.context.ApplicationScoped",
"jakarta.enterprise.context.RequestScoped",
"jakarta.enterprise.context.SessionScoped",
"jakarta.enterprise.context.Dependent",
"jakarta.inject.Singleton"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should also add the javax equivalent here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since version 3.0, Quarkus is based on Jakarta EE 10 and I think it is mandatory to use the jakarta.* packages, so I don't know if it is necessary to add the javax variant

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're correct that Quarkus 3.0+ is based on Jakarta EE 10 and requires jakarta.* packages. However, I included the javax variants following the pattern used in other rules in this codebase (e.g., JEEThreadCheck at java-checks/src/main/java/org/sonar/java/checks/JEEThreadCheck.java:48-52, which supports both javax and jakarta variants for EJB annotations).

The rationale is that SonarJava analyzes existing codebases, some of which may still be using Quarkus 2.x with javax packages. Supporting both variants ensures the rule works across different Quarkus versions, which is helpful for users in the process of migrating from Quarkus 2 to 3.

That said, if the team's policy is to only support current framework versions (Quarkus 3.x+), I can remove the javax variants. What's your preference?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. While Quarkus 3.0+ requires Jakarta EE 10, following the codebase convention seen in other rules (e.g., AtLeastOneConstructorCheck, ServletInstanceFieldCheck, Spring checks), I've added the javax equivalents to support potential legacy code or older Quarkus versions:

"javax.enterprise.context.ApplicationScoped",
"javax.enterprise.context.RequestScoped",
"javax.enterprise.context.SessionScoped",
"javax.enterprise.context.Dependent",
"javax.inject.Singleton"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about the verbose replies, that comes from the vibe-bot 😅

@romainbrenguier romainbrenguier marked this pull request as ready for review June 29, 2026 08:03

@NoemieBenard NoemieBenard left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few comments

}

reportIssue(
classTree.simpleName(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it matters here, but this can be null

"quickfix": "unknown",
"code": {
"impacts": {
"SECURITY": "MEDIUM",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we were not supposed to do security rules, did you ask code security about this rule? We could just keep the "reliability" impact, as it is probably the most important for this rule.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's clearly a rule more about reliability than security, I'll remove the "SECURITY" entry from the rspec.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did the update on the rspec side. It will be taken into account by the next "update metadata" run

"ruleSpecification": "RSPEC-8912",
"sqKey": "S8912",
"scope": "All",
"quickfix": "unknown",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rule is probably a good candidate for a quickfix, we can put it as "targeted" so that it will be easier to find it if we want to implement quickfixes later

@@ -0,0 +1,16 @@
package checks;

import io.quarkus.arc.Unremovable;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import is unused

Suggested change
import io.quarkus.arc.Unremovable;

…ava/org/sonar/java/checks/CredentialsProviderUnremovableCheck.java

Comment: Maybe we should also add the javax equivalent here?
…/org/sonar/java/checks/CredentialsProviderUnremovableCheck.java

Comment: Not sure it matters here, but this can be null
…n/resources/org/sonar/l10n/java/rules/java/S8912.json

Comment: The rule is probably a good candidate for a quickfix, we can put it as "targeted" so that it will be easier to find it if we want to implement quickfixes later
…default/src/main/java/checks/CredentialsProviderUnremovableCheckSampleMinimal.java

Comment: This import is unused
```suggestion
```
…in diff_S1128.json and autoscan-diff-by-rules.json to match actual autoscan results after adding the S8912 test source file
@sonarqube-next

Copy link
Copy Markdown

@NoemieBenard NoemieBenard left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants