I'm currently working through a project that is using HP's Fortify SCA tool to catch security issues in the code base. I'm having a bit of issue determining the best approach to correctly handling JDBC resources.
The code I have at the minute looks like this;
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();
}
}
The problem is that Fortify will flag this code stating that if an exception were to happen in the nested try statement then the reference to conn and ps will be lost and they won't be properly closed. Is fortify correct to flag this or is it a false positive? From what I understand try-with-resource should always close their resource but perhaps this doesn't always happen when they're nested like this.
I've scoured other related questions and blogs around the internet but I haven't been able to get any definitive proof on this.
The most documented solution that's always safe in this situation is to not use try-with-resource and wrap each resource with a try-catch in both the catch and finally blocks of a broader try-catch statement. However, I'd rather avoid this because it's horribly verbose.
Thanks in advance!
Edit: So I realized I've left something out of the code when I was re-writing it into SO. The original catch blocks had a System.exit(1);
statement in them (bad practice I know). That would mean that if an exception was thrown in the nested try-with-resource then Fortify would be correct to say the conn and ps would not be properly closed.
Thanks for the replies, without the System.exit(1);
all resources in this situation will be closed properly and I've selected the answer indicating that.
Using try-with-resource is always supported on Java 7 and higher, no matter tooling is sitting on top of it.
So, if this code compiles (meaning you are on Java7+), you can safely ignore any warnings as they are indeed false positives. The auto-closing resource contract is guaranteed for JRE classes.
Now, if you decide to write you own resource that implements AutoCloseable
then it's up to you to make sure that the close()
method actually closes the resource =)