Skip to content

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

Open
romainbrenguier wants to merge 2 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 2 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.
  • Implementation Assets:
    • Added stub annotations Mapper.java and DaoFactory.java for test source compilation.
    • Provided MapperWithoutDaoFactoryCheckSample.java covering compliant and noncompliant scenarios.
    • 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
@sonarqube-next

Copy link
Copy Markdown

Quality Gate failed Quality Gate failed

Failed conditions
83.3% Coverage on New Code (required ≥ 90%)

See analysis details on SonarQube

romainbrenguier and others added 2 commits June 24, 2026 17:19
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>
@romainbrenguier romainbrenguier force-pushed the new-rule/SONARJAVA-6490-S8910 branch from 50364f5 to 5ad2ff5 Compare June 24, 2026 15:20
Comment on lines +57 to +71
private static boolean hasDaoFactoryMethod(Symbol.TypeSymbol typeSymbol, Set<Symbol.TypeSymbol> visited) {
if (!visited.add(typeSymbol)) {
return false;
}

if (typeSymbol.memberSymbols().stream()
.filter(Symbol::isMethodSymbol)
.map(Symbol.MethodSymbol.class::cast)
.anyMatch(MapperWithoutDaoFactoryCheck::hasDaoFactoryAnnotation)) {
return true;
}

for (Type superType : typeSymbol.superTypes()) {
Symbol.TypeSymbol superTypeSymbol = superType.symbol();
if (!superTypeSymbol.isUnknown() && hasDaoFactoryMethod(superTypeSymbol, visited)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

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.

Was this helpful? React with 👍 / 👎

@gitar-bot

gitar-bot Bot commented Jun 24, 2026

Copy link
Copy Markdown
CI failed: The CI pipeline failed due to a blocking `ImportError` in the orchestration test suite and intermittent infrastructure issues downloading dependencies. The import error is caused by a missing or renamed `IngestionFolder` component, while intermittent 429 errors from package repositories are preventing successful builds.

Overview

Multiple failures were detected in the CI pipeline. The primary blocker is a persistent ImportError during test collection, likely caused by a code refactor affecting imports. Additionally, infrastructure-level rate limiting (HTTP 429) was observed when fetching dependencies from remote repositories.

Failures

Test Collection Failure: ImportError (confidence: high)

  • Type: test
  • Affected jobs: orchestration test jobs
  • Related to change: yes
  • Root cause: The orchestration module fails to collect tests because IngestionFolder can no longer be imported from orchestration.run_folder. This is likely a result of recent changes or refactoring in that file.
  • Suggested fix: Verify if IngestionFolder was renamed, moved, or deleted in orchestration/src/orchestration/run_folder.py. Update the import statement in orchestration/src/orchestration/status.py accordingly.

Dependency Resolution Failure (confidence: high)

  • Type: infrastructure
  • Affected jobs: various build jobs
  • Related to change: no
  • Root cause: Transient '429 Too Many Requests' errors while fetching dependencies from Maven Central and Gradle Plugin repositories.
  • Suggested fix: This is a known infrastructure instability. Rerunning the failed jobs should resolve the issue once the rate limit reset period passes.

Package Installation Conflict (confidence: high)

  • Type: build
  • Affected jobs: update-recordings
  • Related to change: no
  • Root cause: The rule-identification package is marked as --no-build for editable installation, causing installation to fail because no binary distribution is available.
  • Suggested fix: Review the pyproject.toml or install.sh configuration for rule-identification to ensure editable installs are supported correctly for this environment.

Summary

  • Change-related failures: 1 (Test collection error in orchestration module)
  • Infrastructure/flaky failures: 2 (Repository rate limiting and packaging configuration conflict)
  • Recommended action: First, fix the IngestionFolder import error in the codebase. Then, perform a fresh retry of the build to clear the transient infrastructure issues.
Code Review 👍 Approved with suggestions 3 resolved / 4 findings

Implements rule S8910 to validate @Mapper interfaces for required @DaoFactory methods, resolving issues with inherited methods and quality profile registration. Review potential false positives when checking interfaces that extend unresolved supertypes.

💡 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.

✅ 3 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.

🤖 Prompt for agents
Code Review: Implements rule S8910 to validate @Mapper interfaces for required @DaoFactory methods, resolving issues with inherited methods and quality profile registration. Review potential false positives when checking interfaces that extend unresolved supertypes.

1. 💡 Edge Case: Possible false positives when @Mapper extends unresolved supertypes
   Files: 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.

Tip

Comment Gitar fix CI or enable auto-apply: gitar auto-apply:on

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

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