Product: SonarQube Community Build 26.5.0.122743
sonar-java version: sonar-java 8.29 (build 43460)
sonar-java SE version: sonar-java-symbolic-execution 8.16.4 (build 1912)
Java source level: 21 (javac 21, source/target 21)
Rule
java:S1186 — Methods should not be empty
Description
Rule java:S1186 raises a false positive on compact canonical constructors in Java records. While the constructor body appears syntactically empty ({}) at the AST level, it is not semantically empty. The Java compiler implicitly synthesizes the field assignments for every record component. Flagging the compact form while ignoring the semantically identical explicit form (this.a = a; this.b = b;) is inconsistent. This false positive is particularly disruptive when the compact constructor is intentionally declared solely to carry annotations (e.g., @QueryProjection in Querydsl or Jackson’s @JsonCreator).
Reproducer
public class SomeDtoHolder {
@java.lang.annotation.Target(java.lang.annotation.ElementType.CONSTRUCTOR)
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
public @interface QueryProjection {}
// BEFORE — flagged by java:S1186 (false positive)
public record SomeDtoA(int a, int b) {
@QueryProjection
public SomeDtoA {
}
}
// AFTER — NOT flagged, although behavior is identical
public record SomeDtoB(int a, int b) {
@QueryProjection
public SomeDtoB(int a, int b) {
this.a = a;
this.b = b;
}
}
}
Expected behavior
java:S1186 should not flag record compact canonical constructors, treating them as implicitly populated rather than truly empty methods.
Actual behavior
The rule triggers on the compact form public SomeDtoA {}, but accepts the equivalent explicit canonical constructor without raising an issue.