S2259 - FP with static fields in an interface

versions used (SonarQube, Scanner, language analyzer)

SonarQube: 8.7.0.41497
SonarLint: 4.14.2.28348
Intellij IDEA: 2020.3.3
Scanner: 3.1.1

minimal code sample

For reproducing the FP, an Java Interface with some static final Strings must be used, which is located in a different package than the Java class in which the issue is reported.

This is the Interface used:

package de.empic.web.core.validation;

public interface SonarTest
{
    String SONAR_TEST = "sonar_test";
}

The FP Issue is reported in the following class:

1  package de.empic.web.core.util;
2  
3  import java.util.Date;
4  
5  import de.empic.web.core.validation.SonarTest;
6  
7  public class S2259Demo
8  {
9    public String someMethod()
10     {
11      String testString = null;
12      if (checkSomeCondition(new Date()))
13       {
14          testString = SonarTest.SONAR_TEST;
15       }
16       if (testString == null)
17       {
18          if (checkSomeCondition(new Date()))
19          {
20             testString = SonarTest.SONAR_TEST;
21          }
22       }
23       if (SonarTest.SONAR_TEST.equals(testString))
24       {
25          return "test2";
26      }
27      return "n/a";
28   }
29 
30    private boolean checkSomeCondition(Date testDate)
31    {
32       return testDate.after(new Date());
33    }
34 
35 }

Result of the SonarQube Analysis

Analyzing this code with SonarQube/SonarLint results in the following Issue:

Why is this a FP

IMHO this is a FP, as the string constant “SonarTest.SONAR_TEST” never can be null. I assume the rule inferes from the null-Check in line 16 after the possible Assignment in Line 14, that SonarTest.SONAR_TEST might be null. But as there is a string value statically assigned in the interface, it should be possible to check that.

It depends on a condition, whether the static value is really assigned to the “testString” variable in line 14.

At least the error message is not correct - the interface cannot be nullable.

One more information that might be important: If I move the interface into the same package as the class where it is used, no issue is raised.

Hello @tschindler

Thanks for this clear description of the problem. Indeed, there is something wrong happening there. I did not manage to fully understand the problem yet, but I managed to create a simplified reproducer, similar to what you described:

public class NpeEx {
  static final String SONAR_TEST = "sonar_test";
}

class S2259Demo {
  public void someMethod(boolean cond) {
    String testString = null;
    if (cond) {
      testString = NpeEx.SONAR_TEST;
    }
    if (testString == null) {
      // Do something
    }
    if (NpeEx.SONAR_TEST.equals(testString)) { // FP, constant can not be nullable
      // Do something
    }
  }
}

It seems to be related to a known problem: SONARJAVA-3691. I added the two examples there, to make sure the fix will support these cases when we will investigate further.

Thank you and have a nice day.
Quentin

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.