Skip to content

SONARJAVA-6490 Implement S8910: Interfaces with @Mapper should have @DaoFactory methods#5690

Open
romainbrenguier wants to merge 9 commits into
masterfrom
new-rule/SONARJAVA-6490-S8910
Open

SONARJAVA-6490 Implement S8910: Interfaces with @Mapper should have @DaoFactory methods#5690
romainbrenguier wants to merge 9 commits into
masterfrom
new-rule/SONARJAVA-6490-S8910

Conversation

@romainbrenguier

@romainbrenguier romainbrenguier commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements rule S8910 to detect interfaces annotated with @Mapper that don't contain at least one @DaoFactory method.

Implementation

  • Rule type: CODE_SMELL
  • Severity: Major
  • Detection: Checks interfaces with @Mapper annotation for presence of @DaoFactory methods
  • Follows patterns from similar annotation-checking rules (e.g., S7180)

Status

WIP - Implementation incomplete after initial attempts. Requires review and completion.

🤖 Generated with Claude Code


Summary by Gitar

  • Rule Metadata:
    • Added rule S8910 to Sonar_way_profile.json and Sonar_agentic_AI_profile.json.
    • Created S8910.html and S8910.json for rule documentation and configuration.
  • CI/Test Infrastructure:
    • Created diff_S8910.json for autoscan verification.
    • Updated JavaAgenticWayProfileTest to validate the new rule integration.
    • Updated build.yml to use Java 26.
  • Implementation Assets:
    • Added stub annotations Mapper.java and DaoFactory.java for test source compilation.
    • Provided MapperWithoutDaoFactoryCheckSample.java and non-compiling/checks/MapperWithoutDaoFactoryCheckSample.java covering edge cases.
    • Implemented MapperWithoutDaoFactoryCheck.java and corresponding unit tests.

This will update automatically on new commits.

@hashicorp-vault-sonar-prod

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

Copy link
Copy Markdown
Contributor

SONARJAVA-6490

Comment thread java-checks/src/main/java/org/sonar/java/checks/MapperWithoutDaoFactoryCheck.java Outdated
@romainbrenguier romainbrenguier force-pushed the new-rule/SONARJAVA-6490-S8910 branch from 134235b to dd242b4 Compare June 23, 2026 12:36
Comment thread fix-unit-tests/test-output.log Outdated
@romainbrenguier romainbrenguier force-pushed the new-rule/SONARJAVA-6490-S8910 branch from 54d1175 to d2cecff Compare June 24, 2026 07:04
@romainbrenguier romainbrenguier marked this pull request as ready for review June 24, 2026 08:27
@romainbrenguier romainbrenguier force-pushed the new-rule/SONARJAVA-6490-S8910 branch from 50364f5 to 5ad2ff5 Compare June 24, 2026 15:20
Comment thread java-checks/src/main/java/org/sonar/java/checks/MapperWithoutDaoFactoryCheck.java Outdated
@romainbrenguier romainbrenguier removed the request for review from NoemieBenard June 25, 2026 08:16
romainbrenguier and others added 5 commits June 25, 2026 10:24
Add comprehensive test cases to improve code coverage:
- Multi-level inheritance (interface extending interface extending base)
- Multiple inheritance (interface extending multiple interfaces)
- Extending unknown type (to test isUnknown branch)
- Complex inheritance with mixed scenarios

These additions help reach the 90% code coverage threshold
required by the SonarQube quality gate.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
When a @Mapper interface extends an unresolved type (e.g., due to
incomplete classpath), assume it might provide the required @DaoFactory
method to avoid false positives. This conservative approach prioritizes
precision over recall in real-world scenarios where classpaths may be
incomplete.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
When a @Mapper interface explicitly extends other interfaces and one
of them is unresolved (e.g., due to incomplete classpath), assume it
might provide the required @DaoFactory method to avoid false positives.

This conservative approach only applies when the interface has explicit
extends clauses, not for interfaces with no supertypes, ensuring we
still catch genuine violations while avoiding noise in projects with
incomplete classpaths.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@romainbrenguier romainbrenguier force-pushed the new-rule/SONARJAVA-6490-S8910 branch from a303d8a to 13bbacd Compare June 25, 2026 08:31
romainbrenguier and others added 4 commits June 25, 2026 10:55
Added test cases to cover additional code paths:
- Non-compiling test for unresolved supertypes scenario
- Deep inheritance chain test case
- Circular reference base test case

This improves code coverage to meet the 90% quality gate threshold.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added diamond inheritance pattern to test the visited set logic
when the same interface is encountered multiple times through
different inheritance paths.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added diamond inheritance pattern without @DaoFactory to ensure
the visited set logic is exercised when traversing all branches
looking for the required annotation.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@gitar-bot

gitar-bot Bot commented Jun 25, 2026

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

Implements rule S8910 to validate @Mapper interfaces require at least one @DaoFactory method, resolving previously identified gaps in profile integration, inheritance handling, and type-specific coverage.

✅ 4 resolved
Quality: Rule S8910 not added to a quality profile

📄 sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8910.json:10
S8910.json and the check exist, but S8910 does not appear in Sonar_way_profile.json (or other profile JSONs). A rule that is not added to any profile will not be activated by default, so the new check effectively never runs for users. If the rule is meant to be active (status is "ready"), add S8910 to the appropriate profile JSON. This may be intentional given the PR is a WIP draft, but should be resolved before merge.

Edge Case: Inherited @DaoFactory methods from super-interfaces ignored

📄 java-checks/src/main/java/org/sonar/java/checks/MapperWithoutDaoFactoryCheck.java:47-50
visitNode only inspects classTree.members() (the directly declared members of the interface). A @Mapper interface that declares no @DaoFactory method itself but extends a base interface providing one would be flagged as noncompliant, producing a false positive. The test sample's ExtendingMapper happens to extend an empty BaseInterface, so this case is not covered. Consider resolving the interface hierarchy (e.g. via the symbol's super types / all members) or add a test for an extended interface whose parent declares a @DaoFactory method to confirm intended behavior.

Edge Case: @Mapper on class/enum/record not handled or documented

📄 java-checks/src/main/java/org/sonar/java/checks/MapperWithoutDaoFactoryCheck.java:34-37 📄 java-checks-test-sources/default/src/main/java/checks/MapperWithoutDaoFactoryCheckSample.java:78-88
nodesToVisit returns only Tree.Kind.INTERFACE, so @Mapper applied to a class, enum, or record (as in the test sample's MapperClass, MapperEnum, MapperRecord) is silently ignored. This is likely intentional since @Mapper targets interfaces, but the sample includes these cases without // Noncompliant markers as implicit documentation of intent. Consider a brief comment clarifying that only interfaces are checked, to avoid future confusion about whether these are deliberate non-detections.

Edge Case: Possible false positives when @Mapper extends unresolved supertypes

📄 java-checks/src/main/java/org/sonar/java/checks/MapperWithoutDaoFactoryCheck.java:57-71 📄 java-checks-test-sources/default/src/main/java/checks/MapperWithoutDaoFactoryCheckSample.java:129-131
In hasDaoFactoryMethod, any super type whose symbol isUnknown() is silently skipped (MapperWithoutDaoFactoryCheck.java:69-74). As a result, when a @Mapper interface extends a type that the analyzer cannot resolve (e.g. incomplete classpath, missing dependency), the check assumes the supertype contributes no @DaoFactory method and reports the interface as noncompliant. The test sample even encodes this behaviour (ExtendingNonExistentType extends UnknownType is marked Noncompliant at MapperWithoutDaoFactoryCheckSample.java:129-131). In real projects with an incomplete classpath this can produce false positives, since the unresolved supertype may actually declare the required @DaoFactory method. Consider suppressing the issue (or treating it as unknown/compliant) when the interface has at least one unresolved supertype, to avoid noisy false positives.

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

@sonarqube-next

Copy link
Copy Markdown

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.

1 participant