tmpsa (16) [Avatar] Offline
#1
Here's a thing that I don't think is mentioned very much in the otherwise great book:

A Timer service (EJB) survives server restart (and even crash), but not re-/un-deploy.

A good place to set up Timer services in a webapp is (I beleive) in a ServletContextListener .contextInitialized().

But this method is called BOTH at redeploy AND server restart. So after each server restart you would have another Timer service doing the same thing. Not good. Took me a few days to figure out why my maintencance tasks behaved so strangely... :-/

My solution is to have all my maintenance task EJBs subclass an abstract base superclass with a setup() method that checks for existing Timers (of the subclass) with timerService.getTimers() and not creating a new if found.

Perhaps there is a simpler way of doing this...

Cheers,
Per Lindberg
reza_rahman (456) [Avatar] Offline
#2
Re: Gotcha in Timer EJB
Per,

That is an excellent point. We'll add it in the second edition as a caveat (work is currently in progress on the second edition). The restart problem goes way with the EJB 3.1 @Schedule annotation, but for now your solution is the only fail-safe one smilie.

Cheers,
Reza
tmpsa (16) [Avatar] Offline
#3
Re: Gotcha in Timer EJB
Ah, I was wondering about that, Reza! So now it seems that there will be no reason to use naked Timers (with all the ensuing complications). smilie
reza_rahman (456) [Avatar] Offline
#4
Re: Gotcha in Timer EJB
Per,

Exactly. Also, let me know if you have suggestions for EJB in general. We are just beginning to gather ideas for the next version (the technology, not the book).

Cheers,
Reza
vset (1) [Avatar] Offline
#5
Re: Gotcha in Timer EJB
I encountered this too. Could you please explain your fix in detail please. Appreciate it.

thanks,

vs
tmpsa (16) [Avatar] Offline
#6
Re: Gotcha in Timer EJB
Like I said, have a ServletContextListener for your main servlet. In it, call a method in your
stateless EJB that sets up the Timer.

In the EJB, inject

private @Resource TimerService timerService;

Let the method check for timers with timerService.getTimers()
and create a new iff none found.

Hope this helps!