我目前正在进行一个项目,该项目使用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资源应该总是关闭它们的资源,但当它们像这样嵌套时,可能并不总是发生这种情况。
我在互联网上搜索了其他相关问题和博客,但我还没有得到任何明确的证据。
在这种情况下,最安全的解决方案是不使用try with resource,并在更广泛的try-catch语句的catch和finally块中用try-catch包装每个资源。然而,我宁愿避免这样做,因为它非常冗长。
提前感谢!
编辑:所以我意识到当我把代码重写成SO时,我在代码中遗漏了一些东西。原始的cat块中有一个System.exit(1);
语句(我知道不好的做法)。这意味着如果嵌套的try-with资源中抛出了一个异常,那么Fortify说conn和ps不会被正确关闭是正确的。
感谢您的回复,没有System.exit(1);
在这种情况下,所有资源都将被正确关闭,我选择了表明这一点的答案。
FortifyJava翻译器可能从未更新过Java7结构。您应该联系Fortify技术支持并提交测试用例。分析不正确。
此外,你应该把这个和其他相同的发现标记为“不是问题”,然后继续你的生活。
Java7及更高版本始终支持使用资源尝试,无论工具是否位于其之上。
因此,如果此代码编译(这意味着您使用的是Java7),您可以安全地忽略任何警告,因为它们确实是误报。JRE类保证自动关闭资源契约。
现在,如果您决定编写自己的资源来实现自动关闭,那么您需要确保关闭()方法实际上关闭了资源=)
我认为流API在这里是为了使代码更易于阅读。我觉得有点烦。流接口扩展了java。lang.AutoCloseable接口。 因此,如果你想正确地关闭流,你必须使用try-with资源。 清单1.不是很好,流没有关闭。 清单2.使用2嵌套try 清单3。当map返回流时,必须关闭stream()和map()函数。 我举的例子毫无意义。为了示例,我将jpg图像的路径替换为整数。但不要让这些细节分散你的
问题内容: 我一直在看代码,并且看到了尝试资源的机会。我以前使用过标准的try-catch语句,看起来它们在做同样的事情。所以我的问题是“ 尝试使用资源”与“尝试捕获 ”之间的区别是什么,哪个更好。 这是尝试使用资源: 问题答案: 尝试使用资源的重点是确保可靠地关闭资源。 当你不使用try-with-resources时,存在一个潜在的陷阱,称为异常屏蔽。当try块中的代码引发异常,而finall
我有一个实现了AutoCloseable的类,并且打算与Java7的新资源尝试构造一起使用。但是,我找不到一种方法来保证我的类的用户使用资源尝试。如果这种情况没有发生,那么我的类将无法关闭自己,并且会发生不好的事情。有什么方法——语言构造或其他方法——来强制执行它吗?甚至能够检测我是否处于资源尝试块中,这样如果没有,我就可以抛出异常(尽管编译时构造更可取)。 谢谢
这是一种向可观察的客户列表中添加新行星的方法。 我想知道我是否正确使用资源尝试,以及自动关闭是否工作。 我的问题是,这部分需要被封闭在一个try-catch块中,还是自动关闭。
我知道,如果资源已实现自动关闭,您通过尝试传递的资源将自动关闭。到现在为止,一直都还不错。但是,当我有几个我想要自动关闭的资源时,我该怎么办呢。带插座的示例; 所以我知道套接字将被正确关闭,因为它在try中作为参数传递,但是输入和输出应该如何正确关闭呢?
我需要打开N个多播套接字(其中N来自参数列表的大小)。然后,我将向循环中的N个套接字中的每个套接字发送相同的数据,最后关闭每个套接字。我的问题是,如何使用try with resources块来实现这一点?以下是我将如何使用单个资源来实现这一点: 我能想到的使用多个端口执行此操作的唯一方法如下: 有没有一种更简洁的方法来实现这一点,或者我提出的解决方案是否尽可能好?