Skip to content

SONARJAVA-6222 Extend ProfileRegistrar to register rules for specific quality profiles#5749

Merged
aurelien-coet-sonarsource merged 1 commit into
masterfrom
ac/SONARJAVA-6222
Jul 7, 2026
Merged

SONARJAVA-6222 Extend ProfileRegistrar to register rules for specific quality profiles#5749
aurelien-coet-sonarsource merged 1 commit into
masterfrom
ac/SONARJAVA-6222

Conversation

@aurelien-coet-sonarsource

@aurelien-coet-sonarsource aurelien-coet-sonarsource commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary by Gitar

  • API enhancements:
    • Added registerRules(String qualityProfileName, Collection<RuleKey> ruleKeys) to ProfileRegistrar.RegistrarContext.
    • Updated registerDefaultQualityProfileRules to delegate to registerRules for the "Sonar way" profile.
  • Internal refactoring:
    • Modified BuiltInJavaQualityProfile to filter registered rules by profile name and avoid leakage between profiles.
    • Updated JavaAgenticAIProfile and JavaSonarWayProfile to use static constants for profile names and paths.
  • Test infrastructure:
    • Updated TestProfileRegistrarContext to support rule registration mapping for multiple distinct quality profiles.
    • Added verification tests in JavaAgenticWayProfileTest and JavaSonarWayProfileTest to ensure cross-profile isolation.

This will update automatically on new commits.

Comment thread sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSonarWayProfile.java Outdated
@gitar-bot

gitar-bot Bot commented Jul 7, 2026

Copy link
Copy Markdown
Code Review 👍 Approved with suggestions 3 resolved / 4 findings

Extends the ProfileRegistrar interface to support rule registration for specific quality profiles, improving isolation between profile implementations. The debug log regarding skipped registration should be guarded to match the actual execution flow.

💡 Quality: Debug log claims to skip but doesn't guard registration

📄 sonar-java-plugin/src/main/java/org/sonar/plugins/java/BuiltInJavaQualityProfile.java:92-97

The log message says "skipping rules registration" but the code does not actually branch/return based on DEFAULT_PROFILES.contains(qualityProfileName). The subsequent if (qualityProfileName.equals(getProfileName())) is what effectively filters registration, and since getProfileName() is always one of the DEFAULT_PROFILES, unknown names are inherently never matched. This works, but the log fires independently of the actual filter, and the two conditions are redundant/decoupled. Consider combining them (e.g. log inside an else of the equals check, or return early) so the message accurately reflects control flow and unknown-profile handling is explicit.

✅ 3 resolved
Quality: Test double diverges from production for unknown profile names

📄 java-checks-testkit/src/main/java/org/sonar/java/checks/verifier/TestProfileRegistrarContext.java:31-38 📄 sonar-java-plugin/src/main/java/org/sonar/plugins/java/BuiltInJavaQualityProfile.java:90-94
TestProfileRegistrarContext.registerRules throws IllegalArgumentException for any profile name other than the two hard-coded strings ("Sonar way", "Sonar agentic AI"). Production code in BuiltInJavaQualityProfile.registerRulesFromJson instead silently ignores rules registered for a non-matching profile name (the qualityProfileName.equals(getProfileName()) check simply skips them).

This behavioral divergence means a ProfileRegistrar that registers rules for some other profile name would run fine in production but cause a rule developer's unit test (using this testkit double) to fail with an exception — or vice versa, a typo'd profile name is silently dropped in production but loudly caught only in tests. Consider making the test double record rules per arbitrary profile name (e.g. a Map<String, Set<RuleKey>>) rather than hard-coding two names and throwing, so the double mirrors production semantics.

Edge Case: Rules registered for unknown profile name are silently dropped

📄 sonar-java-plugin/src/main/java/org/sonar/plugins/java/BuiltInJavaQualityProfile.java:90-94
In registerRulesFromJson, if a ProfileRegistrar calls registerRules with a profile name that does not exactly match any getProfileName() (e.g. a typo, wrong casing like "Sonar Way" vs "Sonar way", or a profile that does not exist), the rule keys are silently discarded with no log message. Since the Javadoc states the name must match the RSPEC defaultQualityProfiles metadata, a mismatch is a likely and easy-to-make configuration error that would go completely undetected. Consider logging at debug/warn level when a registrar targets a profile name that matches none of the defined Java profiles, to aid diagnosis.

Bug: Path.of().toString() breaks classpath resource loading on Windows

📄 sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSonarWayProfile.java:33 📄 sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaAgenticAIProfile.java:28
SONAR_WAY_PATH and SONAR_AGENTIC_PATH were changed from plain string literals to Path.of("/org/sonar/l10n/...").toString(). On Windows, Path.of(...).toString() uses the platform separator, producing \org\sonar\l10n\... instead of /org/sonar/l10n/.... These constants are used as classpath resource paths — SONAR_WAY_PATH is passed to RuleMetadataLoader and to BuiltInQualityProfileJsonLoader.loadActiveKeysFromJsonProfile(pathToJsonProfile) (via getPathToJsonProfile()), both of which load resources via getResourceAsStream, which requires forward slashes on all platforms. With backslashes the resource lookup returns null and profile/rule loading fails on Windows. The Path.of(...).toString() wrapper adds no value over the original literal and introduces a platform-dependent regression. Revert to the plain string literals.

🤖 Prompt for agents
Code Review: Extends the ProfileRegistrar interface to support rule registration for specific quality profiles, improving isolation between profile implementations. The debug log regarding skipped registration should be guarded to match the actual execution flow.

1. 💡 Quality: Debug log claims to skip but doesn't guard registration
   Files: sonar-java-plugin/src/main/java/org/sonar/plugins/java/BuiltInJavaQualityProfile.java:92-97

   The log message says "skipping rules registration" but the code does not actually branch/return based on `DEFAULT_PROFILES.contains(qualityProfileName)`. The subsequent `if (qualityProfileName.equals(getProfileName()))` is what effectively filters registration, and since `getProfileName()` is always one of the DEFAULT_PROFILES, unknown names are inherently never matched. This works, but the log fires independently of the actual filter, and the two conditions are redundant/decoupled. Consider combining them (e.g. log inside an `else` of the equals check, or return early) so the message accurately reflects control flow and unknown-profile handling is explicit.

Options

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

Comment with these commands to change the behavior for this request:

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

Was this helpful? React with 👍 / 👎 | Gitar

@mallory-scotton mallory-scotton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@sonarqube-next

sonarqube-next Bot commented Jul 7, 2026

Copy link
Copy Markdown

@aurelien-coet-sonarsource aurelien-coet-sonarsource merged commit aa41f3e into master Jul 7, 2026
15 checks passed
@aurelien-coet-sonarsource aurelien-coet-sonarsource deleted the ac/SONARJAVA-6222 branch July 7, 2026 12:14
@gitar-bot

gitar-bot Bot commented Jul 7, 2026

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

Extends the ProfileRegistrar interface to support rule registration for specific quality profiles, ensuring isolation between profiles. Resolved issues regarding path handling, logging, and inconsistent test behavior.

✅ 4 resolved
Quality: Test double diverges from production for unknown profile names

📄 java-checks-testkit/src/main/java/org/sonar/java/checks/verifier/TestProfileRegistrarContext.java:31-38 📄 sonar-java-plugin/src/main/java/org/sonar/plugins/java/BuiltInJavaQualityProfile.java:90-94
TestProfileRegistrarContext.registerRules throws IllegalArgumentException for any profile name other than the two hard-coded strings ("Sonar way", "Sonar agentic AI"). Production code in BuiltInJavaQualityProfile.registerRulesFromJson instead silently ignores rules registered for a non-matching profile name (the qualityProfileName.equals(getProfileName()) check simply skips them).

This behavioral divergence means a ProfileRegistrar that registers rules for some other profile name would run fine in production but cause a rule developer's unit test (using this testkit double) to fail with an exception — or vice versa, a typo'd profile name is silently dropped in production but loudly caught only in tests. Consider making the test double record rules per arbitrary profile name (e.g. a Map<String, Set<RuleKey>>) rather than hard-coding two names and throwing, so the double mirrors production semantics.

Edge Case: Rules registered for unknown profile name are silently dropped

📄 sonar-java-plugin/src/main/java/org/sonar/plugins/java/BuiltInJavaQualityProfile.java:90-94
In registerRulesFromJson, if a ProfileRegistrar calls registerRules with a profile name that does not exactly match any getProfileName() (e.g. a typo, wrong casing like "Sonar Way" vs "Sonar way", or a profile that does not exist), the rule keys are silently discarded with no log message. Since the Javadoc states the name must match the RSPEC defaultQualityProfiles metadata, a mismatch is a likely and easy-to-make configuration error that would go completely undetected. Consider logging at debug/warn level when a registrar targets a profile name that matches none of the defined Java profiles, to aid diagnosis.

Bug: Path.of().toString() breaks classpath resource loading on Windows

📄 sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSonarWayProfile.java:33 📄 sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaAgenticAIProfile.java:28
SONAR_WAY_PATH and SONAR_AGENTIC_PATH were changed from plain string literals to Path.of("/org/sonar/l10n/...").toString(). On Windows, Path.of(...).toString() uses the platform separator, producing \org\sonar\l10n\... instead of /org/sonar/l10n/.... These constants are used as classpath resource paths — SONAR_WAY_PATH is passed to RuleMetadataLoader and to BuiltInQualityProfileJsonLoader.loadActiveKeysFromJsonProfile(pathToJsonProfile) (via getPathToJsonProfile()), both of which load resources via getResourceAsStream, which requires forward slashes on all platforms. With backslashes the resource lookup returns null and profile/rule loading fails on Windows. The Path.of(...).toString() wrapper adds no value over the original literal and introduces a platform-dependent regression. Revert to the plain string literals.

Quality: Debug log claims to skip but doesn't guard registration

📄 sonar-java-plugin/src/main/java/org/sonar/plugins/java/BuiltInJavaQualityProfile.java:92-97
The log message says "skipping rules registration" but the code does not actually branch/return based on DEFAULT_PROFILES.contains(qualityProfileName). The subsequent if (qualityProfileName.equals(getProfileName())) is what effectively filters registration, and since getProfileName() is always one of the DEFAULT_PROFILES, unknown names are inherently never matched. This works, but the log fires independently of the actual filter, and the two conditions are redundant/decoupled. Consider combining them (e.g. log inside an else of the equals check, or return early) so the message accurately reflects control flow and unknown-profile handling is explicit.

Options

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

Comment with these commands to change the behavior for this request:

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

Was this helpful? React with 👍 / 👎 | Gitar

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