EJB Timer Service – A Close Look
Introduction
The EJB 2.1 specification introduced a new feature that allows transactional, time-based event notifications. In this article we will discuss how can you use the Timer functionality to use to schedule business activity. We will take an Entity bean as an example and demonstrate what you have to do to create a timer and use this in a J2EE container like OC4J to schedule a recurring task that occur at a regular interval. Also we will discuss the benefits and limitations of the Timer service and take a look how Oracle has extended the EJB Timer functionality to support cron timers.
What is a Timer Service?
The EJB Timer is a service managed by EJB Container to allow EJB methods to register to call back at a schedule time. Essentially the EJB Timers provides facilities like crontab process of UNIX world to schedule. The Timer could be a single-event Timer that can occur at a specific time or after a specific elapsed duration or an interval timer that may occur at specific intervals.
For example, you can use the timer service can be used do one of the following:
- Run an attendance report after every 8 hours after completion of a job shift
- Cleanup a temporary database table at the end of the day
- Update the employee table from a remote location every week
Let’s assume that you have to implement a business activity that needs to be invoked at a regular interval after 30 mts.
Using a Timer Service
You can use Timer Service with all types of EJBs except Stateful EJBs. The TimerService is accessed by an EJB via its EJBContext. A timer created by an entity bean is associated with the identity of bean instance.
In order to use a Timer service you have to do the following:
- The EJB bean class must implement javax.ejb.TimedObject
- Create a method in the EJB bean class to invoke and create the timer object. Expose the method in the remote/local interface of the EJB. This method will be called by the clients to intialize the timer.
- Implement the ejbTimeOut() method to perform the business logic when the timer is expired
In this example, we have a requirement to have a business activity occur at a regular interval of time so we need to create an interval timer. You have to use the createTimer() method to create the Timer. As we want to create an interval timer that expires after regular interval we will pass the initial expiration time and the interval as parameters. Please note that the interval is specified in milliseconds.
In my EJB, I have a method named initializeTimer() that creates the Timer service to be invoked by the client that occurs after a regular interval after a specified time.
public void initializeTimer(Date firstDate, long timeout, String info) throws RemoteException
{
try {
TimerService ts = ctx.getTimerService();
ts.createTimer(firstDate, timeout, info);
System.out.println("Timer created at " + new Date(System.currentTimeMillis()) +
" with a timeout: " + timeout + " and with info: " + info);
System.out.println(" Collection info : " + ts.getTimers());
} catch (Exception e) {
System.out.println("Exception after create timer : "+ e.toString());
}
return;
}
Implement the Business Logic
You have to implement the business logic in the ejbTimeout() method of the EJB as follows in my example:
public void ejbTimeout(Timer timer)
{
System.out.println("ejbTimeout() called at: " + new Date(System.currentTimeMillis()) +
" with info: " + timer.getInfo());
System.out.println("Generating Report”);
return;
}
Initializing the Timer Service
You have to call the intializeTimer() method of the EJB in your client to initialize the timer service. You probably do want to hardcode the initial expiration time and interval in your applications and either pass as a parameter from your deployment descriptors or supplied by the users according to the business requirement.
// create employee bean
Employee rec = (Employee) home.create(empNo, empName, salary);
System.out.println("Employee bean Created for empNo:"+empNo +"<br>");
// Set up timers - param in millisec
Date firstDate = new java.util.Date();
rec.initializeTimer(firstDate, timerDuration, timerName);
You have to pass the value for Date as java.util.Date, timeDuration as milliseconds so you have to pass 1800000 if you want your business process to execute after every 30mts.
When the application will execute this code, this will create the timer service and the container will invoke the call the ejbTimeout() method at the required interval.
Full source code for a sample application that uses a Timer with entity bean is available for download at Oracle Technology Network at http://otn.oracle.com/tech/java/oc4j/1003/how_to/how-to-ejb-timer.zip.
Benefits of Timer service
1) J2EE standard and supported
EJB Timers are part of J2EE standard and will be supported all application server vendors and your application will be portable across containers. Also you do not worry about extra configuration that is required for an external Timer service/job scheduler like Quartz.
2) Container Managed
Timer is a container managed service and you do not worry about a separate thread pools/user threads that are required from an external scheduler.
3) Transactions Support
Transactions are fully supported with Timers. Normally timers are created within a scope of transaction and hence timer is cancelled when transaction is rolled back. You would like to specify the transaction attribute for the ejbTimeout() method as follows:
<container-transaction>
<method>
<ejb-name>EmployeeBean</ejb-name>
<method-name>ejbTimeout</method-name>
</method>
<trans-attribute>RequiresNew</trans-attribute>
</container-transaction>
4) Timer Persistence
Timers are persisted and survive EJB life cycles and container crash.
4) Timer Clustering
Vendors are coming up implementations that will make Timers highly available. Oracle plans to support for clustering support fof Timers in a future release of Oracle Application Server.
Limitations of Timer Service
1) These are coarse-grained service and may not be suitable for real-time events.
2) Lacks support for cron based a timer that is popular.
3) EJB Timer is a part of J2EE 1.4 and there is no production application server from leading vendors like Oracle, BEA and IBM and that has J2EE 1.4 support.
CRON Timers with EJBs – A possibility with vendor extensions
In the UNIX world, you can schedule a timer to execute regularly at specified intervals known as cron timers. Unfortunately EJB specification does not support cron Timers. However some vendors like Oracle has extended their EJB containers to support cron timers with EJBs. You can use cron expressions for scheduling Timer events with EJBs with OracleAS containers for J2EE (OC4J) 10.0.3.
Some examples of cron expressions are as follows:
0 8 4 7 * ---> The fourth of July at 8:00 A.M.
15 10 * * 15 ---> Every Friday at 10:15 A.M.
If you want to use cron Timers with EJB you have to use Oracle specific APIs to create the Timer. You have to pass the cron expression as a parameter to the parameter to the createTimer method.
Following is the code example that depicts the use of CRON timers with EJB:
import oracle.ias.container.timer.EJBTimer;
import oracle.ias.container.timer.EJBTimerService;
...
String cronExpr = "0 8 4 7 * ";
EJBTimerService ets = (EJBTimerService) ctx.getTimerService();
EJBTimer et = ets.createTimer(cronExpr, info);
The cron EJBTimer service in OC4J can also specify an arbitrary Java class that can be scheduled to be invoked when a cron timer expires. Here is code example that demonstrates scheduling of an arbitrary Java class
EJBTimerService ets = (EJBTimerService) ctx.getTimerService();
EJBTimer et = ets.createTimer(cronExpr,"mypackage.MyTimerClass", info);
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.
You must provide a main method within the mypackage.MyTimerClass, which is used as
The entry point, as follows:
public static void main( String args[] )
Conclusion
EJB Timers are very useful and can be used to schedule business activity that need be invoked at a specified time or at regular interval. Timer Service inherits all benefits of EJBs like container support for transactions, persistence, etc.
References and further reading
1) EJB 2.1 specification at http://java.sun.com/j2ee/
2) EJB 2.1 The Timer Service by Richard Monson-Haefel at http://www.theserverside.com/articles/article.tss?l=MonsonHaefel-Column4
4:24:32 AM
|