GlassFish Back from Devoxx 2011 Mature Java EE 6 and EE 7 well on its way

I’m back from my 8th (!) Devoxx conference (I don’t think I’ve missed one since 2004) and this conference keeps delivering on the promise of a Java developer paradise week. GlassFish was covered in many different ways and I was not involved in a good number of them which can only be a good sign!


Several folks asked me when my Java EE 6 session with Antonio Goncalves was scheduled (we’ve been covering this for the past two years in University sessions, hands-on labs and regular sessions). It turns out we didn’t team up this year (Antonio was crazy busy preparing for Devoxx France) and I had a regular GlassFish session. Instead, this year, Bert Ertman and Paul Bakker covered the 3-hour Java EE 6 University session (“Duke’s Duct Tape Adventures”) on the very first day (using GlassFish) with great success it seems. The Java EE 6 lab was also a hit with a full room of folks covering a lot of technical ground in 2.5 hours (with GlassFish of course).

GlassFish was also mentioned during Cameron Purdy’s keynote (pretty natural even if that surprised a number of folks that had not been closely following GlassFish) but also in Stephan Janssen‘s Keynote as the engine powering Parleys.com.

In fact Stephan was a speaker in the GlassFish session describing how they went from a single-instance Tomcat setup to a clustered GlassFish + MQ environment. Also in the session was Johan Vos (of Mollom fame, along other things). Both of these customer testimonials were made possible because GlassFish has been delivering full Java EE 6 implementations for almost two years now which is plenty of time to see serious production deployments on it.

The Java EE Gathering (BOF) was very well attended and very lively with many spec leads participating and discussing progress and also pain points with folks in the room. Thanks to all those attending this session, a good number of RFE’s, and priority points came out of this. While this wasn’t a GlassFish session by any means, it’s great to have the current RESTful Admin and upcoming Java EE 7 planned features be a satisfactory answer to some of the requests from the attendance.

Last but certainly not least, the GlassFish team is busy with Java EE 7 and version 4 of the product. This was discussed and shown during the Java EE keynote and in greater details in Jerome Dochez’ session. If any indication, the tweets on his demo (virtualization, provisioning, etc…) were very encouraging.

Java EE 6 adoption is doing great and GlassFish, being a production-quality reference implementation, is one of the first to benefit from this. And with GlassFish 4.0, we’re looking at increasing the product and community adoption by offering a pragmatic technical solution to Java EE PaaS deployments. Stay tuned ! (the impatient in you is encouraged to grab a 4.0 build and provide feedback).

Advertisements

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

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.

Video: Java EE 6 does Java 7 (with GlassFish 3.1.1)

Java 7 is here! and so is GlassFish 3.1.1! Get them while they’re hot!

New Java versions can sometimes take a bit of time before they’re adopted because:
a/ your IDE doesn’t support the new version and associated language constructs
b/ you’re a server-side developer and it’ll be a while before your application server supports that new version of the JDK
Well, with Java 7, things are different with the quasi-simultaneous releases of JDK 7, NetBeans 7.0.1 (coming up very soon) and GlassFish 3.1.1! Here’s a new screencast on the GlassFish Youtube Channel showing Java EE 6 development taking advantage of the project Coin features and running on GlassFish 3.1.1 and Java 7 :

JPA/EclipseLink multitenancy screencast

I find JPA and in particular EclipseLink 2.3 to be particularly well suited to illustrate the concept of multitenancy, one of the key PaaS features en route for Java EE 7.

Here’s a short (5-minute) screencast showing GlassFish 3.1.1 (due out real soon now) and its EclipseLink 2.3 JPA provider showing multitenancy in action. In short, it adds EclipseLink annotations to a JPA entity and deploys two identical applications with different tenant-id properties defined in the persistence.xml descriptor. Each application only sees its own data, yet everything is stored in the same table which was augmented with a discriminator column.

For more advanced (or more realistic) uses such as tenant property being set on the @PersistenceContext, XML configuration of multitenant JPA entities, and more check out the nicely written wiki page.

Intercepting startup and shutdown events

Startup and shutdown actions is a pretty common use-case for enterprise development and GlassFish 3.x offers at least two different ways to implement such call-backs: lifecycle modules and EJB 3.1 startup beans.

GlassFish Lifecycle modules

The first one has been around for a little while and is called Lifecycle modules. These are specific to GlassFish and thus not portable to other application servers but they offer a simple and effective way to implement behavior that applies to the entire application server instance (or to an entire cluster), independently of any deployed application.

A single class implementing com.sun.appserv.server.LifecycleListener (available from as-install/glassfish/modules/glassfish-api.jar) can intercept five different events: Initialization, Startup, Ready, Shutdown, and Termination (check the documentation for more details). Here’s a canonical example :


public class GlassFishEvents
         implements com.sun.appserv.server.LifecycleListener {

    private static final Logger logger =
          Logger.getLogger("admin.events");

    @Override
    public void handleEvent(LifecycleEvent le)
             throws ServerLifecycleException {
       switch (le.getEventType()) {
          case LifecycleEvent.INIT_EVENT:
             logger.severe("INIT_EVENT");
             break;
          case LifecycleEvent.READY_EVENT:
             logger.severe("READY_EVENT");
             break;
          case LifecycleEvent.SHUTDOWN_EVENT:
             logger.severe("SHUTDOWN_EVENT");
             break;
          case LifecycleEvent.STARTUP_EVENT:
             logger.severe("STARTUP_EVENT");
             break;
          case LifecycleEvent.TERMINATION_EVENT:
             logger.severe("TERMINATION_EVENT");
             break;
          default:
             logger.severe("UNKNOWN event");
       }
    }
}

Registering the lifecycle module can be done via the admin console or the CLI (asadmin create-lifecycle-module) with optional ordering (relative to other modules, similar to servlets), an enabled/disabled state (default is enabled) and the ability to prevent the server from starting if the module fails to load.

Startup and singleton EJB

An alternate way is to use EJB 3.1 (part of Java EE 6) and in particular a bean combining the @Startup and @Singleton annotations. Its lifecycle methods marked with JSR 250 common annotations will contain the event callback logic. Here’s a simple example simulation the creation of database tables :


@javax.ejb.Singleton
@javax.ejb.Startup
public class CreateTables {
    @PostConstruct
    public void init() {
       logger.warning("Creating tables");
    }

    @PreDestroy
    public void cleanup() {
       logger.warning("Dropping table...");
    }
}

While this offers a more portable solution, it has some notable differences with GlassFish lifecycle modules.

First of all there are only two events that can be intercepted: @PostConstruct, @PreDestroy which are application events, not runtime system events. Undeploying the application is also the only way to disable the behavior and since this is an application-level event interception, there cannot be action taken on other parts of the runtime on failure (arguably you can do a lot more in the rest of you application).

Finally there is no notion of ordering but rather you can express explicit dependencies using @DependsOn as shown here to simulate populating tables that need to be previously created :


@javax.ejb.Singleton
@javax.ejb.Startup
@javax.ejb.DependsOn("CreateTables")
public class PopulateTables {
    @PostConstruct
    public void init() {
       logger.warning("Populating tables");
    }

    @PreDestroy
    public void cleanup() {
       logger.warning("archiving table data");
    }
}

Also note that a Singleton approach only applies to a single instance (not a cluster-wide singleton). If you’re wondering which approach to chose, it really boils down to whether you want to implement system-level or application-level events.

Of course you can combine the two approaches which would trigger a log similar to this one on a startup/shutdown cycle :


SEVERE: INIT_EVENT
WARNING: Creating tables
WARNING: Populating tables
SEVERE: STARTUP_EVENT
SEVERE: READY_EVENT
...
SEVERE: SHUTDOWN_EVENT
WARNING: archiving table data
WARNING: Dropping table...
SEVERE: TERMINATION_EVENT

GlassFish 3.1, the devops appserver




Of course you can consider using the new GlassFish 3.1 because it is operations-friendly with full clustering and centralized admin or because it offers a great developer environment with fast startup, a modular architecture or application versioning but I’d like to argue that the GlassFish value is greater than sum of the parts and a devops appserver. Today.

In fact GlassFish is pursuing what it’s been doing since version 2.x: hit a middle ground between the requirements from developers (latest APIs, lightweight runtime) and those from operations (manageable, stable, centralized admin). Here are some features which I believe to be relevant to developers, operations and QA :

• Fast startup: whether you’re developing, testing or deploying an application, the time it takes to bring a service online is critical. GlassFish has had this for a while (even before 3.0) but the full modular architecture offers yet greater flexibility.

Embedded API: while the new standard EJBContainer API is a great step forward, it mostly addresses the unit testing use-case while this feature offers an API to drive the entire set of GlassFish services and features.

Maven plugin: easily integratable into your favorite continuous integration server. In a continuous deployment scenario and generally for automation, Maven and CI’s are key tools to rely on.

Domain-driven administration: the concept of a domain has been around for a while in GlassFish and with 3.1 the entire admin tools (CLI, Web and REST) scale from a single instance development or production config to a full multi-cluster environment. This makes for easy transfer of work from development to QA and/or to production and back.

• More questionable features (wrt Devops) are active redeployment and application versioning. While the former is recommended only in development the versioning feature can be used in many different ways for testing and potentially in production (with the caveat that only one application version can be active at a given point in time).

Of course there’s much more to devops than just a product or technology. Is your application server devops-friendly?