Try-catch-finally, and then try to catch again

I often came across situations like: -

try{ ... stmts ... } catch(Exception ex) { ... stmts ... } finally { connection.close // throws an exception } 

which still needs a try-catch block inside.

What is the best practice to overcome this?

+30
java exception-handling try-catch-finally
Aug 26 '09 at 16:03
source share
10 answers

Write a SQLUtils class that contains static closeQuietly methods that catch and log such exceptions and then use them as needed.

You will get something like this:

 public class SQLUtils { private static Log log = LogFactory.getLog(SQLUtils.class); public static void closeQuietly(Connection connection) { try { if (connection != null) { connection.close(); } } catch (SQLExcetpion e) { log.error("An error occurred closing connection.", e); } } public static void closeQuietly(Statement statement) { try { if (statement!= null) { statement.close(); } } catch (SQLExcetpion e) { log.error("An error occurred closing statement.", e); } } public static void closeQuietly(ResultSet resultSet) { try { if (resultSet!= null) { resultSet.close(); } } catch (SQLExcetpion e) { log.error("An error occurred closing result set.", e); } } } 

And your client code will look something like this:

 Connection connection = null; Statement statement = null; ResultSet resultSet = null; try { connection = getConnection(); statement = connection.prepareStatement(...); resultSet = statement.executeQuery(); ... } finally { SQLUtils.closeQuietly(resultSet); SQLUtils.closeQuietly(statment); SQLUtils.closeQuietly(connection); } 

Update: starting with Java 7, various JDBC interfaces extend java.lang.AutoCloseable and although the above code answers the original question, if you write code directly for the JDBC API, now it can be structured:

 try ( Connection connection = getConnection(); PreparedStatement statement = connection.prepareStatement(...); ResultSet resultSet = statement.executeQuery() ) { ... } 
+24
Aug 26 '09 at 16:06
source share

As mentioned, the closeQuietly static utility is the way to go. Add one: if you are in the world of java.io , not java.sql , then there is a useful interface for this - java.io.Closeable

All data sources and receivers in java.io implement this interface - all streams, channels, writers and readers. Thus, you can create a single utility to solve the same problem of closing exception (), without requiring many overloaded versions.

eg.

 public class IoUtils { public static closeQuietly (Closeable closeable) { try { closeable.close(); } catch (IOException logAndContinue) { ... } } } 
+12
Aug 26 '09 at 17:05
source share

I usually did it like this:

 try { try { .. stmts ... } finally { connection.close(): } } catch (Exception ex) { .. stmts .. } 

I usually used this only when I did not use the library that took care of this plumbing for me.

As Imagist points out, this is technically not the same thing that will finally work before the catch, but I think it solves the problem you are trying to solve.

+10
Aug 26 '09 at 16:06
source share

Commons-io also has closeQuietly () for input and output streams. I use it all the time. This makes your code more readable.

+4
Aug 26 '09 at 16:40
source share

Feel free to use another try ... catch inside finally.

+1
Aug 26 '09 at 16:06
source share

In Java 10, you can write:

 public void java10() throws SQLException { try (var connection = Connections.openConnection(); var callableStatement = connection.prepareCall("my_call"); var resultSet = callableStatement.executeQuery()) { while (resultSet.next()) { var value = resultSet.getString(1); System.out.println(value); } } } 

In Java 7, 8 and 9 you can write:

 public void java7() throws SQLException { try (Connection connection = Connections.openConnection(); CallableStatement callableStatement = connection.prepareCall("my_call"); ResultSet resultSet = callableStatement.executeQuery()) { while (resultSet.next()) { String value = resultSet.getString(1); System.out.println(value); } } } 

In Java 6, you need to write all these lines:

 public void java6() throws SQLException { Connection connection = Connections.openConnection(); try { CallableStatement callableStatement = connection.prepareCall("my_call"); try { ResultSet resultSet = callableStatement.executeQuery(); try { while (resultSet.next()) { String value = resultSet.getString(1); System.out.println(value); } } finally { try { resultSet.close(); } catch (Exception ignored) { } } } finally { try { callableStatement.close(); } catch (Exception ignored) { } } } finally { try { connection.close(); } catch (Exception ignored) { } } } 
+1
Dec 10 '14 at 15:05
source share

As a rule, you do not want to do anything more than register an exception that occurs when the resource is closed, so it should really go on its own try / catch. However, this is common code that will happen often, so do not repeat yourself and put the closure in a static method (as Nick Holt suggests) this way you will not have two try / catch elements in the same method, making the code easier to read and observations.

0
Aug 26 '09 at 16:39
source share

There is a convenient Closeables # closeQuitely method in Google Guava - it can be used for any Closeable

0
Mar 22 '13 at 13:45
source share

Can we try a block followed by finally a bock and a catch block later?

0
Jan 23 '14 at 18:35
source share

just remember .. finally always execute either with try or catch.

-one
Aug 26 '09 at 16:26
source share



All Articles