Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Try-With-Resources Debate

Ok now, at my job we're having a debate over try-with-resources and exception suppression.

Quick recap: try-with-resources, from java 7, eliminates the need for that pesky finally block to close resources. I personally feel it is way more elegant, but I have a coworker who isn't convinced. He doesn't like that the one exception gets suppressed, and has been arguing that we loose information through that.

At first I was taking his word for it, because I'm a junior dev and he's senior, I'm new, etc. But I recently discovered that hey, all the info makes it into the stack trace, including the suppressed exception. So no information is lost there.

The last piece of this debate that I'm looking for (since I'm advocating for try-with-resources) is how auto-closeable handles that exception. Let's say an exception is thrown while trying to close a resource, is there the potential that resource could stay open and leak? Ultimately this may not be such a big deal, since the logs would alert us to this issue anyway.

Just curious. Thanks so much.

like image 324
craigmiller160 Avatar asked Apr 26 '16 16:04

craigmiller160


People also ask

What is the advantage of try with resources in Java?

The try-with-resources statement ensures that each resource is closed at the end of the statement execution. If we don't close the resources, it may constitute a resource leak and also the program could exhaust the resources available to it. You can pass any object as a resource that implements java.

What are the improvements made to try with resources in Java 9?

From Java 9, try with resources will recognize resources declared outside its body. You can pass the reference of resource declared outside directly to try block. There is no need to declare resources locally within try block.

Which is the correct statement about try with resources statement in Java 9?

The try-with-resources statement is a try statement with one or more resources duly declared. Here resource is an object which should be closed once it is no more required. The try-with-resources statement ensures that each resource is closed after the requirement finishes.

Does try with resources need finally?

In the try-with-resources method, there is no use of the finally block. The file resource is opened in try block inside small brackets. Only the objects of those classes can be opened within the block which implements the AutoCloseable interface, and those objects should also be local.


1 Answers

You are correct that suppressing the exception does not result in losing information. Your co-worker's concern about that is groundless. The points of try-with-resources are:

  • to make sure that resources get closed, regardless of what is thrown while using them, and in the reverse order in which they're declared,

  • to make sure that exceptions thrown on close don't cause exceptions thrown in the try block to get lost, and

  • to make sure that exceptions thrown on close still get retained as suppressed exceptions so no information is lost.

If closing a resource throws an exception, there's nothing you can do about it in either case. In JDBC the database objects communicate back to the database server to tell it to de-allocate resources, and those would stay open if close fails. (And retrying is usually pointless anyway because the problem is typically that something changed about the network or the connection.) But the server will clean those up eventually, and it's out of the client code's hands. Both try-with-resources and the older try-finally idiom do an equally good job of closing resources, it's just more work and more typing with the try-finally idiom.

The biggest difference to me in whether to use try-with-resources or nested try-finally statements is that in the former case, if nothing is thrown in the try block and something is thrown on close, the exception thrown on close is thrown (since there's no exception thrown in the try-block to attach it to as a suppressed exception). If you use nested try-finally blocks then you can make sure exceptions thrown on close do not propagate from the finally block, so that an intermittent network glitch while releasing resources doesn't result in losing a valid business transaction.

But in practice very few people have the tolerance for this kind of nesting and they take shortcuts that lead to resource leaks (typically connections that don't get closed because an earlier call in the finally block failed). People also tend to write code that causes exception-masking (mentioned in the second bullet point), where the exception thrown on close causes an exception thrown within the try-block to be lost; try-with-resources prevents this kind of error. There is definitely a place for try-with-resources.

My advice is to learn all you can about exception handling, write example programs demonstrating how exceptions work, and understand the strong and weak points of both approaches so that you can talk about them in detail and compare and contrast. That way you can show that you understand the concerns your co-workers raise and you can give advice not as an advocate for one way over the other but with a goal of helping your group find solutions that help it write better software.

like image 56
Nathan Hughes Avatar answered Sep 23 '22 17:09

Nathan Hughes