epesh
I'm Joseph Ottinger, editor of TheServerSide.com.

Calendar

««Nov 2009»»
SMTWTFS
1234567
891011121314
15161718192021
22232425262728
2930

My Bookmarks

My Top Tags

                                       

Mailing List

My RSS Feeds








Search Box

 

EJB3 timer feature still not... quite... complete, IMO

posted Wednesday, 8 March 2006
So I'm canoodling along with a finally-reinstalled Netbeans 5.5 preview, new and simple enterprise app that's being verified constantly so I can identify the very moment something goes haywire, and I'm looking at doing something very, very common: scheduled events.

I have a project where I need to do something constantly, roughly every minute. There are a lot of ways for me to do this: Quartz, cron, jcrontab, a series of other projects and invocation mechanisms. However, Quartz bothers me because it creates threads, cron is non-Java... all things that, pragmatically speaking, I can tolerate, but if you have to use pragmatism as an excuse, the standard isn't sufficient.

With EJB 3, you have a Timer service, basically where you annotate a method with a @Timeout annotation, and that method is called on the EJB when the timer elapses. Sounds horribly useful, and exactly what I rather want, except for this:

Here's a slightly modified example from the JEE tutorial, with imports trimmed for space:

@Stateless
public class TimerSessionBean implements TimerSession {
  @Resource
  TimerService timerService;

  public void createTimer(long intervalDuration) {
    Timer timer = timerService.createTimer(intervalDuration, intervalDuration,
        "Created new timer");
  }
  @Timeout
  public void timeout(Timer timer) {
    System.out.println("TimerBean: timeout occurred");
  }
} 
The change is in the createTimer(long) method, where it uses the form of TimerService.createTimer() that creates recurring events (i.e., time out in "intervalDuration" milliseconds, and every "intervalDuration" milliseconds later.) So for events that should happen every minute, I'd simply call createTimer(60000L), right?

Ah, here's where the problems start. From where? The example uses a handy-dandy application client, which gets a reference to the stateless session bean via injection (i.e., @EJB TimerSessionBean timerbean;) and it then calls timerbean.createTimer(30000);.

The problem is that I want this to start when I deploy and start the application. I don't want an explicit "start" mechanism.

I could always use a servlet, loaded on startup, but I don't know how the application shutdown (or deactivation) is supposed to affect the threads - if I redeploy the .war without necessarily deactivating everything associated with the .ear, am I looking at two event timers? I hope not.

What would be really nice is if the specification mandated that timers were server-managed resources (like, oh, queues?) and allowed me to say "TimerBean will get a single (or recurring) event every 30000 milliseconds," and I'd leave the application code out of it altogether.

Of course, maybe I'm just misinformed. I don't know, but I think if it's really as easy as I think it should be, this should be clearly documented somewhere.

tags:            




1. Jasper Bryant-Greene left...
Monday, 13 November 2006 11:13 pm :: http://jbg.name/

What I've done is used an app startup servlet to remove all existing timers for that class and then create a new one. Not the prettiest solution but obtains the necessary behaviour.


2. James Jerselius left...
Wednesday, 16 May 2007 3:05 am

Consider putting this in a (dedicated) ServletContextListener, e.g

public class MyTimerInitiationListener implements ServletContextListener{

  • public void contextInitialized(ServletContextEvent sce){

    • doStuff();

  • }

}

Don't forget the web.xml entry:

<listener> <listener-class> MyTimerInitiationListener </listener-class> </listener>


3. Dobes Vandermeer left...
Saturday, 1 November 2008 6:12 am :: http://www.dobesland.com/

Yes, I have the same problem and now I'm getting two timers firing on my server. Sigh - created a big mess for me to clean up. I'd hardly call JPA a pleasant experience to use, but I think (I hope!) they're still working on making it more usable.

I'm using the ServletContextListener approach, you can use the @EJB annotation to get a reference to the EJB, and then call a method that sets up the timers. Doesn't seem to be any other way.


4. Mattias left...
Friday, 5 June 2009 9:29 am

Try MBeans!