Timer Service Sample Application 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
- Compiling and Assembling the Sample Application
- Deploying the Sample Application
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
ejbTimeoutmethod of the bean's implementation class. TheejbTimeoutmethod contains the business logic that handles the timed event. BecauseejbTimeoutis defined by thejavax.ejb.TimedObjectinterface, the bean class must implementTimedObject.There are four interfaces in the
javax.ejbpackage that are related to timers:Creating Timers
To create a timer, the bean invokes one of the
createTimermethods of theTimerServiceinterface. (For details on the method signatures, see theTimerServiceAPI documentation.) When the bean invokescreateTimer, 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
TimerSessionEJBexample,createTimeris 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 thecreateTimercall in the bean'sejbCreatemethod.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
ejbTimeoutwhen 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
Dateandlongparameters of thecreateTimermethods represent time with the resolution of milliseconds. However, because the timer service is not intended for real-time applications, a callback toejbTimeoutmight 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
Timerobject for future reference, invoke itsgetHandlemethod and store theTimerHandleobject in a database. (ATimerHandleobject is serializable.) To re-instantiate theTimerobject, retrieve the handle from the database and invokegetTimeron the handle. ATimerHandleobject 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'sTimerHandleobject. Local clients, however, do not have this restriction.Getting Timer Information
In addition to defining the
cancelandgetHandlemethods, theTimerinterface also defines methods for obtaining information about timers:public long getTimeRemaining();
public java.util.Date getNextTimeout();
public java.io.Serializable getInfo();The
getInfomethod returns the object that was the last parameter of thecreateTimerinvocation. For example, in thecreateTimercode snippet of the preceding section, this information parameter is aStringobject with the value,created timer.To retrieve all of a bean's active timers, call the
getTimersmethod of theTimerServiceinterface. ThegetTimersmethod returns a collection ofTimerobjects.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
ejbTimeoutmethod usually has theRequiresNewtransaction attribute. With this attribute, the EJB container begins the new transaction before callingejbTimeout. If the transaction is rolled back, the container will try to callejbTimeoutat least one more time.The TimerSessionEJB Example
The source code for this example is in the
<install_dir>/samples/ejb/misc/timersession/directory.
TimerSessionEJBis a stateless session bean that shows how to set a timer. The implementation class forTimerSessionEJBis calledTimerSessionBean. In the source code listing ofTimerSessionBeanthat follows, note themyCreateTimerandejbTimeoutmethods. Because it's a business method,myCreateTimeris defined in the bean's remote interface (TimerSession) and may be invoked by the client. In this example, the client invokesmyCreateTimerwith an interval duration of 30000 milliseconds. ThemyCreateTimermethod fetches aTimerServiceobject from the bean'sSessionContext. Then it creates a new timer by invoking thecreateTimermethod ofTimerService. Now that the timer is set, the EJB container will invoke theejbTimermethod ofTimerSessionBeanwhen the timer expires--in about 30 seconds. Here's the source code for theTimerSessionBeanclass: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 theTimerSessionEJBexample, 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 ajava.rmi.RemoteExceptionwith 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 buildTimerSessionEJB, 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.
Running the Sample Application
Running the J2EE Application Client
To run the J2EE application client, perform the following steps.
- In a terminal window, go to the
<install_dir>/domains/<domain_name>/applications/j2ee-apps/timersessiondirectory.- Type the following command:
whereappclient -client timersessionClient.jar -xml<install_dir>/domains/<domain_name>/config/sun-acc.xml<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:- To run client in "
domain1" domain, enter this command:In the terminal window, the client displays these lines: 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 upserver.login 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.RemoteExceptionwith the messageEJB 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.