java:S2095 FP when closure is surrounded by null test?

I’m not sure if this is the same as (Misreport on rule "Resources should be closed (java:S2095)") or (S2095 FP in some cases) but I’m getting this instance of the unclosed-resource rule:

image

Here is the start of the finally clause:

image

Is SQ getting confused because we test for null first?

Also, (S2095 - PreparedStatement closure in finally ignored when not first line) presented a case with two resources being closed, and it was pointed out that the first closure could throw an error, thereby bypassing the second closure. If that were the case for our code, shouldn’t SQ attach the issue to the declaration of jbdcConn (which occurs in our try block a few lines above the declaration of sqlStatement) rather than the declaration of sqlStatement itself?

Hello @MisterPi ,

Sorry for the delay in answering you, and thank you for your patience. This looks like a FP from the rule, but I would need a complete reproducer to identify the cause and not some extract of both the closing parts and the creation of the statement. Screenshots are not good enough to investigate what makes the engine behaves that way.

Locally, with the latest version of our analyzer, I get an issue with the connection being not correctly closed with your finally block. However, I had to extrapolate and super-simplify the way your code is operating.

If you are still facing the issue, can you please provide a complete reproducer, and mention what version of SQ you are running?

Thanks,
Michael

FYI: the code I used based on the info ou gave:

  public final void m() {
    Connection conn = null;
    PreparedStatement prepareStatement = null;
    try {
      conn = DriverManager.getConnection(getConnectionUrl()); // True Positive by java:S2095 raised here
      prepareStatement = conn.prepareStatement(getSqlQuery()); // True Negative (no issue) here
    } catch (Exception e) {
      LOG.info("do something");
    } finally {
      try {
        if (prepareStatement != null) {
          prepareStatement.close(); // if this calls fails, then the connection is not closed
        }
        if (conn != null) {
          conn.close();
        }
      } catch (Exception e) {
        LOG.info("do something else");
      }
    }
  }