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.