mardi mai 24, 2011

Intercepting startup and shutdown events

This blog has moved to alexismp.wordpress.com
Follow the link for the most up-to-date version of this blog entry.

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

vendredi sept. 07, 2007

Geronimo and GlassFish startup time compared

Julien has a comparison of open source application servers in which has an interesting quote about Geronimo's startup time :

"The startup is a bit slow: I suspect that the GBeans framework (IoC) flexibility price is some CPU time."

The interesting part to me was Julien making a connection between startup performance and IoC. Trying for myself the Tomcat incarnation of Geronimo 2.0.1 (at 55MB, the download is the same as GlassFish v2 which comes with clustering, WSIT, and OpenESB), I obtained the following start-up time -

On my machine, using Java 6, a Geronimo warm start is 43 seconds (cold start with Java 5 is 60sec). A good chunk of that time is taken by starting the EJB container. GlassFish v2 on the same machine starts in 10 seconds (stopping actually takes almost longer than starting!).

To be fair, startup time was an important effort for GlassFish v2 resulting in not all services being started as part of those 10 seconds. So I also tried Little-G which also starts up in 10 seconds. Such identical figures don't make startup-time an argument in favor of having the stripped-down version.

As a reminder, the demo of the preview of GlassFish v3 this year at JavaOne showed the HK2 kernel and the web container start in about a second. Now GlassFish v3 work is only starting, but I understand the goal is to improve startup time and to contradict Julien's thinking about flexible architectures ;). Modularity shouldn't come at price.

About

This blog has moved

Alexis Moussine-Pouchkine's Weblog

GlassFish - Stay Connected

Search

Archives
« avril 2014
lun.mar.mer.jeu.ven.sam.dim.
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today
Blogroll

No bookmarks in folder

News

No bookmarks in folder