[ACCEPTED]-throws Exception in finally blocks-finally
I usually do it like this:
try {
// Use the resource.
} catch( Exception ex ) {
// Problem with the resource.
} finally {
// Put away the resource.
closeQuietly( resource );
}
Elsewhere:
protected void closeQuietly( Resource resource ) {
try {
if (resource != null) {
resource.close();
}
} catch( Exception ex ) {
log( "Exception during Resource.close()", ex );
}
}
0
I typically use one of the closeQuietly
methods in org.apache.commons.io.IOUtils
:
public static void closeQuietly(OutputStream output) {
try {
if (output != null) {
output.close();
}
} catch (IOException ioe) {
// ignore
}
}
0
If you're using Java 7, and resource
implements 2 AutoClosable
, you can do this (using InputStream as 1 an example):
try (InputStream resource = getInputStream()) {
// Use the resource.
}
catch( Exception ex ) {
// Problem with the resource.
}
Arguably a bit over the top, but maybe useful 11 if you're letting exceptions bubble up and 10 you can't log anything from within your 9 method (e.g. because it's a library and 8 you'd rather let the calling code handle 7 exceptions and logging):
Resource resource = null;
boolean isSuccess = false;
try {
resource = Resource.create();
resource.use();
// Following line will only run if nothing above threw an exception.
isSuccess = true;
} finally {
if (resource != null) {
if (isSuccess) {
// let close throw the exception so it isn't swallowed.
resource.close();
} else {
try {
resource.close();
} catch (ResourceException ignore) {
// Just swallow this one because you don't want it
// to replace the one that came first (thrown above).
}
}
}
}
UPDATE: I looked 6 into this a bit more and found a great blog 5 post from someone who has clearly thought 4 about this more than me: http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html He goes one step 3 further and combines the two exceptions 2 into one, which I could see being useful 1 in some cases.
As of Java 7 you no longer need to explicitly 22 close resources in a finally block instead you 21 can use try-with-resources syntax. The try-with-resources 20 statement is a try statement that declares 19 one or more resources. A resource is an 18 object that must be closed after the program 17 is finished with it. The try-with-resources 16 statement ensures that each resource is 15 closed at the end of the statement. Any 14 object that implements java.lang.AutoCloseable, which 13 includes all objects which implement java.io.Closeable, can 12 be used as a resource.
Assume the following 11 code:
try( Connection con = null;
Statement stmt = con.createStatement();
Result rs= stmt.executeQuery(QUERY);)
{
count = rs.getInt(1);
}
If any exception happens the close method 10 will be called on each of these three resources 9 in opposite order in which they were created. It 8 means the close method would be called first 7 for ResultSetm then the Statement and at 6 the end for the Connection object.
It's also 5 important to know that any exceptions that 4 occur when the close methods is automatically 3 called are suppressed. These suppressed 2 exceptions can be retrieved by getsuppressed() method defined 1 in the Throwable class.
Source: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Ignoring exceptions which occur in a 'finally' block 31 is generally a bad idea unless one knows what those 30 exceptions will be and what conditions they 29 will represent. In the normal try/finally
usage pattern, the 28 try
block places things into a state the outside 27 code won't be expecting, and the finally
block 26 restores those things' state to what the 25 outside code expects. Outside code which 24 catches an exception will generally expect 23 that, despite the exception, everything 22 has been restored to a normal
state. For example, suppose 21 some code starts a transaction and then 20 tries to add two records; the "finally" block 19 performs a "rollback if not committed" operation. A 18 caller might be prepared for an exception 17 to occur during the execution of the second 16 "add" operation, and may expect that if 15 it catches such an exception, the database 14 will be in the state it was before either 13 operation was attempted. If, however, a 12 second exception occurs during the rollback, bad 11 things could happen if the caller makes 10 any assumptions about the database state. The 9 rollback failure represents a major crisis--one 8 which should not be caught by code expecting 7 a mere "Failed to add record" exception.
My 6 personal inclination would be to have a 5 finally method catch exceptions that occur 4 and wrap them in a "CleanupFailedException", recognizing 3 that such failure represents a major problem 2 and such an exception should not be caught 1 lightly.
One solution, if the two Exceptions are 3 two different classes
try {
...
}
catch(package1.Exception err)
{
...
}
catch(package2.Exception err)
{
...
}
finally
{
}
But sometimes you cannot 2 avoid this second try-catch. e.g. for closing 1 a stream
InputStream in=null;
try
{
in= new FileInputStream("File.txt");
(..)// do something that might throw an exception during the analysis of the file, e.g. a SQL error
}
catch(SQLException err)
{
//handle exception
}
finally
{
//at the end, we close the file
if(in!=null) try { in.close();} catch(IOException err) { /* ignore */ }
}
Why do you want to avoid the additional 13 block? Since the finally block contains 12 "normal" operations which may throw an exception 11 AND you want the finally block to run completely 10 you HAVE to catch exceptions.
If you don't 9 expect the finally block to throw an exception 8 and you don't know how to handle the exception 7 anyway (you would just dump stack trace) let 6 the exception bubble up the call stack (remove 5 the try-catch from the finally block).
If 4 you want to reduce typing you could implement 3 a "global" outer try-catch block, which 2 will catch all exceptions thrown in finally 1 blocks:
try {
try {
...
} catch (Exception ex) {
...
} finally {
...
}
try {
...
} catch (Exception ex) {
...
} finally {
...
}
try {
...
} catch (Exception ex) {
...
} finally {
...
}
} catch (Exception ex) {
...
}
After lots of consideration, I find the 2 following code best:
MyResource resource = null;
try {
resource = new MyResource();
resource.doSomethingFancy();
resource.close();
resource = null;
} finally {
closeQuietly(resource)
}
void closeQuietly(MyResource a) {
if (a!=null)
try {
a.close();
} catch (Exception e) {
//ignore
}
}
That code guarantees 1 following:
- The resource is freed when the code finished
- Exceptions thrown when closing the resource are not consumed without processing them.
- The code does not try to close the resource twice, no unnecessary exception will be created.
If you can you should test to avoid the 9 error condition to begin with.
try{...}
catch(NullArgumentException nae){...}
finally
{
//or if resource had some useful function that tells you its open use that
if (resource != null)
{
resource.Close();
resource = null;//just to be explicit about it was closed
}
}
Also you should 8 probably only be catching exceptions that 7 you can recover from, if you can't recover 6 then let it propagate to the top level of 5 your program. If you can't test for an 4 error condition that you will have to surround 3 your code with a try catch block like you 2 already have done (although I would recommend 1 still catching specific, expected errors).
You could refactor this into another method 1 ...
public void RealDoSuff()
{
try
{ DoStuff(); }
catch
{ // resource.close failed or something really weird is going on
// like an OutOfMemoryException
}
}
private void DoStuff()
{
try
{}
catch
{
}
finally
{
if (resource != null)
{
resource.close();
}
}
}
I usually do this:
MyResource r = null;
try {
// use resource
} finally {
if( r != null ) try {
r.close();
} catch( ThatSpecificExceptionOnClose teoc ){}
}
Rationale: If I'm done 8 with the resource and the only problem I 7 have is closing it, there is not much I 6 can do about it. It doesn't make sense either 5 to kill the whole thread if I'm done with 4 the resource anyway.
This is one of the cases 3 when at least for me, it is safe to ignore 2 that checked exception.
To this day I haven't 1 had any problem using this idiom.
try {
final Resource resource = acquire();
try {
use(resource);
} finally {
resource.release();
}
} catch (ResourceException exx) {
... sensible code ...
}
Job done. No null tests. Single catch, include 4 acquire and release exceptions. Of course 3 you can use the Execute Around idiom and 2 only have to write it once for each resource 1 type.
Changing Resource
from best answer to Closeable
Streams implements Closeable
Thus 1 you can reuse the method for all streams
protected void closeQuietly(Closeable resource) {
if (resource == null)
return;
try {
resource.close();
} catch (IOException e) {
//log the exception
}
}
I encountered a situation similar where 7 I couldn't use try with resources but I 6 also wanted to handle the exception coming 5 from the close, not just log and ignore 4 it like closeQuietly mechanism do. in my 3 case I'm not actually dealing with an output 2 stream, so the failure on close is of more 1 interest than a simple stream.
IOException ioException = null;
try {
outputStream.write("Something");
outputStream.flush();
} catch (IOException e) {
throw new ExportException("Unable to write to response stream", e);
}
finally {
try {
outputStream.close();
} catch (IOException e) {
ioException = e;
}
}
if (ioException != null) {
throw new ExportException("Unable to close outputstream", ioException);
}
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.