Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception coming out of close() in try-with-resource [duplicate]

I was reading about the try-with-resource in JDK7 and while I was thinking of upgrading my application to run with JDK7 I faced this problem..

When using a BufferedReader for example the write throws IOException and the close throws IOException.. in the catch block I am concerned in the IOException thrown by the write.. but I wouldn't care much about the one thrown by the close..

Same problem with database connections.. and any other resource..

As an example I've created an auto closeable resource:

public class AutoCloseableExample implements AutoCloseable {

    public AutoCloseableExample() throws IOException{
        throw new IOException();
    }

    @Override
    public void close() throws IOException {
        throw new IOException("An Exception During Close");
    }

}

Now when using it:

public class AutoCloseTest {

    public static void main(String[] args) throws Exception {
        try (AutoCloseableExample example = new AutoCloseableExample()) {
            System.out.println(example);

            throw new IOException("An Exception During Read");
        } catch (Exception x) {
            System.out.println(x.getMessage());
        } 
    }

}

how can I distinguish between such exceptions without having to create wrappers for classes such as BufferedReader?

Most of cases I put the resource close in a try/catch inside the finally block without caring much about handling it.

like image 478
Mohammed R. El-Khoudary Avatar asked Dec 18 '13 12:12

Mohammed R. El-Khoudary


People also ask

Does try with resources close on exception?

The Java try with resources construct, AKA Java try-with-resources, is an exception handling mechanism that can automatically close resources like a Java InputStream or a JDBC Connection when you are done with them. To do so, you must open and use the resource within a Java try-with-resources block.

What happens when an exception is thrown from the try with resources?

For try-with-resources, if an exception is thrown in a try block and in a try-with-resources statement, then the method returns the exception thrown in the try block. The exceptions thrown by try-with-resources are suppressed, i.e. we can say that try-with-resources block throws suppressed exceptions.

How do you handle exceptions in trying with resources?

If a try block throws an exception and one or more exceptions are thrown by the try-with-resources, the exceptions thrown by try-with-resources are suppressed. In other words, we can say, exceptions which are thrown by try-with-resources are suppressed exceptions.

Do we need catch for try with resources?

A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.


1 Answers

Lets consider the class:

public class Resource implements AutoCloseable {

    public Resource() throws Exception {
        throw new Exception("Exception from constructor");
    }

    public void doSomething() throws Exception {
        throw new Exception("Exception from method");
    }

    @Override
    public void close() throws Exception {
        throw new Exception("Exception from closeable");
    }
}

and the try-with-resource block:

    try(Resource r = new Resource()) {
        r.doSomething();
    } catch (Exception ex) {
        ex.printStackTrace();
    }

1. All 3 throw statements enabled.

Message "Exception from constructor" will printed and the exception thrown by constructor will be suppressed, that means you can't catch it.

2. The throw in constructor is removed.

Now the stack trace will print "Exception from method" and "Suppressed: Exception from closeable" below. Here you also can't catch the suppressed exception thrown by close method, but you will be nofitied about the suppressed exception.

3. Throws from constructor and method are removed.

As you have probably already guessed the "Exception from closeable" will be printed.

Important tip: In all of above situations you are actually catching all exceptions, no matter where they were throwed. So if you use try-with-resource block you don't need to wrap the block with another try-catch, the extra block is simply useless.

Hope it helps :)

like image 144
Flying Dumpling Avatar answered Oct 21 '22 21:10

Flying Dumpling