org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:5.1.0.4882
SonarCloud is flagging code with java:S2259, indicating that a NullPointerException could occur because map() can return null. However, this is a false positive in this instance. The rule incorrectly identifies the potential for a null return, despite Optional.ofNullable ensuring that the code will not produce a NullPointerException.
Code Sample:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.Optional;
public class ExampleClass {
public static void main(String[] args) throws IOException {
Document document = Jsoup.connect("https://www.sonarsource.com/").get();
Optional<String> value = new ExampleClass().parse(document);
System.out.println(value);
}
private Optional<String> parse(Document rootDocument) {
return Optional.ofNullable(rootDocument)
.map(document -> document.getElementsByClass("ety5px91 css-1xx1qgu e1gts9nz0"))
.filter(elements -> !elements.isEmpty())
.map(Elements::last)
.map(Element::text);
}
}
Explanation:
In this example:
The method parse(Document rootDocument) uses Optional.ofNullable() to handle the case where rootDocument could be null.
Each subsequent map() operation is safely chained, returning an empty Optional if any step results in null, rather than throwing a NullPointerException.
Expected Behavior:
SonarCloud should recognize that Optional.ofNullable and subsequent transformations do not produce a NullPointerException, making this rule’s flagging here inaccurate.
Impact:
This false positive may lead developers to refactor code unnecessarily, impacting productivity.
Could you please review this behavior and suggest a way to handle such cases without suppressing the rule for legitimate cases?
Thank you.
Getting “A “NullPointerException” could be thrown; “tb” is nullable here.” from
if (Optional.ofNullable(tb).map(val -> val.getFrom()).map(EReference.class::isInstance).orElse(false)) {
EStructuralFeature feature = (EStructuralFeature)tb.getTo();
Error is reported on tb.getTo()
Since tb is checked with Optional for nullable and if optional is empty we return false, we can’t get to the next line and have a nullable tb
Using:
SonarLint for Eclipse 10.9.1.82333
ganncamp
(G Ann Campbell)
November 20, 2024, 3:37pm
4
Hi,
You haven’t provided the rule ID, so I can’t be sure, but I suspect this is the same issue…?
Reproduced this in SonarLint for Eclipse 10.8.0.82289.
There are cases where the rule “S3655: Optional value should only be accessed after calling isPresent()” produces a false-positive when we could logically reason that the accessed value is present at that point.
Take the following simplified example:
private String test()
{
Optional<String> opt = getOptString(); // Get an Optional from somewhere.
if ( opt.map( String::toLowerCase ).filter( s -> s.equals( "test" ) ).isPresent()…
Ann
ganncamp
(G Ann Campbell)
November 20, 2024, 4:25pm
7
Hi @Alain_Picard ,
Thanks for the rule ID. I’ve combined your thread with another about the same rule.
Ann
nelkahn
(Daniel Robinson)
February 3, 2025, 2:43pm
9
Is there any feedback on this issue? I am having the same issue on map() possibly causing a NullPointerException.
I have a very simple test class with no external dependencies if that is useful.
Kind regards,
ganncamp
(G Ann Campbell)
February 3, 2025, 3:06pm
10
Hi,
Would you mind posting your test class?
Thx,
Ann
nelkahn
(Daniel Robinson)
February 3, 2025, 3:23pm
11
Hi,
Yes no problem :
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
public class S2259Test {
public class TestObject {
@Nullable String value;
public @Nullable String getValue() {
return this.value;
}
}
public static void main(String[] args) {
List<@NonNull TestObject> testObjects = new ArrayList<>();
// FP : A "NullPointerException" could be thrown; "map()" can return null.
String result = testObjects.stream()
.findAny()
.map(t -> t.getValue())
.orElse(null);
System.out.println(result);
}
}
map() can never return null, by contract. It can throw a NullPointerException if the argument is null, which is not the case here.
Kind regards,
1 Like