[hyddd的Fortify SCA分析Java代码记录][Control Flow]Unreleased Resource
2009-02-25 14:09 hyddd 阅读(2595) 评论(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;
}
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);
}
}
}
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);
}
}
}
作者:hyddd
出处:http://www.cnblogs.com/hyddd/
本文版权归作者所有,欢迎转载,演绎或用于商业目的,但是必须说明本文出处(包含链接)。