The strangeness begins with "static" base class members should not be accessed via derived types java:S3252 being reported for code that looks like this:
@Data
@SuperBuilder
public class MySuperClass {
@Builder.Default
private Optional<String> foo = Optional.empty();
}
@Data
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class MySubClassOne extends MySuperClass {
@Builder.Default
private Optional<String> bar = Optional.empty();
}
@Data
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class MySubClassTwo extends MySuperClass {
@Builder.Default
private Optional<String> baz = Optional.empty();
}
MySubClassOne.builder().build(); <- issue here
MySubClassTwo.builder().baz("baz").build(); <- but not here
So far this seems like an ordinary false positive. But then I made a small change to one of the classes, so that it looks like this:
@Data
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class MySubClassOne extends MySuperClass {
@Builder.Default
@Nullable
private String bar = null;
public Optional<String> getBar() {
return Optional.ofNullable(bar);
}
}
This did not resolve the initial (false positive) issue, but it did cause 3 completely unrelated issues to be falsely marked as resolved (false negative).
In a file which uses a renamed getter in MySubClassOne (and no other changes), 3 issues marked as resolved:
// Annotate the parameter with @javax.annotation.Nullable in method 'itemCategory' declaration, or make sure that null can not be passed as argument.
// contextData.itemCategory is still annotated as @Nullable, and the field in the builder is still annotated @NonNull
.itemCategory(contextData.getItemCategory())
...
/// A "NullPointerException" could be thrown; "getLogo()" can return null.
// contextData.logo is still annotated as @Nullable
builder.logoUrl(contextData.getLogo().toString());
...
// Remove this expression which always evaluates to "true"
// The issue was not fixed, contextData.backgroundImage is still annotated @NonNull
if (contextData.getBackgroundImage() != null) {
I’m using org.projectlombok 1.18.36 and gradle plugin io.freefair.lombok 8.11.
But as I said, the behavior of sonar in the surrounding code is very strange and reproducing likely requires some highly specific thing that is not obvious. I’ve played around with it a bit more and found this:
MySubClassOne.builder().build(); // Issue here in one file
MySubClassTwo.builder().build(); // But not here in another file
So I tried adding the MySubClassTwo.builder directly above the MySubClassOne.builder in the same file, and it caused the original false positive to be resolved as fixed.
And also 3 other totally unrelated issues in the same file were incorrectly marked as resolved (the same 3 false negatives I mentioned in my original post)
I just tried adding a single line of whitespace above the line with the false positive and got the same result. False positive resolved, and 3 real issues falsely resolved.
I haven’t tried merging this whitespace change so maybe (if the file with the false positive is changed in anyway) the PR analyzer fixes (by not reporting) the false positive but also creates 3 false negatives (by not being able to see them due to correct analysis requiring it to be able to see other not-changed files).
Whereas the main branch analyzer creates the false positive (due to unknown reasons) but fixes the 3 false negatives (by comprehensively analyzing the related classes?
I attempted again to reproduce the problem, but was unable to do so. Whitespaces should not matter. Since at this point we do not have an easily reproducible example, I will not be able to file a ticket for it.
That said, we appreciate your report! If we come across another instance of the issue, we may be able to revisit it.