Saturday, August 20, 2016

Quick Solution: Scheduler / Background Job in a Web Application

 EJB available? Use @Schedule

If your environment happen to support EJB (e.g. WildFly, JBoss AS/EAP, TomEE, GlassFish, etc), then use @Schedule instead.
 


@Singleton
public class BackgroundJobManager {

    @Schedule(hour="0", minute="0", second="0", persistent=false)
    public void someDailyJob() {
        // Do your job here which should run every start of day.
    }

    @Schedule(hour="*/1", minute="0", second="0", persistent=false)
    public void someHourlyJob() {
        // Do your job here which should run every hour of day.
    }

    @Schedule(hour="*", minute="*/15", second="0", persistent=false)
    public void someQuarterlyJob() {
        // Do your job here which should run every 15 minute of hour.
    }
 
    @Schedule(hour="*", minute="*", second="2", persistent=false)
    public void someSecondlylyJob() {
        // Do your job here which should run every 2 seconds of a minute.
    } 

} 
 
 


Yes, that's really all. The container will automatically pickup and manage it.

EJB unavailable? Use ScheduledExecutorService

If your environment doesn't support EJB (i.e. not a real Java EE server, e.g. Tomcat, Jetty, etc), use ScheduledExecutorService. This can be initiated by a ServletContextListener. Here's a kickoff example:


@WebListener
public class BackgroundJobManager implements ServletContextListener {

    private ScheduledExecutorService scheduler;

    @Override
    public void contextInitialized(ServletContextEvent event) {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
        scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
        scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        scheduler.shutdownNow();
    }

}


Where the job classes look like this:
 
 
public class SomeDailyJob implements Runnable {

    @Override
    public void run() {
        // Do your daily job here.
    }

}
 
public class SomeHourlyJob implements Runnable {

    @Override
    public void run() {
        // Do your hourly job here.
    }

} 
 
public class SomeQuarterlyJob implements Runnable {

    @Override
    public void run() {
        // Do your quarterly job here.
    }

}
 

Do not ever think about using java.util.Timer/java.lang.Thread in Java EE

Never directly use java.util.Timer and/or java.lang.Thread in Java EE. This is recipe for trouble.

No comments:

Post a Comment