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
ejbTimeout
method of the bean's implementation class. TheejbTimeout
method contains the business logic that handles the timed event. BecauseejbTimeout
is defined by thejavax.ejb.TimedObject
interface, the bean class must implementTimedObject
.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 theTimerService
interface. (For details on the method signatures, see theTimerService
API 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
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 thecreateTimer
call in the bean'sejbCreate
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
andlong
parameters of thecreateTimer
methods represent time with the resolution of milliseconds. However, because the timer service is not intended for real-time applications, a callback toejbTimeout
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 itsgetHandle
method and store theTimerHandle
object in a database. (ATimerHandle
object is serializable.) To re-instantiate theTimer
object, retrieve the handle from the database and invokegetTimer
on the handle. ATimerHandle
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'sTimerHandle
object. Local clients, however, do not have this restriction.Getting Timer Information
In addition to defining the
cancel
andgetHandle
methods, theTimer
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 thecreateTimer
invocation. For example, in thecreateTimer
code snippet of the preceding section, this information parameter is aString
object with the value,created timer
.To retrieve all of a bean's active timers, call the
getTimers
method of theTimerService
interface. ThegetTimers
method returns a collection ofTimer
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 theRequiresNew
transaction attribute. With this attribute, the EJB container begins the new transaction before callingejbTimeout
. If the transaction is rolled back, the container will try to callejbTimeout
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 forTimerSessionEJB
is calledTimerSessionBean
. In the source code listing ofTimerSessionBean
that follows, note themyCreateTimer
andejbTimeout
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 invokesmyCreateTimer
with an interval duration of 30000 milliseconds. ThemyCreateTimer
method fetches aTimerService
object from the bean'sSessionContext
. Then it creates a new timer by invoking thecreateTimer
method ofTimerService
. Now that the timer is set, the EJB container will invoke theejbTimer
method ofTimerSessionBean
when the timer expires--in about 30 seconds. Here's the source code for theTimerSessionBean
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 theTimerSessionEJB
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 ajava.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 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/timersession
directory.- 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.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 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.