Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

try with resource, will resource clean if thrown exception is not caught?

Tags:

java

java-8

What happens when a try-with-resource throws an exception which is caught outside? Will a cleanup still be performed?

Sample:

public void myClass() throws customException {
  try (Connection conn = myUtil.obtainConnection()) {
     doSomeStuff(conn);
     if (someCheck)
       throw new customException(somePara);

     doSomeMoreStuff(conn);
     conn.commit();

  } catch (SQLException e) {
     log.error(e);
  }
}

The part I'm concerned with is when the customException is thrown. I do not catch this exception with the catch of my try-with-resource. Hence I wonder if the connection cleanup will be performed in this scenario.

Or do I need to catch and rethrow the connection, like this:

public void myClass() throws customException {
  try (Connection conn = myUtil.obtainConnection()) {
     doSomeStuff(conn);
     if (someCheck)
       throw new customException(somePara);

     doSomeMoreStuff(conn);
     conn.commit();

  } catch (SQLException e) {
     log.error(e);
  } catch (customException e) {
     throw new customException(e);
  }
}

2 Answers

A documentation has an answer to your exact question

Note: 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.

If an exception is thrown from the try block and one or more exceptions are thrown from the try-with-resources statement, then those exceptions thrown from the try-with-resources statement are suppressed, and the exception thrown by the block is the one that is thrown by the writeToFileZipFileContents method. You can retrieve these suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.

Please have a look https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

like image 172
phil_g Avatar answered Oct 20 '25 04:10

phil_g


Yes, the cleanup will happen... if the close() method correctly handles the cleanup:

Example of execution

public class Main {
  public static void main(String[] args) throws Exception {
    try (AutoCloseable c = () -> System.out.println("close() called")) {
      throw new Exception("Usual failure");
    }
  }
}

(shortened by Holger in the comments)

Output on stdout:

close() called

Output on stderr:

Exception in thread "main" java.lang.Exception: Usual failure
    at Main.main(Main.java:4)

Example of execution with an exception thrown in the close() method

(suggested by Holger in the comments)

public class Main {
  public static void main(String[] args) throws Exception {
    try (AutoCloseable c = () -> { throw new Exception("Failure in the close method"); }) {
      throw new Exception("Usual failure");
    }
  }
}

No output on stdout.

Output on stderr:

Exception in thread "main" java.lang.Exception: Usual failure
    at Main.main(Main.java:4)
    Suppressed: java.lang.Exception: Failure in the close method
        at Main.lambda$main$0(Main.java:3)
        at Main.main(Main.java:3)
like image 45
Olivier Grégoire Avatar answered Oct 20 '25 05:10

Olivier Grégoire



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!