Question

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.

Was it helpful?

Solution

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 :)

OTHER TIPS

I would suggest using a flag as in the following example:

static String getData() throws IOException {
    boolean isTryCompleted = false;
    String theData = null;
    try (MyResource br = new MyResource();) {

        theData = br.getData();
        isTryCompleted = true;

    } catch(IOException e) {
        if (!isTryCompleted )
            throw e;
        // else it's a close exception and it can be ignored
    }

    return theData;
}

source:Close resource quietly using try-with-resources

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top