Skip Headers
Oracle® Containers for J2EE Enterprise JavaBeans Developer's Guide
10g Release 3 (10.1.3)
B14428-02
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
 
Next
Next
 

25 Configuring Timer Services

This chapter describes:

For more information, see "Understanding EJB Timer Services".

Configuring an EJB 3.0 EJB with a J2EE Timer

You can configure a J2EE timer on an EJB 3.0 stateless session bean or message-driven bean.

You can access the timer service using annotations and dependency injection (see "Using Annotations"), using the initial context API (see "Using Initial Context").

You can implement the timeout call back by:

Using Annotations

Example 25-1 shows how to use resource injection to acquire a J2EE timer in an EJB 3.0 EJB.

Example 25-1 Using @Resource to Acquire a J2EE Timer in an EJB 3.0 EJB

@Stateless public class EmployeeServiceBean implements EmployeeService
{
    ...
    @Resource Timer EmpDurationTimer;
    ...
    }
}

Using Initial Context

Example 25-2 shows how to use the initial context to look up a J2EE timer in an EJB 3.0 EJB.

Example 25-2 Using Initial Context to Look Up an EJB 3.0 J2EE Timer

InitialContext ctx = new InitialContext();
TimerService ts = ctx.getTimerService();
Timer myTimer = ts.createTimer(timeout, "EmpDurationTimer");

Configuring an EJB 2.1 EJB with a J2EE Timer

You can configure a J2EE timer on an EJB 2.1 stateless session bean, entity bean, or message-driven bean.

The EJB that creates the timer first retrieves the timer service—TimerService interface—through the getTimerService method of the EJBContext interface. From the TimerService interface, you can create a timer using one of the four provided createTimer methods that allow you to specify the timer as a single-event timer or as an interval timer. The timers are defined in milliseconds, even though most events are for much longer time periods. The expiration of the timer can be defined as a duration or in absolute time. In addition, the bean can pass some information to identify the timer, which must be serializable.

TimerService ts = ctx.getTimerService();Timer myTimer = ts.createTimer(timeout, "EmpDurationTimer");

The timer is created by a bean to designate when a callback method is invoked. The business logic that is to be executed when the timer expires is implemented in a callback method—ejbTimeout—within the application bean class. The bean class that uses the timer service must implement the javax.ejb.TimedObject interface, which contains the ejbTimeout method.

The created timer is associated with the identity of the bean. For entity beans, the ejbTimeout is invoked on the bean instance that created the bean; for stateless session beans and MDBs, the ejbTimeout method is invoked on any bean instance in the pool.

public abstract class EmployeeBean implements EntityBean, TimedObject
...
  public void ejbTimeout(Timer timer)  {    System.out.println("ejbTimeout() called at: " + new            Date(System.currentTimeMillis()) + " with info: " + timer.getInfo());    return;  }


Note:

There is no guarantee that the timers are executed in any order; therefore, your implementation within the ejbTimeout callback must be able to handle the callbacks in any sequence.

The TimerService provides the following methods for creating the different types of timers:

public interface javax.ejb.TimerService {
  /* After a specified duration*/
  public Timer createTimer(long duration, java.io.Serializable info);
 /* At a specifed interval */
  public Timer createTimer(long initialDuration, long intervalDuration,                                java.io.Serializable info);
  /* At a certain time */
  public Timer createTimer(java.util.Date expiration, java.io.Serializable info);
  /*  A certain duration after a specified date and time */
  public Timer createTimer(java.util.Date initialExpiration,                              long intervalDuration, java.io.Serializable info);  public Collection getTimers();}

The getTimers method retrieves all active timers associated with the bean.


Note:

Timers and their handles are local objects; therefore, they should not be passed through the bean remote interface.

Configuring an EJB with an OC4J Cron Timer

You can use an OC4J cron timer with:

You can schedule a timer to execute regularly at specified intervals. In the UNIX world, these are known as cron timers.

The following are examples of the different methods you can use in scheduling a cron timer. Where there is an asterisk, all values are valid.

Example 25-3 How to Configure Different Timers

20  * * * * --> 20 minutes after every hour, such as 00:20, 01:20, and so on
 5 22 * * * --> Every day at 10:05 P.M.
 0  8 1 * * --> First day of every month at 8:00 A.M. 
 0  8 4 7 * --> The fourth of July at 8:00 A.M. 
15 12 * * 5 --> Every Friday at 12:15 P.M.

The format of a cron time variable includes five time fields:

You can define complex timers by specifying multiple values in a field, separated by commas or a dash.

Example 25-4 Complex Timers

0  8   *   * 1,3,5 --> Every Monday, Wednesday, and Friday at 8:00 A.M.
0  8  1,15 *  *   --> The first and 15th of every month at 8:00 A.M.
0 8-17 *   * 1-5  --> Every hour from 8 A.M. through 5 P.M., Monday through Friday

You can create cron timers either through the createTimer method that takes a String with the previous five fields in it—separated by spaces—or with the createTimer method that has variables for each field. To create the cron timers, use the following Oracle-specific createTimer APIs:

EJBTimer createTimer(String cronline, Serializable info)  throws IllegalArgumentException, IllegalStateException;

EJBTimer createTimer(int minute, int hour, int dayOfMonth, int month, int dayOfWeek, int year, Serializable info) throws IllegalArgumentException, IllegalStateException;

Create the cron timers in the same manner as other timers by retrieving the extended Oracle-specific timer service, and schedule a cron timer using the createTimer method. However, since cron timers are Oracle-specific, you cast the returned object as an EJBTimerService object. The following example provides a String with the five variables separated by spaces. The timer is scheduled to execute every minute.

import oracle.ias.container.timer.EJBTimer;
import oracle.ias.container.timer.EJBTimerService;
...
String cron = "1 * * * *";  
EJBTimerService ets = (EJBTimerService) ctx.getTimerService();
EJBTimer et = ets.createTimer(cron, info);

You can also provide a class that is to be invoked within the createTimer method, as follows:

EJBTimer createTimer(String cronline, String className, Serializable info) throws IllegalArgumentException,  IllegalStateException;

EJBTimer createTimer(int minute, int hour, int dayOfMonth, int month, int dayOfWeek, String className, Serializable info) throws IllegalArgumentException, IllegalStateException;

For arbitrary Java classes, the info variable can be either null or be a String[] of parameters to pass to the main method of the class.

For example, you can have the mypackage.MyClass invoked when the get timer fires:

EJBTimerService ets = (EJBTimerService) ctx.getTimerService();
EJBTimer et = ets.createTimer(cron,"mypackage.MyClass", info);

You must provide a main method within the mypackage.MyClass, which is used as the entry point, as follows:

public static void main( String args[] )

Troubleshooting Timers

This section describes:

How to Retrieve Information About the Timer

You can retrieve information and cancel the timer through the Timer object. The methods available are cancel(), getTimeRemaining(), getNextTimeout(), getHandle(), and getInfo(). To compare for object equality, use the Timer.equals(Object obj) method.

How to Retrieve a Persisted Timer

Timers must be able to be persisted so that they can survive the life cycle of the bean (ejbLoad, ejbStore, and so on). You can retrieve a persisted Timer object through its handle. Retrieve the TimerHandle through the Timer.getHandle() method. Then, you can retrieve the persisted Timer object through the TimerHandle.getTimer() method.

Executing the Timer Within the Scope of a Transaction

The timer is normally created or cancelled within the scope of a transaction. Thus, the bean normally is configured as being within a transaction. Typically this is configured with RequiresNew. If the transaction is rolled back, then the container retries the timeout.

For more information on transactions, see the Oracle Containers for J2EE Services Guide.

What Does a NoSuchObjectLocalException Mean with Timers?

When you try to invoke a method on a timer object that has been either successfully invoked or cancelled, you will receive a NoSuchObjectLocalException.