At the LJC OpenConference

1 Comment

Martijn and I are at the LJC OpenConference today, which is taking place at the lovely IBM offices on Southbank. Some fascinating talks today – including Steve Poole from IBM and Steve Elliott from Oracle.

Our keynote seemed to go over well.

Currently in a great entry-level technical debt reduction talk from Markus K.

Glad the snow held off a bit!

Did you like this? Share it:

Java 7’s Automatic Resource Management now covers JDBC

6 Comments

One of the most eye-catching new features of Java 7’s Project Coin (JSR Pending) is Automatic Resource Management (ARM). ARM removes the need to write exception handling and resource management code for I/O streams, socket connections and other resources. In other words, there will no longer be a need to write error-prone try/catch statements, nor tedious resource cleanup code.

As stated on Joseph D. Darcy’s Oracle Weblog, ARM support is to be added to JDBC, which will provide much relief to ORM providers and day to developers alike!

This blog entry will highlight the benefits of ARM via a basic I/O based code example and will then go one to show a similar example for JDBC.

Lets imagine you’ve been asked to read a file containing the names of the New Zealand Football squad, and print those names out line by line. The existing (JDK 6) way of writing this code would probably look a little something like this:

FileReader fr;
BufferedReader br;
try
{
    String teamMember;
    fr = new FileReader('/home/NZTeamList.txt');
    br = new BufferedReader(fr);
    while ((teamMember = br.readLine()) != null)
    {
        System.out.println(teamMember);
    }
}
catch (FileNotFoundException e)
{
    e.printStackTrace();
}
catch (IOException e)
{
    e.printStackTrace();
}
finally
{
    if (br!= null)
    {
        br.close();
        if (fr != null)
        {
            fr.close();
        }
    }
}

As well as making sure that you cleanly close of the BufferedReader and the FileReader, notice all of the extra try/catch exception handling you have to put in place. It would be all to easy to miss a close() call or to declare a catch incorrectly.

Now lets look at the same problem with ARM involved. ARM removes the need for the explicit exception handling and automatically closes off resources for you:

String teamMember = null;
try (BufferedReader br =
            new BufferedReader(new FileReader('/home/NZTeamList.txt')))
{
    while ((teamMember = br.readLine()) != null)
    {
        System.out.println(teamMember);
    }
}

Notice the new syntax – the resources which will be managed are now inside a try()
parenthesis and the exception handling (i.e. the ‘catch’ blocks) is gone. The logic is now much cleaner and focused purely on the task at hand, no extra code for resource management is required.

You might be asking yourself: “Does that work for any manageable resource in the Java Standard Edition?” and the answer would be “No…. for now”. But a large step in the right direction has been made with the announcement that JDBC would be getting ARM support. JDBC is an area where most of the code that you write tends to focus more on exception handling and resource management than the actual business logic, so ARM can be put to good use here.

Lets say you have to retrieve and print out some employee salaries from a mySQL database. To refresh your memory, here’s an example of the current way of establishing a connection to a MySQL database using ye olde Connection, Statement and ResultSet interfaces:

String connectionURL = 'jdbc:mysql://localhost:3306/myDB';
Connection connection = null;
Statement st = null;
ResultSet rs = null;
try
{
    Class.forName('com.mysql.jdbc.Driver').newInstance();
    connection = DriverManager.getConnection(connectionURL, 'root', 'admin');
    st = connection.createStatement();
    rs = st.executeQuery('Select * from EMPLOYEE_SALARIES');
    while (rs.next())
    {
        System.out.println('EMPLOYEE_NAME/EMPLOYEE_SALARY');
        System.out.println(rs.getString(1) + '/' + rs.getString(2));
    }
}
catch (ClassNotFoundException ex)
{
    ex.printStackTrace();
}
catch (SQLException ex)
{
    ex.printStackTrace();
}
catch (InstantiationException ex)
{
    ex.printStackTrace();
}
catch (IllegalAccessException ex)
{
    ex.printStackTrace();
}
finally
{
    try
    {
        if (rs != null && !rs.isClosed())
        {
            rs.close();
        }
        if (st != null && !st.isClosed())
        {
            st.close();
        }
        if (connection != null && !connection.isClosed())
        {
            connection.close();
        }
    }
    catch (SQLException ex)
    {
        ex.printStackTrace();
    }
}

What is wrong with the above code? Compiler-wise…. nothing. But the abundance of exception-handling code simply overwhelms the core executeQuery()/parsing of the result set business logic.

If we look back to the ARM version of the first example, applying that paradigm to the JDBC code example above, should result in a cleaner version. More specifically there will be no  ’catch’ clauses and no code to close the opened connections, statements and result sets. An approximate version might look something like the following:

String connectionURL = 'jdbc:mysql://localhost:3306/myDB';
try
(
    Connection connection =
        DriverManager.getConnection(connectionURL, 'root', 'admin');
    Statement st = connection.createStatement();
    ResultSet rs = st.executeQuery('Select * from EMPLOYEE_SALARIES');
)
{
    Class.forName('com.mysql.jdbc.Driver').newInstance();
    while (rs.next())
    {
        System.out.println('EMPLOYEE_NAME/EMPLOYEE_SALARY');
        System.out.println(rs.getString(1) + '/' + rs.getString(2));
    }
}

The differences between ‘without ARM’ and ‘with ARM’ cases is indeed considerable. With ARM, the developer’s focus remains on the business logic.

Nevertheless, using ARM for automatically closing previously-opened resources raises some concerns. The most obvious of these is how the closing of the Connection will affect transactional behaviour. Should all transactions be committed or rolled back before ARM calls “close()” on the Connection? If the runtime resource manager decides to close the connection suddenly and not all changes have been committed, what would be the consequences of automatically rolling back everything? These questions are more will be answered in a follow up post once we get our hands on the first ARM/JDBC supported build.

Cheers,
Martijn, Ben and Dragos (our fantastic intern!).

Did you like this? Share it:

Book Cover!

No Comments

Book Cover!

Did you like this? Share it:

Oracle to monetize the JVM

No Comments

As discussed in the Register here, an Oracle VP has dropped a hint that Oracle plans to offer a premium VM.

What does all of this mean? Well, some commentators seem to think that this is a sign of the imminent Java apocalypse.

Another interpretation would be that this is, well, business as usual. Oracle already has a premium VM – JRockit. They just choose not to charge for it currently. All the time that Sun was an independent company, that decision may have been forced on them by the fact that Sun didn’t charge for HotSpot. So this can be seen as a reversion to a more usual model for Oracle.

So the Oracle roadmap is to merge JRockit and HotSpot, and put it out under the OpenJDK project. There’s quite a few things to note about that.

First off, this is far from as easy it sounds. HotSpot currently has the -server and -client switches, which cause class files to be compiled and executed on what are effectively different VMs. Sun never managed to bring them together, and they’re based on fundamentally the same architecture. Doing the merge of two completely different VMs will be quite a trick, and Oracle has lost a lot of talented ex-Sun engineers recently – including people who would have been very useful for a merge like this.

Secondly, the vaunted performance gains of JRockit are rather more subjective than Oracle would like to claim. That JRockit is a more high-performance VM than HotSpot is open to some debate.

Thirdly, if adding JRockit IP to the OpenJDK codebase, Oracle either has to put that IP under the GPL, or has to change the license of OpenJDK. The latter option would probably provoke a fork, which Oracle probably want to avoid.

Fourthly, the model used by other OSS projects of a free edition which has releases which time-lag the premium one does not work at all for the VM. One of the major points of OpenJDK was and is that the early adopters of new features help find bugs. This is an essential part of hammering the new features into a state where they will be used by the mainstream.

Most large corporates are very conservative about rolling new releases of VMs into production. It wasn’t very long ago that you still saw Java 1.4 VMs in the wild. If the natural early adopters are being discouraged from trying out new features by a pricetag on the VM, then how will those new features get the field testing that they need for Oracle’s real high-value customers to start using them.

So, the time-lag model doesn’t work, and the license for OpenJDK probably can’t be changed without risking a schism. Oracle needs the early adopters to use the free versions to get the bugs out of new features. This doesn’t leave a lot in the premium version – it’s basically a Support-Plus model, which is essentially what Sun was selling in the year or two before their acquisition. Let’s see if Oracle can make more of a go of it than Sun did. The sky is not falling.

Did you like this? Share it: