S2259 - False positive with System.exit()

Hello. I have a couple of NPEs (S2259) being reported as Sonar fails to recognize a call to System.exit(int) is being made. Example:

S2259Demo.java

public class S2259Demo {

  public static void terminate() {
    System.exit(0);
  }

  public static void right() {
    String s = null;
    terminate();
    System.out.println(s.length()); // Sonar: OK
  }

  public static void wrong() {
    String s = null;
    Utils.terminate();
    System.out.println(s.length()); // Sonar: "s" is nullable here
  }

}

Utils.java

public final class Utils {

  public static void terminate() {
    System.exit(0);
  }
}

I analyzed the same code with FindBugs and I get no NPE warning as with Sonar.

Is this something you can fix or that I can get around somehow? Thanks!

Versions used:

  • SonarLint 4.2.0.3434
  • SonarQube Community Edition Version 7.7 (build 23042)
  • SonarJava 5.13.1 (build 18282)

Hello @pvaldv,

Thanks for the feedback.

Rule S2259 is relying on SonarJava’s Symbolic Execution (SE) engine. This engine is proceeding to a context-sensitive, path-sensitive data flow analysis to detect NPEs in source code. While this SE engine is also cross-procedural, which allows it to detect usage of System.exit() in some other methods being called from within the method under analysis, it is unfortunately not supporting cross-file analysis, and therefore can not follow execution path when jumping from a file to another.

In you context, this means that SonarJava will behave correctly in case of having the utility method terminate() placed in the same file under analysis, but this won’t be the case when placed outside… Ultimately leading to the FP. Similarly you would have observed the same behavior if the method was placed in an external dependency.

Unfortunately, there is not much you can do at the point, except closing the issue as FP. We don’t plan to work on this at short term, but be sure this is a known and annoying limitation.

Hope this helps,
Michael