Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start an EJB Timer on deployment?

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.

like image 777
scheibk Avatar asked Aug 12 '09 12:08

scheibk


People also ask

What is the EJB Timer Service?

EJB Container calls the method, which is annotated by @Timeout. EJB Timer Service is a service provided by EJB container, which helps to create timer and to schedule callback when timer expires.

What is @timeout in EJB?

EJB - Timer Service. Timer Service is a mechanism by which scheduled application can be build. For example, salary slip generation on the 1st of every month. EJB 3.0 specification has specified @Timeout annotation, which helps in programming the EJB service in a stateless or message driven bean.

Can I configure the EJB3 Timer Service to use a DataSource?

From JBoss EAP 6.4 you can configure the EJB3 Timer Service to use a datasource instead of a local directory. There is a minor performance cost to this option but it has the advantage of decreasing risk to timer data in the event of a local storage issue.

What is the difference between OC4J timer and EJB timer?

Timers apply to all EJB types except stateful session beans and EJB 3.0 entities. EJB timers are supported only in an OC4J instance that runs on a single JVM (where numprocs=1 in the <process-set> element of the opmn.xml configuration file).


2 Answers

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.

like image 152
seafoxx Avatar answered Nov 15 '22 20:11

seafoxx


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.

like image 37
Jesse Avatar answered Nov 15 '22 20:11

Jesse