我目前正在开展一个项目,该项目使用 HP 的 Fortify SCA 工具来捕获代码库中的安全问题。我在确定正确处理 JDBC 资源的最佳方法时遇到了一些问题。
我现在的代码如下所示;
try (Connection conn = new DatabaseService().getConnection();
PreparedStatement ps = conn.prepareStatement(query);) {
ps.setString(1, mString);
try (ResultSet rs = ps.executeQuery();) {
while (rs.next()) {
...Do logic...
}
} catch (SQLException e) {
e.printStackTrace();
}
} catch (SQLException e){
e.printStackTrace();
}
}
问题是 Fortify 将标记此代码,指出如果嵌套 try 语句中发生异常,则对 conn 和 ps 的引用将丢失,并且它们不会被正确关闭。 fortify 标记这一点是正确的还是误报?根据我的理解,try-with-resource 应该总是关闭它们的资源,但当它们像这样嵌套时,也许这并不总是发生。
我在互联网上搜索了其他相关问题和博客,但我无法获得任何明确的证据。
在这种情况下,最安全的解决方案是不使用 try-with-resource,并在更广泛的 try-catch 语句的 catch 和 finally block 中使用 try-catch 包装每个资源。但是,我宁愿避免这种情况,因为它非常冗长。
提前致谢!
编辑:所以我意识到当我将代码重写为SO时,我在代码中遗漏了一些东西。原始的 catch block 中有一个 System.exit(1);
语句(我知道这是不好的做法)。这意味着,如果在嵌套的 try-with-resource 中抛出异常,那么 Fortify 会正确地说 conn 和 ps 不会正确关闭。
感谢您的回复,如果没有 System.exit(1);
,这种情况下的所有资源将正确关闭,我已经选择了表明这一点的答案。
最佳答案
Java 7 及更高版本始终支持使用 try-with-resource,无论工具位于其之上。
因此,如果此代码可以编译(意味着您使用的是 Java7+),您可以安全地忽略任何警告,因为它们确实是误报。 JRE 类保证自动关闭资源契约。
现在,如果您决定编写自己的资源来实现 AutoCloseable
那么您需要确保 close()
方法实际上关闭了资源 =)
关于JDBC、Fortify 和 Try-With-Resource,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34139717/