Try-with-resources equivalent in Java 1.6
Asked Answered
D

3

11

I have the following code:

    public class Main {

        public static void main(String[] args) throws SQLException {

            try (
                    Connection conn = DBUtil.getConnection(DBType.HSQLDB);
                    Statement stmt = conn.createStatement(
                            ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                    ResultSet rs = stmt.executeQuery("SELECT * FROM tours");
                    ) {

            DBUtil.getConnection();

            } catch (SQLException e) {
                DBUtil.processException(e);
            } 

        }

    }

I use this code to fetch data from a database. My problem is that I'm not allowed to use the Java 1.7 compiler and have to use 1.6. How can I translate the try-with-resources-code to use with a 1.6 compiler? What exactly happens in this special try block?

Dispread answered 12/5, 2014 at 14:37 Comment(5)
Put all the lines between parenthesis at the beginning of the try code, and put all closing code in a finally after all the catchs.Foley
(i) put the statements in the try code (ii) close what needs to be closed in a finally block.Pennyworth
is this that easy? ok, I thought the try-with-ressources was more complicated because I've seen some strange postsDispread
Why can't you use the Java 7 compiler? You could set the target compatibility to Java 6...Ciaphus
this is for a university project and we should use the 1.6 compilerDispread
O
15

Oracle explains how try-with-resources works here

The TL;DR of it is:
There is no simple way of doing this in Java 1.6. The problem is the absence of the Suppressed field in Exception. You can either ignore that and hardcode what happens when both try AND close throw different exceptions, or create your own Exception sub-hierarchy that has the suppressed field.

In the second case, the link above gives the proper way of doing it:

   AutoClose autoClose = new AutoClose();
   MyException myException = null;
   try {
       autoClose.work();
   } catch (MyException e) {
       myException = e;
       throw e;
   } finally {
       if (myException != null) {
           try {
               autoClose.close();
           } catch (Throwable t) {
               myException.addSuppressed(t);
           }
       } else {
           autoClose.close();
       }
   }  

is equivalent to

try (AutoClose autoClose = new AutoClose()) {
    autoClose.work();
}

In case you want to make it easier and not create a whole lot of new Exception classes, you will have to decide what to throw in the catch clause inside the finally (t or e).

PS. Dealing with multiple variable declaration in the try is also discussed in the link above. And the amount of code that you need to do it properly is staggering. Most people take shortcuts in Java 1.6 by not coping with exceptions in the finally block and using nullchecks.

Outspread answered 12/5, 2014 at 14:44 Comment(0)
C
1

I would advise usage of apache's commons-dbutils library which have class DBUtils with close and closeQuietly methods. The code would look like this:

import org.apache.commons.dbutils.DBUtils;
...
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

try {
    conn = myOwnUtil.getConnection();
    stmt = conn.createStatement();
    rs = stmt.executeQuery( "SELECT * FROM table" ); // or any other custom query
} catch ( SQLException e ) {
    <<handle exception here>>;
} finally {
    DBUtils.closeQuietly( conn );
    DBUtils.closeQuietly( stmt );
    DBUtils.closeQuietly( rs );
    // or simply use DBUtils.close( conn, stmt, rs );
}

Note that closeQuietly will throw no exceptions, while close might cast SQLException, so adapt the code to your own use case.

If you want to close streams than you can use apache's commons-io with IOUtils class which also have close and closeQuietly.

Conservatism answered 15/11, 2016 at 16:30 Comment(0)
H
0

Do it like this:

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

try {
    conn = DBUtil.getConnection(DBType.HSQLDB);
    stmt = conn.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
    rs = stmt.executeQuery("SELECT * FROM tours");
} catch (SQLException e) {
    DBUtil.processException(e);
} finally {
    if(conn != null) {
        conn.close();
    }
    if(stmt != null) {
        stmt.close();
    }
    if(rs != null) {
        rs.close();
    }
}
Hutt answered 12/5, 2014 at 14:42 Comment(3)
-1 This is not equivalent to try-with-resources. Particularly around exception handling.Ciaphus
Years of flame wars and we're back to where we started. A simple google search on "Java 6 close resources" will give plenty of explanations of why this is incorrect, including SO questions. #5783147 this for example, from 3 years ago (with the accepted answer of "Use JDK 7, it's just that much simpler")Outspread
wouldn't close statements in finally block need another try/catch ?Mercorr

© 2022 - 2024 — McMap. All rights reserved.