Using the Timer Service
Applications that model business work flows often rely on timed notifications. The timer service of the enterprise bean 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 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 described in The TimerSessionBean Example creates a timer as follows:
TimerService timerService = context.getTimerService(); Timer timer = timerService.createTimer(intervalDuration, "created timer");In the
TimerSessionBeanexample,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 can 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.Canceling and Saving Timers
Timers can be canceled by the following events:
If a method is invoked on a canceled 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 reinstantiate 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 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 valuecreated 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 that use container-managed transactions, the
ejbTimeoutmethod usually has theRequiresNewtransaction attribute to preserve transaction integrity. 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 TimerSessionBean Example
The source code for this example is in the
<INSTALL>/j2eetutorial14/examples/ejb/timersession/src/directory.
TimerSessionBeanis a stateless session bean that shows how to set a timer. The implementation class forTimerSessionBeanis 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 can be invoked by the client. In this example, the client invokesmyCreateTimerwith an interval duration of 30,000 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() {} }Building TimerSessionBean
In a terminal window, go to the
<INSTALL>/j2eetutorial14/examples/ejb/timersession/directory. To buildTimerSessionBean, type the following command:Use
deploytoolto package and deploy this example.Creating the Application
In this section, you'll create a J2EE application named
TimerSessionApp, storing it in the fileTimerSessionApp.ear.
- In
deploytool, select FileNew
Application.
- Click Browse.
- In the file chooser, navigate to
<INSTALL>/j2eetutorial14/examples/ejb/timersession/.- In the File Name field, enter
TimerSessionApp.ear.- Click New Application.
- Click OK.
- Verify that the
TimerSessonApp.earfile resides in<INSTALL>/j2eetutorial14/examples/ejb/timersession/.Packaging the Enterprise Bean
Start the Edit Enterprise Bean wizard by selecting File
New
Enterprise JavaBean. The wizard displays the following dialog boxes.
- In the Introduction dialog box:
- In the EJB JAR dialog box:
- Select the button labeled Create New JAR Module in Application.
- In the combo box below this button, select
TimerSessionApp.- In the JAR Display Name field, enter
TimerSessionJAR.- Click Edit Contents.
- In the tree under Available Files, locate the
<INSTALL>/j2eetutorial14/examples/ejb/timersession/build/directory.- Select these classes:
TimerSession.class,TimerSessionBean.class, andTimerSessionHome.class.- Click Add.
- Click OK.
- Click Next.
- In the General dialog box:
- In the Enterprise Bean Class combo box, select
TimerSessionBean.- In the Enterprise Bean Name field, enter
TimerSessionBean.- Under Bean Type, select Stateless Session.
- In the Remote Interfaces section, select
TimerSessionHomefor the Remote Home Interface, andTimerSessionfor the Remote Interface.- Click Next.
- In the Expose as Web Service Endpoint dialog box:
- Click Finish.
Compiling the Application Client
The application client files are compiled at the same time as the enterprise bean files.
Packaging the Application Client
To package an application client component, you run the New Application Client wizard of
deploytool. During this process the wizard performs the following tasks.To start the New Application Client wizard, select File
New
Application Client. The wizard displays the following dialog boxes.
- Introduction dialog box
- JAR File Contents dialog box
- Select the button labeled Create New AppClient Module in Application.
- In the combo box below this button, select
TimerSessionApp.- In the AppClient Display Name field, enter
TimerSessionClient.- Click Edit Contents.
- In the tree under Available Files, locate the
<INSTALL>/j2eetutorial14/examples/ejb/timersession/builddirectory.- Select the
TimerSessionClient.classfile.- Click Add.
- Click OK.
- Click Next.
- General dialog box
Specifying the Application Client's Enterprise Bean Reference
When it invokes the
lookupmethod, theTimerSessionClientrefers to the home of an enterprise bean:You specify this reference as follows.
- In the tree, select
TimerSessionClient.- Select the EJB Ref's tab.
- Click Add.
- In the Coded Name field, enter
ejb/SimpleTimerSession.- In the EJB Type field, select
Session.- In the Interfaces field, select
Remote.- In the Home Interface field, enter
TimerSessionHome.- In the Local/Remote Interface field, enter
TimerSession.- In the JNDI Name field, select
TimerSessionBean.- Click OK.
Deploying the Enterprise Application
Now that the J2EE application contains the components, it is ready for deployment.
- Select
TimerSessionApp.- Select Tools
Deploy.
- Under Connection Settings, enter the user name and password for the Application Server.
- Under Application Client Stub Directory, check Return Client Jar.
- In the field below the checkbox, enter
<INSTALL>/j2eetutorial14/examples/ejb/timersession/.- Click OK.
- In the Distribute Module dialog box, click Close when the deployment completes.
- Verify the deployment.
Running the Application Client
To run the application client, perform the following steps.
The output from the timer is sent to the
server.logfile located in the<J2EE_HOME>/domains/domain1/server/logs/directory.View the output in the Admin Console:
Alternatively, you can look at the log file directly. After about 30 seconds, open
server.login a text editor and you will see the following lines: