Spring boot @Scheduler not working on tomcat

Viewed 3439

I have a @Scheduled method which runs without a problem when I build my Spring Boot application using embedded tomcat. But when i build my project in .war and deploy it using tomcat v8, it seem like scheduler not trigger. Other functions working great just this scheduler not trigger on my server.

@Component
public class DeleteUser {

@Autowired
private UserService userService;

@Autowired
private UserAuthoritiesService userAuthService;

private static final Logger logger = LoggerFactory.getLogger(DeleteUser.class);

private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

//(cron="second, minute, hour, day of month, month, day(s) of week")
@Scheduled(cron="0 0 8 * * *", zone="Asia/Kuala_Lumpur")
public void schedulerDeleteUser() {

    List<User> ls = userService.getAllInactiveUser3Day(new Date());

    try {
        if(ls.size()>0) {

            for(User user: ls) {
                userService.updateStatusAccount(false, user.getId());
            }
        }
    }
    catch(Exception e) {
        logger.error(e.getMessage());
    }
    logger.info("Scheduler run at {}", dateFormat.format(new Date()));
  }
}
1 Answers

I had the same problem: everything working fine on built-in tomcat server but not when I've deployed .war file into production. I've tried a few things to solve it (don't remember exactly which particular one worked) and eventually I've ended up with the following:

  1. I have dedicated scheduler configuration class:

    @Configuration
    @EnableScheduling
    @EnableAsync
    public class SchedulerConfiguration implements SchedulingConfigurer {
    
        private final int POOL_SIZE = 2;
        private final String THREAD_NAME_PREFIX = "task-scheduler-";
    
        @Override
        public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
            ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    
            threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
            threadPoolTaskScheduler.setThreadNamePrefix(THREAD_NAME_PREFIX);
            threadPoolTaskScheduler.initialize();
    
            scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
        }
    }
    

    I guess, what's most important above are @EnableScheduling and @EnableAsync annotations (I didn't had the 2nd one before)

  2. Last but not least, I have noticed that my main application class wasn't extending SpringBootServletInitializer so I have fixed that too:

    public class SpringBootApplication extends SpringBootServletInitializer {
        public static void main(String[] args) {
            SpringApplication.run(MarketplaceMonitorApplication.class, args);
        }
    }
    

    Without it, application started but @Scheduling wasn't working.. or I fixed that earlier and forget :-) Anyway, please make sure you have it! ;-)

Now everything works on the production as expected.

Related