Rule java:S5411 reports an issue when calling a Boolean returning method, even though the method is declared inside a JSpecify @NullMarked class and its return type is non-null by default.
Adding an explicit @NonNull annotation to the return type suppresses the issue. Under JSpecify, these two declarations f1 and f2 have the same nullness (non-null) contract.
// BooleanProvider.java
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.NullMarked;
@NullMarked
public class BooleanProvider {
public Boolean f1() {
return Boolean.TRUE;
}
public @NonNull Boolean f2() {
return Boolean.TRUE;
}
}
// BooleanConsumer.java
public class BooleanConsumer {
public void example(BooleanProvider provider) {
if (provider.f1()) { // False positive: java:S5411
System.out.println("f1");
}
if (provider.f2()) { // No issue
System.out.println("f2");
}
}
}
In BooleanConsumer, S5411 reports an issue on (provider.f1()), but not on (provider.f2()).
Expected: Neither invocation should trigger S5411, because unannotated types within a @NullMarked scope are treated as non-null.
Possible cause
In the S5411 implementation, isAnnotatedNonnull() checks direct symbol annotations for the names NonNull and NotNull. It appears that this check does not account for the non-null default established by the scope enclosing the method declaration.