Hello,
after upgrade from 3.2.3 to 3.3.0 without any changes we have issue with websocket config.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'performanceMonitoringService' defined in file [/backbone/modules/base/spring-service/build/classes/java/main/com/eurofunk/eocs/monitoring/PerformanceMonitoringService.class]: Unsatisfied dependency expressed through constructor parameter 2: Error creating bean with name 'customStompRelayMessageBrokerConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0: Error creating bean with name 'org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration$WebSocketMessageConverterConfiguration': Unsatisfied dependency expressed through constructor parameter 1: Error creating bean with name 'messageBrokerTaskScheduler': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:795)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1357)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1194)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:962)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352)
at myapp.core.deployment.EocsApplication.run(EocsApplication.java:55)
at myapp.core.deployment.EocsApplication.run(EocsApplication.java:88)
at myapp.Application.main(Application.java:157)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91)
at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53)
at org.springframework.boot.loader.launch.PropertiesLauncher.main(PropertiesLauncher.java:574)
at myapp.BootstrapApplication.main(BootstrapApplication.java:68)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91)
at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53)
at org.springframework.boot.loader.launch.PropertiesLauncher.main(PropertiesLauncher.java:574)
the PerformanceMonitoringService has constructor like this
@Autowired(required = false)
public PerformanceMonitoringService(
@Nullable final ServletWebServerApplicationContext servletWebServerApplicationContext,
@Nullable @Qualifier("redisConnectionPools") final Map<
Class,
GenericObjectPool
> redisConnectionPools,
final List<ThreadPoolTaskScheduler> taskSchedulers,
final List<ThreadPoolTaskExecutor> taskExecutors
) { ...
and we are overriding the DelegatingWebSocketMessageBrokerConfiguration with
@Override
@Bean(name = { "messageBrokerTaskScheduler", "messageBrokerSockJsTaskScheduler" })
public ThreadPoolTaskScheduler messageBrokerTaskScheduler() {
final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setThreadNamePrefix("MessageBrokerPool-");
scheduler.setPoolSize(threadPoolSize);
scheduler.setRemoveOnCancelPolicy(true);
return scheduler;
}
when I remove that method application starts...however it's weird that this started to happen without any other change. I've also seen this issue which seems to be related however I don't use such method to set task scheduler.
Comment From: wilkinsona
Thanks for the report but it's not clear why you believe this to be a Spring Boot bug, particularly when you've referenced a Spring Framework issue as being related. If you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.
Comment From: bilak
@wilkinsona sorry didn't realised that it's framework's issue. I'm attaching the project which simulates the circular dependency. websocket-issue.zip
Comment From: wilkinsona
The cycle is happening because you're sub-classing DelegatingWebSocketMessageBrokerConfiguration and, in the same @Configuration class, you're defining a bean that a WebSocketMessageBrokerConfigurer consumes. As the javadoc of DelegatingWebSocketMessageBrokerConfiguration suggests, this is atypical and you should use @EnableWebSocketMessageBroker instead. If you need to sub-class DelegatingWebSocketMessageBrokerConfiguration, you shouldn't define additional beans in the same class. As you have seen here, it's a brittle arrangement that will break as soon as you define a bean that's consumed by a WebSocketMessageBrokerConfigurer as is now the case due to https://github.com/spring-projects/spring-boot/pull/39611.