I have followed very simple examples online to set up a cron job in Spring yet I keep getting this error in my Tomcat startup log each and every time:
2015-05
I agree you can ignore it but just changing the severity will not fix it. I had the same issue but I am using xml instead of annotations, and in my case it happened because I did not included the executor on my bean definition. So adding this fixed it:
<task:annotation-driven executor="myExecutor"
scheduler="myScheduler" />
<task:executor id="myExecutor" pool-size="5" />
<task:scheduler id="myScheduler" pool-size="10" />
I hope it helps.
Regards.
For solving this problem just create task scheduler bean in config.
@Bean
public TaskScheduler taskScheduler() {
return new ConcurrentTaskScheduler();
}
EDIT: the best answer is here and it involves creating an Executor:
@Configuration
@EnableAsync
public class AppContext extends WebMvcConfigurationSupport {
@Bean
public Executor taskExecutor() {
return new SimpleAsyncTaskExecutor();
}
}
PREVIOUS (still valid though):
The NoSuchBeanDefinitionException is logged with a DEBUG severity and can be safely ignored. If you look at the source code for ScheduledAnnotationBeanPostProcessor, you see that it first tries to get a TaskScheduler, then a ScheduledExecutorService, then it keeps going on "falling back to default scheduler":
if (this.registrar.hasTasks() && this.registrar.getScheduler() == null) {
Assert.state(this.beanFactory != null, "BeanFactory must be set to find scheduler by type");
try {
// Search for TaskScheduler bean...
this.registrar.setScheduler(this.beanFactory.getBean(TaskScheduler.class));
}
catch (NoUniqueBeanDefinitionException ex) {
throw new IllegalStateException("More than one TaskScheduler exists within the context. " +
"Remove all but one of the beans; or implement the SchedulingConfigurer interface and call " +
"ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback.", ex);
}
catch (NoSuchBeanDefinitionException ex) {
logger.debug("Could not find default TaskScheduler bean", ex);
// Search for ScheduledExecutorService bean next...
try {
this.registrar.setScheduler(this.beanFactory.getBean(ScheduledExecutorService.class));
}
catch (NoUniqueBeanDefinitionException ex2) {
throw new IllegalStateException("More than one ScheduledExecutorService exists within the context. " +
"Remove all but one of the beans; or implement the SchedulingConfigurer interface and call " +
"ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback.", ex);
}
catch (NoSuchBeanDefinitionException ex2) {
logger.debug("Could not find default ScheduledExecutorService bean", ex);
// Giving up -> falling back to default scheduler within the registrar...
}
}
}
You can remove the exception by setting at least a INFO severity on org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor, like
<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>
when using logback.
The cron expression has six fields:
second (0-59), minute (0-59), hour (0-23, 0 = midnight), day (1-31), month (1-12), weekday (1-7, 1 = Sunday)
The syntax can be found in the quartz docs. I'm not sure about the "?" character because, although the page says
The '?' character is allowed for the day-of-month and day-of-week fields. It is used to specify “no specific value”. This is useful when you need to specify something in one of the two fields, but not the other.
the examples on that page actually use ? even when the other field is *. IMHO all should work with just *, so in order to execute every midnight, the expression should be
0 0 0 * * *
With Spring Boot 2.0.5, I keep getting:
2018-11-20 11:35:48.046 INFO 64418 --- [ restartedMain] s.a.ScheduledAnnotationBeanPostProcessor :
No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
The only way to get rid of it seems to be using SchedulingConfigurer
interface in your @Configuration
class like this:
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
private final int POOL_SIZE = 10;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");
threadPoolTaskScheduler.initialize();
scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
}
}
Note: This was taken from https://www.callicoder.com/spring-boot-task-scheduling-with-scheduled-annotation/
according to exception Info Could not find default TaskScheduler bean
, the config should define TaskScheduler
rather than "Executor"
@Configuration
public class AppContext extends WebMvcConfigurationSupport {
@Bean
public TaskScheduler taskScheduler() {
return new ConcurrentTaskScheduler();
}
// Of course , you can define the Executor too
@Bean
public Executor taskExecutor() {
return new SimpleAsyncTaskExecutor();
}
}