4

Whenever I need to acquire a resource in Java and then guarantee that the resource is released, where an exception might be thrown, I use the following pattern:

try {
  Resource resource = null;
  try {
    resource = new Resource();
    // Use resource
  } finally {
    if (resource != null) {
      // release resource
    }
  }
} catch (Exception ex) {
  // handle exceptions thrown by the resource usage or closing
}

For example, if I need a database connection, and using or closing the connection can throw an exception, I write the following code:

try {
  Connection connection = null;
  try {
    connection = ... // Get database connection
    // Use connection -- may throw exceptions
  } finally {
    if (connection != null) {
      connection.close(); // This can also throw an exception
    }
  }
} catch (SQLException ex) {
  // handle exceptions thrown by the connection usage or closing
}

I don't like just doing a simple try-catch-finally because I am obligated to catch the (possible) exception that can be thrown when the database connection is closed, and I am never sure how to handle that one.

Is there a better pattern for handling this situation?

Ralph
  • 31,584
  • 38
  • 145
  • 282
  • Why don't you add finally clause to the normal exception.(SqlException in this case..) – uncaught_exceptions Sep 15 '11 at 15:18
  • Similar, but not an exact dupe: http://stackoverflow.com/questions/1335812/try-catch-finally-and-then-again-a-try-catch – razlebe Sep 15 '11 at 15:18
  • I don't like where you have to check if the resource is null before closing it. i'd rather create the resource outside the try block and avoid all that. also exceptions thrown during close are pretty useless, just log them and go on. – Nathan Hughes Sep 15 '11 at 15:23

3 Answers3

8

IOUtils.closeQuietly() could solve your problem.

Example:

    Closeable closeable = null;
    try {
        closeable = new BufferedReader(new FileReader("test.xml"));
        closeable.close();
    } catch (IOException e) {
        // Log the exception
        System.err.println("I/O error");
    } finally {
        // Don't care about exceptions here
        IOUtils.closeQuietly(closeable);
    }
Sahil Muthoo
  • 12,033
  • 2
  • 29
  • 38
  • 1
    I don't see what's the point of `closeable.close()` here, if it's already being closed with `IOUtils.closeQuietly(closeable);`. Also, this is swallowing the exception. Maybe it would be better to let it propagate and be handled at a higher level. Well, there's clearly two options on what to do if you don't know what to do with it. Swallowing or propagating :) – Xavi López Sep 15 '11 at 15:33
  • My earlier example was swallowing exceptions. This is logging and swallowing. Much better :). Thanks @Xavi. – Sahil Muthoo Sep 15 '11 at 15:48
  • Hahah, yes indeed :) Thank you for showing me `closeQuietly()`, too! – Xavi López Sep 15 '11 at 15:51
8

Personally, I use the following pattern:

  Connection connection = null;
  try {
    connection = ... // Get database connection
    // Use connection -- may throw exceptions
  } finally {
    close(connection);
  }

private void close(Connection connection) {
  try {
    if (connection != null) {
      connection.close(); // This can also throw an exception
    }
  } catch (Exception e) {
    // log something
    throw new RuntimeException(e); // or an application specific runtimeexception
  }
}

or similar to that. This pattern doesn't lose the exception, but makes your code a lot cleaner. I use this pattern when the exception being caught in the finally clause (in this case close()) is difficult to deal with and should be dealt with at a higher level.

Cleaner still is to use the loan pattern.

Matthew Farwell
  • 60,889
  • 18
  • 128
  • 171
2

You should not catch exceptions if you don't know how to handle them.

michael nesterenko
  • 14,222
  • 25
  • 114
  • 182