Try-with-resources (originally known as Automatic Resource Management) is one of the Project Coin proposals that made its way into recent JDK 7 builds. Traditionally, developers had to manually terminate any resources (Files, Database connections, etc) they use in their applications and sometimes it was painful to keep track of those things and failing to do so may have serious problems such as resource leaks which could potentially lead to application failures that are hard to debug and triage. The burden of managing resources is no more a developer’s headache as this will be natively supported in Java 7.

C# has “using” blocks and C++ destructors served a similar purpose. This is a more sought after language feature for years and Joshua Bloch brings this to real for Java developers with some syntax sugaring. While this construct looks alien to Java, I believe this is something we have to accept and move forward as this solves common programming errors. IDEs can fill this space to support intelligent code completion for ARM constructs and make it easy for developer adoption. The other disadvantage outlined in the proposal is increased coupling between the language specification and libraries. To support this feature, a class must implement a designated interface AutoCloseable to make it eligible for automatic resource management.

Let us look at the example used in the ARM proposal, copying a file involving two resources.

    public void copy(String src, String dest) throws IOException {
        InputStream in = new FileInputStream(src);
        try {
            OutputStream out = new FileOutputStream(dest);
            try {
                byte[] buf = new byte[8192];
                int n;
                while ((n = in.read(buf)) >= 0)
                    out.write(buf, 0, n);
            } finally {
                out.close();
            }
        } finally {
            in.close();
        }
    }

With the new try-with-resources construct, we should be able to rewrite the above code with much simplicity:

    public void copy(String src, String dest) throws IOException {
        try(InputStream in = new FileInputStream(src);
            OutputStream out = new FileOutputStream(dest)){
            byte[] buf = new byte[8192];
            int n;
            while ((n = in.read(buf)) >= 0)
                out.write(buf, 0, n);
        }
    }

The bloated code we use these days will become more crisp with fewer lines of code, while continuing to maintain readability.

Java APIs that involve dealing with resources are mostly retrofitted to support this new AutoCloseable interface. This feature brings heap of benefits to the JDBC world where this may prove very useful when managing database connections and its subsidiaries.

Here is the traditional way of programming in JDBC where the user has to manage JDBC resources such as ResultSet, Statement and Connection.

        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            conn = DriverManager.getConnection("jdbc:h2:mem:test", "sa", "");
            stmt = conn.createStatement();
            rs = stmt.executeQuery("SELECT * FROM INFORMATION_SCHEMA.USERS");
            while (rs.next()) {
                System.out.println(rs.getString(1));
            }
        } catch (SQLException e) {
            // handle exception
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                }
                rs = null;
            }
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                }
                stmt = null;
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                }
                conn = null;
            }

        }

You guessed it right, there is so much boilerplate code that is involved here. Here is the same code with our try-with-resources construct.

        try(Connection conn = DriverManager.getConnection("jdbc:h2:mem:test", "sa", "");
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT * FROM INFORMATION_SCHEMA.USERS")) {// no trailing semicolon in the last line of the block containing automatic resource definition
            while (rs.next()) {
                System.out.println(rs.getString(1));
            }
        } catch (SQLException e) {
            // handle exception
        }

Wow, it is compact and powerful. JDBC support for the new try-with-resources construct will be part of JDBC 4.1 specification and the implementation is available in the recent JDK 7 build 112.

In these try-with-resources examples, an exception thrown during the lifetime of a try-with-resources statement receives priority over an exception thrown by an automatically generated close invocation. The proposal addresses automatic retention of those suppressed exceptions which are associated with the primary exception thrown during the try-with-resources statement.

The following methods are added to java.lang.Throwable to support extraction of these suppressed exceptions.

    public synchronized void addSuppressedException(Throwable exception);

    public synchronized Throwable[] getSuppressedExceptions();

You may want to go through the recent JavaOne presentation which details Project Coin features that are included in Java 7, slated for release in mid 2011.

Do you think Project Coin will become a crown jewel of Java 7, since Lambda expressions and Project Jigsaw are no longer the main contenders? In the coming days, I will be exploring many other language features that are included in Java 7 and help you decide the crown jewel of Java 7.

Keep watching this space for more Java 7 delicacies :-)

Possibly Related Posts:


Trackbacks/Pingbacks

  1.  » Rest of Project Coin explored, advantage Java 7 Blogging at the speed of thought: Life, Technology and More