2

We have a need to run a housekeeping thread in an EJB3.0 container. We currently have a "TimerService" @Stateless EJB (necessary because it has has other @EJBs injected), which creates an interval EJB Timer when it's startTimer() method is called. There should only be one instance of this timer thread. The current solution involves calling startTimer() from the init() method of one of our servlets, where the servlet is forced to load at startup using in the web.xml, but that feels like coincidental behaviour instead of the right way to do things. We've already had a problem because someone else subclassed that servlet, which meant that init() was called twice, which meant two timer threads.

This feels like it's not an unusual requirement, so what's the proper way to do this, if anything? It seems to me like there ought to be a simple way to ask the container to start a thread when it starts up, without having to tie it to other resources in the container.

RevBingo
  • 307
  • 1
  • 12
  • perhaps related? http://stackoverflow.com/questions/2707733/eager-auto-loading-of-ejb-load-ejb-on-startup-on-jboss – Bozho Dec 02 '10 at 13:47
  • Thanks - the accepted answer applies to EJB3.1, which we're not using, but of interest is the other answer, which mentions that the best way prior to 3.1 is the solution we're currently using :( – RevBingo Dec 02 '10 at 13:49

3 Answers3

1

For EJB < 3.1 you are going to have to get application server specific or hackish. Since you mention you are using JBoss, you can use the @Management tag which has defined lifecycle methods.

Yishai
  • 90,445
  • 31
  • 189
  • 263
0

Does your app server support "startup beans"? I ask because in WebSphere Application Server, there is an option in the administrative console to set the server to fire "startup beans" on server start up. We use it for certain applications we have that require a lot of "heavy loading" and initializing, so that way we can minimize start up time for the end-user experience. Here is a link to WAS 6 documention (old, I know, but still helpful). Startup beans

I know this is specific to IBM WebSphere, but perhaps your app server (if not WebSphere) has something similar to help you kick them off?

Chris Aldrich
  • 1,904
  • 1
  • 22
  • 37
0

I want to suggest 2 solutions.

1 The fix to your implementation. make your servlet final. this will avoid subclassing. But the servlet still may be deployed twice. To avoid this create static boolean variable into the servlet. The init should check this variable. If it is false it turns it to true and continues. Otherwise it throws exception.

This is fast fix that you can do now. but it is not a "right" solution. For example this will not work in clustered environment.

2 There are 2 "right" solutions.

2.1. use quartz

2.2. Implement timer using JCA. Connector is the only place in J2EE where you can legally use threads and timers.

I mentioned JCA in other context in this article: http://alexradzin.blogspot.com/2010/10/send-delayed-jms-messages.html You are welcome to view it and see a short code sample that can probably help you.

AlexR
  • 114,158
  • 16
  • 130
  • 208