我目前正在使用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 的引用将会丢失,他们不会被妥善关闭。是强制正确标记这个还是假阳性?根据我的理解,try-with-resource 应该总是关闭他们的资源,但是当他们像这样嵌套时,这并不总是会发生。
我已经浏览了互联网上的其他相关问题和博客,但我无法得到任何明确的证据。
在这种情况下始终安全的文档最多的解决方案是不使用try-with-resource并在更广泛的try-catch语句的catch和finally块中使用try-catch包装每个资源。但是,我宁愿避免这种情况,因为它非常冗长。
提前致谢!
编辑:所以当我重新写入SO时,我意识到我已经从代码中遗漏了一些东西。原始的catch块中有一个System.exit(1);
语句(我知道这种做法不好)。这意味着如果在嵌套的try-with-resource中抛出异常,那么强制说明 conn 和 ps 将无法正确关闭。
感谢您的回复,在这种情况下没有System.exit(1);
所有资源将正确关闭,我选择了答案,表明了这一点。
答案 0 :(得分:3)
在Java 7及更高版本上使用try-with-resource 始终,无论工具是否位于其上。
因此,如果此代码编译(意味着您使用的是Java7 +),则可以安全地忽略任何警告,因为它们确实是误报。 JRE类保证自动关闭资源合同。
现在,如果您决定编写自己的实现AutoCloseable
的资源,那么您需要确保close()
方法实际关闭资源=)
答案 1 :(得分:1)
Fortify Java转换器可能永远不会使用此Java 7+构造进行更新。您应该联系Fortify技术支持并提交测试用例。分析不正确。
此外,您应该标记这个和其他相同的发现"不是问题"继续你的生活。