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
  • 30,462
  • 36
  • 132
  • 269

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
  • 11,313
  • 2
  • 28
  • 37
  • 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
  • 59,707
  • 18
  • 122
  • 168
2

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

michael nesterenko
  • 13,742
  • 23
  • 107
  • 178