Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Provide time zone to Spring @Scheduled?

How can I configure the time zone for a Spring based @Scheduled cron job?

Background:

I have a job that executes once a day, say 2 PM, using Spring's @Scheduled annotation:

@Scheduled(cron = "0 0 14 * * *") public void execute() {     // do scheduled job } 

The problem is that 2 PM differs between different servers, because Spring uses on TimeZone.getDefault() internally. Moreover, the JavaDoc of TimeZone.getDefault() states that:

Gets the default TimeZone for this host. The source of the default TimeZone may vary with implementation.

In other words, the time zone is not determined. It may depend on JVM implementation, server time zone configuration, server location, and / or other unknown factors. Consequently, the cron job triggers on different times on different servers, unless there is a way to explicitly set which time zone that should be used?

I am using Spring 3.2.2.


Update

As of Spring 4, Spring Jira issue SPR-10456 has been resolved. Consequently, the @Scheduled annotation has a new zone attribute for exactly this purpose.

like image 327
matsev Avatar asked Apr 10 '13 15:04

matsev


People also ask

How do you give a timezone in cron expression?

You can use the CRON_TZ environment variable, excerpt from man 5 crontab on a CentOS 6 server: The CRON_TZ specifies the time zone specific for the cron table. User type into the chosen table times in the time of the specified time zone. The time into log is taken from local time zone, where is the daemon running.

What is @scheduled annotation in Java?

Adding a @Schedule annotation on an enterprise bean marks that method as a timeout method according to the calendar schedule specified in the attributes of @Schedule .

What is @scheduled in spring?

Spring Core. Spring provides excellent support for both task scheduling and asynchronous method execution based on cron expression using @Scheduled annotation. The @Scheduled annotation can be added to a method along with trigger metadata.


1 Answers

It turned out that I could not use the @Scheduled annotation, but I implemented a work-around. In the JavaDoc of the SchedulingConfigurer it is stated that:

[SchedulingConfigurer is] Typically used for setting a specific TaskScheduler bean to be used when executing scheduled tasks or for registering scheduled tasks in a programmatic fashion as opposed to the declarative approach of using the @Scheduled annotation.

Next, I changed the cron job to implement the Runnable interface and then updated my configuration file to implement the SchedulingConfigurer, see below:

@Configuration @EnableScheduling @ComponentScan("package.that.contains.the.runnable.job.bean") public class JobConfiguration implements SchedulingConfigurer {      private static final String cronExpression = "0 0 14 * * *";     private static final String timeZone = "CET";      @Autowired     private Runnable cronJob;      @Bean     CronTrigger cronTrigger() {         return new CronTrigger(cronExpression, TimeZone.getTimeZone(timeZone));     }      @Override     public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {         taskRegistrar.addCronTask(new CronTask(job, cronTrigger()));     } } 

Please read the JavaDoc of the @EnableScheduling for more information.


Update

As of Spring 4, Spring Jira issue SPR-10456 has been resolved. Consequently, the @Scheduled annotation has a new zone attribute for exactly this purpose, e.g.

@Scheduled(cron = "0 0 14 * * *", zone = "CET") public void execute() {     // do scheduled job } 
like image 119
matsev Avatar answered Sep 17 '22 12:09

matsev