I used multiple threads to register multiple @Scheduled
tasks during the spring container initialization phase, NullPointerException occurred. Here is the stack information.
The @Scheduled
bean scope is SCOPE_PROTOTYPE
17:56:40.174 ERROR org.springframework.boot.SpringApplication - Application run failed
java.lang.NullPointerException: null
at org.springframework.scheduling.config.ScheduledTaskRegistrar.scheduleCronTask(ScheduledTaskRegistrar.java:414)
at org.springframework.scheduling.config.ScheduledTaskRegistrar.scheduleTasks(ScheduledTaskRegistrar.java:352)
at org.springframework.scheduling.config.ScheduledTaskRegistrar.afterPropertiesSet(ScheduledTaskRegistrar.java:332)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.finishRegistration(ScheduledAnnotationBeanPostProcessor.java:300)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:231)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:103)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:896)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:162)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:552)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204)
at loki.porsche.MacanApplicationKt.main(MacanApplication.kt:27)
Comment From: sbrannen
How exactly did you register the tasks?
And what version of Spring Framework are you using?
Comment From: jhoeller
It looks like this.taskScheduler
is suddenly null
after it initially passed the precending non-null check'? Or is the incoming task
instance null
by any chance?
In any case, we generally only support concurrent registration for very specific components, so there may be many subtle issues in such scenarios. That said, if this SchedulerTaskRegistrar
concern is trivial to fix, we're likely to address it nevertheless.
Comment From: li-daqian
To help you better understand this problem, I wrote a simple Demo. Spring Framework Version: 5.1.0.
@EnableScheduling
@SpringBootApplication
public class Example {
public static void main(String[] args) {
SpringApplication.run(Example.class, args);
}
}
@Component
class TaskInitializer {
private final ExecutorService executor;
public TaskInitializer(TaskConfig config) {
executor = Executors.newFixedThreadPool(4);
int i;
// Error, if no errors occur, try again
for (i = 0; i < 1000000; i++) {
executor.submit(() -> {
config.newTask();
});
}
// OK
// for (i = 0; i < 1000000; i++) {
// config.newTask();
// }
}
}
@Component
class Task {
@Scheduled(cron = "2 0 0/1 * * *")
void reload() {
// doSomeThing
}
}
@Configuration
class TaskConfig {
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
Task newTask() {
return new Task();
}
}
Comment From: snicoll
@marvinliz sorry for the delay in looking at your sample. Going forward, please share an actual sample rather than code in text as it makes sure we're running the same code. I am not able to replicate the NPE with a supported version of the framework so I am going to close this now.