18 - Introduction to Timer Service

Introduction

Timer service is a JEE utility that can be used to schedule notifications in enterprise applications. In other words, In case you need to run an action on a specific time in future (i.e. 10/10/2015 – assuming current date is 10/10/2014), or you need to repeat an action every specific amount of time (i.e. every 10 minutes) then the timer service is the utility that you need.

JEE7 provides 2 types of timers, programmatic timers and automatic timers.

Programmatic Timers

Programmatic timers are the timers that are initiated by the application code itself on a specific action, in other words, you have to code some lines to start the timer when you need to (i.e. when the user clicks the start timer button, the timer should start immediately).

package com.ejb3.timer;

import javax.annotation.Resource;
import javax.ejb.ScheduleExpression;
import javax.ejb.Singleton;
import javax.ejb.Timeout;
import javax.ejb.TimerService;

@Singleton
public class ProgTimer {

    @Resource
    private TimerService timerService;

    @Timeout
    public void timeOut() {
        System.out.println("Method Invoked");
    }

    public void initTimer() {
        System.out.println("INIT-CALLED");
        ScheduleExpression exp = new ScheduleExpression();
        exp.hour("*").minute("*").second("*/4");
        timerService.createCalendarTimer(exp);
    }
}

The above example creates a timer bean that when initialized, the timeOut method will be invoked every 4 seconds. The method initTimer can be invoked from a Servlet or another EJB object. You can also make the timer start automatically using the @Startup and @PostConstruct annotations, the @Startup for the bean and @PostConstruct for the initTimer method, like the following:

package com.ejb3.timer;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.ScheduleExpression;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.TimerService;

@Singleton
@Startup
public class ProgTimer {

      @Resource
      private TimerService timerService;

      @Timeout
      public void timeOut() {
        System.out.println("Method Invoked");
      }

      @PostConstruct
      public void initTimer() {
        System.out.println("INIT-CALLED");
        ScheduleExpression exp = new ScheduleExpression();
        exp.hour("*").minute("*").second("*/4");
        timerService.createCalendarTimer(exp);
    }
}

Automatic Timers

Automatic timers are the timers that are initiated by the EJB container due to the deployment of beans that are marked with @Schedule/@Schedules annotations. The above example can be converted to automatic timer as shown below:

package com.ejb3.timer;

import javax.ejb.Schedule;
import javax.ejb.Singleton;

@Singleton
public class AutoTimer {

    @Schedule(hour="*", minute="*", second="*/4")
    public void timeOut() {
        System.out.println("Method Invoked");
    }
} 

 

This will give the same effect of invoking the method timerOut every 4 seconds. Just a note - when trying to deploy timers on JBOSS, sometimes you may face  issues due to caching old timers. To handle this, you will need to stop JBOSS, delete the tmp and data directory, then start JBOSS again.

Timers Scheduling Expressions

Scheduling expressions are the expressions used to configure the timer running intervals (i.e. every minute, every 10 seconds, day number 5 in each month…etc.), the expression syntax is similar to the UNIX Cron utility

The available attributes in the expressions are second, minute, hour, dayOfWeek, dayOfMonth, month, year

The expression attributes can be fixed values (i.e. 1, 20, 30), range (i.e. 9-7, 1-7, 40-50), multiple values (i.e. “10, 20-30, 50”), interval (i.e. minute=”30/2”, this means every 2 seconds in the second half of the minute) or wildcard expression (i.e. minute=”*”, this will mean every minute, second=”*/4”, this will mean every 4 seconds)

Examples:

  • Second=”*”, minute=”*”, Hour=”*”, execute the timer every second
  • Second=”*/10”, minute=”*”, Hour=”*”, execute the timer every 10 second
  • Second=”30/10”, minute=”*”, Hour=”*”, execute the timer every 10 second from the 2nd half of the minute
  • dayOfMonth=”1”, month=”*”, execute the timer on the first day of every month
  • dayOfWeek=”Fri”, execute the timer every friday

Canceling Timers

Canceling a timer can be done using 2 ways, calling the cancel method on a Timer object that is passed to a timeout (@Schedule) method, or calling the getTimers method of a TimerService object and then calling the cancel method.

package com.ejb3.timer;

import javax.annotation.Resource;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.ejb.Timer;
import javax.ejb.TimerService;

@Singleton
public class AutoTimer {

        @Resource  
        private TimerService timerService; 

        @Schedule(hour="*", minute="*", second="*/4")
        public void timeOut(Timer timer) {
        System.out.println("Method Invoked");
        stopTimers(); // or just timer.cancel();
        }
  
        public void stopTimers() {
        for(Timer timer : timerService.getTimers())
            timer.cancel();
    }
}

Transaction Rollback Effect

Creating a Timer inside a transaction causes the timer creation to rollback in case the transaction is rolled back, and also the timer canceling will be rolled back in case the transaction that the cancel method is called inside, is rolled back.

@Timeout annotation has the same effect of using the transaction attribute value of Required or RequiresNew when using container managed transactions. This means that a transaction will  always exist during the execution of the timer timeout method. In case of errors and that transaction should rollback, the container will cause the timeout method to be fired one more time.

 

Like us on Facebook