Timer Service Sample Application

  Samples Index


Timer Service Sample Application


This document describes how to utilize the timer serviced  in conjunction with the Application Server.

This sample application document contains the following sections:


Overview

 Timer Service

Applications that model business work-flows often rely on timed notifications. The timer service of the EJB container enables you to schedule timed notifications for all types of enterprise beans except for stateful session beans. You can schedule a timed notification to occur at a specific time, after a duration of time, or at timed intervals. For example, you could set timers to go off at 10:30 AM on May 23, in 30 days, or every 12 hours.

When a timer expires (goes off), the EJB container calls the ejbTimeout method of the bean's implementation class. The ejbTimeout method contains the business logic that handles the timed event. Because ejbTimeout is defined by the javax.ejb.TimedObject interface, the bean class must implement TimedObject.

There are four interfaces in the javax.ejb package that are related to timers:

Creating Timers

To create a timer, the bean invokes one of the createTimer methods of the TimerService interface. (For details on the method signatures, see the TimerService API documentation.) When the bean invokes createTimer, the timer service begins to count down the timer duration.

The bean creates a timer as follows:

TimerService timerService = context.getTimerService();
Timer timer = timerService.createTimer(intervalDuration,
"created timer");

In the TimerSessionEJB example, createTimer is invoked in a business method, which is called by a client. An entity bean can also create a timer in a business method. If you want to create a timer for each instance of an entity bean, you could code the createTimer call in the bean's ejbCreate method.

Timers are persistent. If the server is shut down (or even crashes), timers are saved and will become active again when the server is restarted. If a timer expires while the server is down, the container will call ejbTimeout when the server is restarted.

A timer for an entity bean is associated with the bean's identity--that is, with a particular instance of the bean. If an entity bean sets a timer in ejbCreate, for example, each bean instance will have its own timer. In contrast, stateless session and message-driven beans do not have unique timers for each instance.

The Date and long parameters of the createTimer methods represent time with the resolution of milliseconds. However, because the timer service is not intended for real-time applications, a callback to ejbTimeout might not occur with millisecond precision. The timer service is for business applications, which typically measure time in hours, days, or longer durations.

Cancelling and Saving Timers

Timers may cancelled by the following events:

If a method is invoked on a cancelled timer, the container throws the javax.ejb.NoSuchObjectLocalException.

To save a Timer object for future reference, invoke its getHandle method and store the TimerHandle object in a database. (A TimerHandle object is serializable.) To re-instantiate the Timer object, retrieve the handle from the database and invoke getTimer on the handle. A TimerHandle object cannot be passed as an argument of a method defined in a remote or Web service interface. In other words, remote clients and Web service clients cannot access a bean's TimerHandle object. Local clients, however, do not have this restriction.

Getting Timer Information

In addition to defining the cancel and getHandle methods, the Timer interface also defines methods for obtaining information about timers:

public long getTimeRemaining();
public java.util.Date getNextTimeout();
public java.io.Serializable getInfo();

The getInfo method returns the object that was the last parameter of the createTimer invocation. For example, in the createTimer code snippet of the preceding section, this information parameter is a String object with the value, created timer.

To retrieve all of a bean's active timers, call the getTimers method of the TimerService interface. The getTimers method returns a collection of Timer objects.

Transactions and Timers

An enterprise bean usually creates a timer within a transaction. If this transaction is rolled back, the timer creation is also rolled back. Similarly, if a bean cancels a timer within a transaction that gets rolled back, the timer cancellation is rolled back. In this case, the timer's duration is reset as if the cancellation had never occurred.

In beans with container-managed transactions, the ejbTimeout method usually has the RequiresNew transaction attribute. With this attribute, the EJB container begins the new transaction before calling ejbTimeout. If the transaction is rolled back, the container will try to call ejbTimeout at least one more time.

The TimerSessionEJB Example

The source code for this example is in the <install_dir>/samples/ejb/misc/timersession/ directory.

TimerSessionEJB is a stateless session bean that shows how to set a timer. The implementation class for TimerSessionEJB is called TimerSessionBean. In the source code listing of TimerSessionBean that follows, note the myCreateTimer and ejbTimeout methods. Because it's a business method, myCreateTimer is defined in the bean's remote interface (TimerSession) and may be invoked by the client. In this example, the client invokes myCreateTimer with an interval duration of 30000 milliseconds. The myCreateTimer method fetches a TimerService object from the bean's SessionContext. Then it creates a new timer by invoking the createTimer method of TimerService. Now that the timer is set, the EJB container will invoke the ejbTimer method of TimerSessionBean when the timer expires--in about 30 seconds. Here's the source code for the TimerSessionBean class:

import javax.ejb.*;

public class TimerSessionBean implements SessionBean,
TimedObject {

private SessionContext context;

public TimerHandle myCreateTimer(long intervalDuration) {

System.out.println
("TimerSessionBean: start createTimer ");
TimerService timerService =
context.getTimerService();
Timer timer =
timerService.createTimer(intervalDuration,
"created timer");
}

public void ejbTimeout(Timer timer) {

System.out.println("TimerSessionBean: ejbTimeout ");
}

public void setSessionContext(SessionContext sc) {
System.out.println("TimerSessionBean:
setSessionContext");
context = sc;
}

public void ejbCreate() {
System.out.println("TimerSessionBean: ejbCreate");
}

public TimerSessionBean() {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}

}


NOTE: You must start the Database.


Note: To run the TimerSessionEJB example, you must start the PointBase server (see How to start Database) before you start the J2EE application server. If you don't start the PointBase server, or if you start it after the J2EE application server, then you will get a java.rmi.RemoteException with the message, EJB Timer service not available.


Compiling and Assembling the Sample Application

Building TimerSessionEJB

In a terminal window, go to the <install_dir>/samples/ejb/misc/timersession/ directory. To build TimerSessionEJB, type the following command:

asant   


Deploying the Sample Application

Deploying the Enterprise Application

Now that the J2EE application contains the components, it is ready for deployment.

  1. Use asant deploy  to deploy this example.


Running the Sample Application

Running the J2EE Application Client

To run the J2EE application client, perform the following steps.

  1. In a terminal window, go to the <install_dir>/domains/<domain_name>/applications/j2ee-apps/timersession directory.
  2. Type the following command:
  3.   appclient -client timersessionClient.jar
    -xml <install_dir>/domains/<domain_name>/config/sun-acc.xml   
        
    where <install_dir> is the location of where you installed your application server, and <domain_name> is the name of the domain in which this application client is running.

    For example:
    • To run client in "samples" domain, enter this command:
        appclient -client timersessionClient.jar
      -xml <install_dir>/domains/samples/config/sun-acc.xml   
          
    • To run client in "domain1" domain, enter this command:
        appclient -client timersessionClient.jar
      -xml <install_dir>/domains/domain1/config/sun-acc.xml   
          
  • In the terminal window, the client displays these lines:
  •   Creating a timer with an interval duration of 30000 ms. 
        

    The output from the timer is sent to the server.log located in the <install_dir>/domains/<domain_name>/server/logs/ directory. After about 30 seconds, open up server.log in a text editor and you will see the following lines:

    TimerSessionBean: setSessionContext
    TimerSessionBean: ejbCreate
    TimerSessionBean: start createTimer
    TimerSessionBean: ejbTimeout

    Troubleshooting

    Note: You must have started the PointBase server before you started the J2EE application server in order to run this example. If you get a java.rmi.RemoteException with the message EJB Timer service not available, the PointBase server is either not running, or was not started before the J2EE application server.


       

    All of the material in this example is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.