Java EE 6 does Java 7 with GlassFish 3.1.1, the making-of

August 24, 2011 § 5 Comments

I recently posted a screencast showing how a simple JavaEE 6 web application can take advantage of Java 7’s new language features (aka project coin). Here are more details on the code for the three Java 7 new language features shown. The full code is available here.

The first Project Coin feature shown (Java 7 refactorings start at 7:37 into the screencast) is Strings in switch statements. This is rather straightforward (a number of folks thought this was already supported) and if probably a good candidate to use with web frameworks which take user input as Strings.


String name = request.getParameter("name");
if ("duke".equals(name)) {
    vip = true;
    name = name.toUpperCase(); // let's visually recognize DUKE
} else if ("sparky".equals(name)) {
    vip = true;         // another VIP
}

becomes :


String name = request.getParameter("name");
switch (name) {
    case "duke":
        vip = true;
        name = name.toUpperCase(); // let's visually recognize DUKE
        break;
    case "sparky":
        vip = true;         // another VIP
        break;
}

Of course you can also have a default: section equivalent to an else statement.

The second feature is try-with-resources and is shown here in the initializing sequence of a stateless EJB. It uses JDBC to ping a well-known system table. The code specifically relies on the fact that multiple classes in JDBC 4.1 (Connection, Statement and ResultSet) now implement the new Java 7 java.lang.AutoCloseable interface. This is what allows for the following code requiring proper closing of resources :


@PostConstruct
public void pingDB(){
    try {
        Connection c = ds.getConnection();
        Statement stmt = c.createStatement();

        ResultSet rs = stmt.executeQuery("SELECT * from SYS.SYSTABLES");
        while (rs.next()) {
            System.out.println("***** SYSTEM TABLES" + rs.getString("TABLENAME"));
        }
        stmt.close();
        c.close();

    } catch (SQLException ex) {
        ex.printStackTrace();
    }
}

… to be rewritten as follows (resources initialized in a single statement, no closing required as the compiler takes care of it when they go out of scope) :


@PostConstruct
public void pingDB() {
    try (Connection c = ds.getConnection(); Statement stmt = c.createStatement()) {
        ResultSet rs = stmt.executeQuery("SELECT * from SYS.SYSTABLES");
        while (rs.next()) {
            System.out.println("***** SYSTEM TABLES" + rs.getString("TABLENAME"));
        }
    } catch (SQLException ex) {
        ex.printStackTrace();
    }
}

As you can see in the source code, the DataSource is actually created using a @DataSourceDefinition annotation which is a new feature in Java EE 6.

The third and final part of the demonstration uses a somewhat convoluted piece of JPA code to illustrate the multi-catch feature. For the purpose of the demo, the JPA query (also in the above EJB) uses a LockModeType.PESSIMISTIC_WRITE (new in JPA 2.0) when building the JP-QL query and adds two catch blocs for PessimisticLockException and LockTimeoutException :


try {
    List customers = em.createNamedQuery("findAllCustomersWithName")
        .setParameter("custName", name)
        .setLockMode(LockModeType.PESSIMISTIC_WRITE)
        .getResultList();
    if (customers.isEmpty()) {
        doesExist = false;
        Customer c = new Customer();
        c.setName(name);
        em.persist(c);
    } else {
        doesExist = true;
    } catch (final PessimisticLockException ple) {
        System.out.println("Something lock-related went wrong: " + ple.getMessage());
    } catch (final LockTimeoutException lte) {
        System.out.println("Something lock-related went wrong: " + lte.getMessage());
    }

}

Which can be refactored to this equivalent code using multi-catch :


try {
    List customers = em.createNamedQuery("findAllCustomersWithName")
        .setParameter("custName", name)
        .setLockMode(LockModeType.PESSIMISTIC_WRITE)
        .getResultList();
    if (customers.isEmpty()) {
        doesExist = false;
        Customer c = new Customer();
        c.setName(name);
        em.persist(c);
    } else {
        doesExist = true;
    } catch (final PessimisticLockException | LockTimeoutException ple) {
        System.out.println("Something lock-related went wrong: " + ple.getMessage());
    }


}

This new language feature is *very* useful for reflection or java.io File manipulation, not quite the most common Java EE code out there.

Of course all of the above only works with JDK 7 at runtime and if running NetBeans 7.0.1 you’ll also need to set the source level to Java 7 for the quick fixes to light up. I’ve also successfully executed this under Mac OS X using the OpenJDK Mac OS binary port.

Some resources :

Full Source code.
Screencast showing this “in action”.
String in switch statements.
try-with-resources.
Multi-catch and precise rethrow.

About these ads

Tagged: , , , , ,

§ 5 Responses to Java EE 6 does Java 7 with GlassFish 3.1.1, the making-of

  • But do we need to do any java.io.File manipulation anymore, now that we have java.nio.Path? :)

  • guest says:

    >Connection c = ds.getConnection(); Statement stmt = c.createStatement()
    For those cases where the connection is only used to create a single statement and nothing else, a further simplification could perhaps be made if DataSource had a convenience method that directly created a statement.
    Of course it’s undoable to add this to an existing interface, but maybe this would be an option for a new sub-interface, e.g. SQLDataSource?

  • Alexis MP says:

    Thanks Arjan. I’ve shared your comment with the JDBC lead.

  • guest says:

    On the try-with-resources closing, if there is a conditional filter or if one could pass a listener or a construct such that say, if I share the connection to live beyond the try block scope for strategic requirements, it would be great use.
    The listener could decide when to close, or configure it based on configurable conditions.
    Thanks

What’s this?

You are currently reading Java EE 6 does Java 7 with GlassFish 3.1.1, the making-of at Bistro! 2.0.

meta

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: