-
Notifications
You must be signed in to change notification settings - Fork 41.6k
Description
I want to use spring-boot-starter-quartz and spring-boot-starter-websocket simultaneously,but it fails to satisfy my needs, and when I try to use them,some errors as follow appeared.
2020-12-08 18:50:09.535 [main] ERROR org.springframework.boot.SpringApplication [line:837] - Application run failed
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'defaultSockJsTaskScheduler' is expected to be of type 'org.springframework.scheduling.TaskScheduler' but was actually of type 'org.springframework.beans.factory.support.NullBean'
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:399)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:227)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1175)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1142)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.resolveSchedulerBean(ScheduledAnnotationBeanPostProcessor.java:327)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.finishRegistration(ScheduledAnnotationBeanPostProcessor.java:256)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:233)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:105)
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:404)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:898)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)I have figured out what caused these errors. It is because that there is a logical conflict on the instantiation of Taskscheuler after the procedure of use spring-boot-starter-quartz and spring-boot-starter-websocket simultaneously. spring-wesocket created a NullBean as instantiation of Taskscheduler. when the quartz is applied,the errors would emerge that is:
In org.springframework.web.socket.config.annotation.WebSocketConfigurationSupport#defaultSockJsTaskScheduler
org.springframework.web.socket.config.annotation.WebSocketConfigurationSupport#defaultSockJsTaskScheduler
@Bean
@Nullable
public TaskScheduler defaultSockJsTaskScheduler() {
if (initHandlerRegistry().requiresTaskScheduler()) {
ThreadPoolTaskScheduler threadPoolScheduler = new ThreadPoolTaskScheduler();
threadPoolScheduler.setThreadNamePrefix("SockJS-");
threadPoolScheduler.setPoolSize(Runtime.getRuntime().availableProcessors());
threadPoolScheduler.setRemoveOnCancelPolicy(true);
this.scheduler = threadPoolScheduler;
}
return this.scheduler;
}If this condition is not satisfied, it's going to create an instance(NullBean(org.springframework.beans.factory.support.NullBean)) of TaskScheduler here.
So we're going to rely on spring-boot-starter-quartz:
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration#taskScheduler
@Bean
@ConditionalOnBean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
@ConditionalOnMissingBean({ SchedulingConfigurer.class, TaskScheduler.class, ScheduledExecutorService.class })
public ThreadPoolTaskScheduler taskScheduler(TaskSchedulerBuilder builder) {
return builder.build();
}But due to the existence of the Nullbean the above method is impracticable, neither for the creation of a new workable Taskscheduler, but this problem can be tackled in this way:
@Bean
public ThreadPoolTaskScheduler taskScheduler(TaskSchedulerBuilder builder) {
return builder.build();
}Or implement WebSocketConfigurer to solve it.
Although we can use the above ways to settle the errors, but they are only temporary .In my opinion,the root cause for the problem is the bug of spring-websocket and so that cause the wrong existence of Nullbean
I think we can use these ways to deal with:
- Change logical order of the two procedures, that is to put the spring-boot-starter-quartz before the instantiation
- In spring-websocket, conditionally include TaskScheduler
- Always create a TaskScheduler Bean without if{}
- In spring-websocket, org.springframework.web.socket.config.annotation.WebSocketConfigurationSupport#defaultSockJsTaskScheduler no longer as a Spring Bean
The above mentioned are my immature thoughts ,may be you can solve the errors in a better way,thanks for your attention