ThreadPoolTaskScheduler is used to create a thread pool that manages scheduler task. These threads will run periodically based on the time interval that has been configured. Configured parameters must be initialized before the schedulers are used.
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-12-21 06:14:22.771 ERROR 16366 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: ThreadPoolTaskScheduler not initialized
at org.springframework.util.Assert.state(Assert.java:73) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler.getScheduledExecutor(ThreadPoolTaskScheduler.java:155) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler.scheduleAtFixedRate(ThreadPoolTaskScheduler.java:346) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.scheduling.config.ScheduledTaskRegistrar.scheduleFixedRateTask(ScheduledTaskRegistrar.java:479) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.scheduling.config.ScheduledTaskRegistrar.scheduleFixedRateTask(ScheduledTaskRegistrar.java:453) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.scheduling.config.ScheduledTaskRegistrar.scheduleTasks(ScheduledTaskRegistrar.java:374) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.scheduling.config.ScheduledTaskRegistrar.afterPropertiesSet(ScheduledTaskRegistrar.java:349) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.finishRegistration(ScheduledAnnotationBeanPostProcessor.java:302) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:233) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:105) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:403) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:360) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:897) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at com.yawintutor.SpringSchedulerApplication.main(SpringSchedulerApplication.java:12) [classes/:na]
Root Cause
The custom thread pool is created in the spring boot application. Schedulers are invoked before the ThreadPoolTaskScheduler is initialized. Configured parameters must be initialized before the Schedulers are used.
How to Reproduce this issue
Create a custom ThreadPoolTaskScheduler class and run without initializing the thread pool will reproduce this issue
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
threadPoolTaskScheduler.setThreadNamePrefix("my-pool-");
taskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
}
Solution
The initialize() method in the ThreadPoolTaskScheduler must be invoked in your custom thread pool creation code as shown in the code below
package com.yawintutor;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.stereotype.Component;
@Component
public class SchedulerCustomThread implements SchedulingConfigurer {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private int POOL_SIZE = 10;
@Scheduled(fixedRate = 5000)
public void task() {
System.out.println(Thread.currentThread().getName() + " Scheduler (Fixed Rate = 5000) task with duration : " + sdf.format(new Date()));
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
threadPoolTaskScheduler.setThreadNamePrefix("my-pool-");
threadPoolTaskScheduler.initialize();
taskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
}
}