Right now the only way to get SL to be quiet, short of disabling the warning altogether, is nonsense like requireNonNull(requireNonNullElse(…)). Would really love to be able to stop doing that.
Thanks! SL has been such a huge timesaver for us; really appreciate all the work you put into it!
var matcher = DATA_URI_PATTERN.matcher(Objects.requireNonNullElse(jobOutput.getResource(), EMPTY_URI).toString());
The only possible way the issue is raised is in case there is no check about jobOutput being non-null before invoking the getResource() method.
I used the following example to verify the possible use cases to be covered:
void notRepoducer(@Nullable String x) {
Pattern pattern = Pattern.compile(".*.json");
var matcher = pattern.matcher(Objects.requireNonNullElse(x, "")); // no issue
matcher = pattern.matcher(Objects.requireNonNullElse(x.toLowerCase(), "")); // issue, because x can be null
assert x != null;
matcher = pattern.matcher(Objects.requireNonNullElse(x.toLowerCase(), "")); // no issue, because x I checked to not be null
}
Can you ensure that the jobOutput is not null before the line is raised as an issue?
I can confirm that jobOutput can not be null at that location. It has been deferenced a couple of lines above already and it’s the result of a Objects.requireNonNull call. Also the error messages explicitly mentions that requireNonNullElse can return null, it does not say anything about jobOutput.
The rule has been reworked recently, so I would recommend you update to the latest version of Sonar Qube, if possible. Alternatively, you can update the sonar-java plugin to the latest version by following the install a plugin guide. The sonar-java plugin releases are available on GitHub at sonar-java/releases.
For the sake of completeness, I checked also the case when Objects.requireNonNull is used:
void notRepoducer(@Nullable String x) {
Pattern pattern = Pattern.compile(".*.json");
var xx = Objects.requireNonNull(x);
var matcher = pattern.matcher(Objects.requireNonNullElse(x.toLowerCase(), "")); // no issue
matcher = pattern.matcher(Objects.requireNonNullElse(xx.toLowerCase(), "")); // no issue
}
In case you’re not able to fix the problem by updating to the latest versions, I would suggest providing a code example where the issue is reproduced.
I’m using sonarsource.sonarlint-vscode-3.19.2-darwin-arm64 and I’m still seeing the issue. Do you know which version would represent the “latest version of Sonar Qube” for the VS Code extension?
Can you try to analyze the code example below and tell me what result you get from Sonar Lint?
void notRepoducer(@Nullable String x) {
Pattern pattern = Pattern.compile(".*.json");
var matcher = pattern.matcher(Objects.requireNonNullElse(x, "")); // no issue
matcher = pattern.matcher(Objects.requireNonNullElse(x.toLowerCase(), "")); // issue, because x can be null
assert x != null;
matcher = pattern.matcher(Objects.requireNonNullElse(x.toLowerCase(), "")); // no issue, because x I checked to not be null
}
On line 13 of CliMain.java, the warning is "Parameter 1 to this constructor is marked "@NonNull" but null could be passed.sonarlint(java:S2637)". However, it is not possible for jobId to be null at that point in the code, since Objects.requireNonNullElse() can never return null.
Thanks, @starkos for providing a reproducible example and you are correct: rule S2637 has a false positive in Sonar Lint that can be reproduced with the following code:
record Task(String id){}
static class Request {
public Request(@org.eclipse.jdt.annotation.NonNull String id){}
}
public Request prepareRequest(Task task)
{
var jobId = Objects.requireNonNullElse(task.id(), "0");
return new Request(jobId); // Compliant
}
I created SONARJAVA-4564 to investigate further the issue and fix it.
Thank you for reporting this elusive false positive