代码改变世界

[hyddd的Fortify SCA分析Java代码记录][Control Flow]Unreleased Resource

2009-02-25 14:09  hyddd  阅读(2248)  评论(0编辑  收藏

  这个问题和FindBugs里面的[M X OBL] Method may fail to clean up stream or resource比较类似,可以参考一下:>

但是如果仔细看,Fortify和FindBugs在这个问题上还是有所不同的,Fortify会更严谨一些,先看看下面一段代码:

public static String getHttpRequestMsg(String url) {
        String szRetCode 
= "";
        String szTmp 
= "";
        HttpURLConnection httpUrl;
        
try {
            URL urlDest 
= new URL(url);
            httpUrl 
= (HttpURLConnection) urlDest.openConnection();
            httpUrl.getResponseMessage();

            InputStream input 
= httpUrl.getInputStream();

            
int nRead = 0;
            
byte[] b = new byte[1024];
            szTmp 
= "";
            
while ((nRead = input.read(b, 0, b.length)) > 0) {
                szTmp 
= new String(b, 0, nRead, "utf-8");
                szRetCode 
+= szTmp;
            }
            input.close();
        } 
catch (IOException e) {
    log.info("Error in
getHttpRequestMsg(). Error Message: ", e.toString);
        }

        
return szRetCode;
    }

Fortify在InputStream input = httpUrl.getInputStream();会报警告,说input可能没有被释放。

FindBugs在此处不会报异常。

  在代码中,明明写了input.close();,就是资源是有释放的!为什么Fortify还认为有问题呢,看解释,Fortify认为:如果在input.close();之前出现异常,会立即转入异常处理,input.close();就不会执行,即:input存在没能释放的可能性。

  所以Fortify建议如果要释放资源,最好把资源定义放在try{}catch{}外,并且在finally{}里面进行统一释放,如:

public void execCxnSql(Connection conn) {
    Statement stmt;
    
try {
      stmt 
= conn.createStatement();
      ResultSet rs 
= stmt.executeQuery(CXN_SQL);
      
    }
    
finally {
      
if (stmt != null) {
        safeClose(stmt);
      }
    }
}

public static void safeClose(Statement stmt) {
  
if (stmt != null) {
    
try {
      stmt.close();
    } 
catch (SQLException e) {
      log(e);
    }
  }
}