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.
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.
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.
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.
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).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With