How to start an EJB Timer on deployment?
Asked Answered
S

3

10

I need to create an interval Timer that is set to run once a week automatically. I don't want it to start based on user input, but I want it to be created when the application is deployed to the server. Every example that I have seen has another class starting the timer. I don't want to use a message driven bean to create the timer because the audit should just query a database for a given time period and is not based off of actions which send messages.

I have included an example of a Timer. In the example below, the timer should fire every 10 minutes. As a test I want the timer to fire every 10 minutes so I can test the timer.

@Stateless
public class TimerTest implements
        TimerTestLocal, TimerTestRemote{

    @Resource 
    private TimerService timerService;
    private Logger log = Logger.getLogger(TimerTest.class);
    private long interval = 1000 * 60 * 10;
    private static String TIMER_NAME = "AuditTimer";

    public void scheduleTimer() throws NamingException {
        // TODO Auto-generated method stub
        Calendar cal = Calendar.getInstance();
        //cal.set(Calendar.HOUR_OF_DAY, 23);//run at 11pm
        //cal.set(Calendar.MINUTE, 00);
        //cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm");
        log.debug("schedule for: " + sdf.format(cal.getTime()));

        timerService.createTimer(cal.getTime(), interval, TIMER_NAME);
    }

    public void cancelTimer() {
        for(Object obj : timerService.getTimers())
        {
            Timer timer = (Timer)obj;
            if(timer.getInfo().equals(TIMER_NAME))
                timer.cancel();
        }
    }

    @Timeout
    public void timerEvent(Timer timer) {
        log.debug("timer fired");
    }


}

So is there any way that I can start this timer when the application is deployed? I don't think it's a good idea to put the creation of the Timer in a @PostConstruct method because of class loaders on in the server.

Springbok answered 12/8, 2009 at 12:36 Comment(0)
S
16

The way that I've done timers in the past is to create a context listener in the web.xml to configure the timer.

That way you can ensure that it is started with the container, and shut down cleanly when the app is taken down.

Skip answered 12/8, 2009 at 13:4 Comment(0)
I
25

If your project can use jee6 / ejb3.1 there is a much better solution to this problem. http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html

@javax.ejb.Schedule(minute="*/10", hour="*")
public void automaticTimeout() {
    logger.info("Automatic timeout occured");
}

By using the new @Schedule annotation you have extensive control about when and how often a timeout method will be called. The big upside: you no longer have to start the timer "from outside".

Oracle writes:

Automatic timers are created by the EJB container when an enterprise bean that contains methods annotated with the @Schedule or @Schedules annotations is deployed. An enterprise bean can have multiple automatic timeout methods, unlike a programmatic timer, which allows only one method annotated with the @Timeout annotation in the enterprise bean class.

Idel answered 1/12, 2011 at 14:32 Comment(1)
To answer your other QuestionIdel
S
16

The way that I've done timers in the past is to create a context listener in the web.xml to configure the timer.

That way you can ensure that it is started with the container, and shut down cleanly when the app is taken down.

Skip answered 12/8, 2009 at 13:4 Comment(0)
C
1

I don't know whether using the contextListener to start the timer can work. From this article, how to use EJb 3 timer in a weblogic 10 cluster, it looks like you may run into some problems in weblogic 10.3.2.

Clerihew answered 1/11, 2010 at 19:58 Comment(1)
I found the same problem in JBoss EAP 5.1. The EJB isn't accessible at the time the context listener is invoked.Purposive

© 2022 - 2024 — McMap. All rights reserved.