spring-cloud-netflix: Eureka shutdown appear BeanCreationNotAllowedException
I create two service use cloud. First, run EurekaServerApp.java. Second, run WorkApp.java. Third, run UserApp.java. Finally, run UserServiceTest.java to test the testAddUser() Interface. The data success insert to db, but shutdown I received this ugly exception:
the demo url is https://github.com/smallGit2017/test-0317.git
org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'eurekaAutoServiceRegistration': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:216) [spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081) [spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.event.ApplicationListenerMethodAdapter.getTargetBean(ApplicationListenerMethodAdapter.java:280) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:250) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:174) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:137) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383) [spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:389) [spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:337) [spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:994) [spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:961) [spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.cloud.context.named.NamedContextFactory.destroy(NamedContextFactory.java:76) [spring-cloud-context-1.2.0.RELEASE.jar:1.2.0.RELEASE] at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:272) [spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578) [spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554) [spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:961) [spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523) [spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:968) [spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1033) [spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1009) [spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext$2.run(AbstractApplicationContext.java:928) [spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 49 (10 by maintainers)
Commits related to this issue
- added feign bean post processor to accoring to https://github.com/spring-cloud/spring-cloud-netflix/issues/1952#issuecomment-355487342 — committed to ETspielberg/stockanalyzer by ETspielberg 5 years ago
With Spring Cloud Edgware, the previous workaround doesn’t work anymore. The right workaround should be:
I’m using Spring Boot 1.5.6 with Spring Cloud Dalston SR2. It’s easy to reproduce this issue with at least one FeignClient interface and one Component auto-wire that interface.
The following exception will be shown on shutdown:
The root cause is when closing ApplicationContext, it will destroy all singleton bean,
eurekaAutoServiceRegistrationis destroyed first, thenfeignContext. When destroyfeignContext, it will close the ApplicationContext associated with each FeignClient. SinceeurekaAutoServiceRegistrationlisten on ContextClosedEvent, those events will be sent to that bean. Unfortunately because it has been destroyed, so we got the above exception (try to create bean in destruction).I don’t have workaround for that. 😦
Finchley.M9版本 我报这个错 是因为缺少spring-boot-starter-web依赖,添加之后就不报错了
Found a workaround. Also added more details about the root cause.
When
ApplicationContextshutdown, it will destroy all disposable beans (and beans depend on them). In this case:FeignContextimplementsDisposableBeaninterfaceInetUtilsimplementsAutoCloseableinterfaceEurekaServiceRegistryhas a public close method So they are all considered as disposable beans. SinceEurekaAutoServiceRegistrationdepends onInetUtilsandEurekaServiceRegistrybeans, so if either bean is destroyed,EurekaAutoServiceRegistrationwill be destroyed.Destroy follow First In, Last Out order. Usually application code will not depends on InetUtils or EurekaServiceRegistry, but they depends on FeignClient interfaces. That means
FeignContextusually get instituted beforeInetUtilsandEurekaServiceRegistry, so it will be destroyed after them:InetUtilsorEurekaServiceRegistryto be destroyed.EurekaAutoServiceRegistrationfirst.InetUtilsandEurekaServiceRegistry.FeignContextwhich will shutdown allApplicationContextassociated with FeignClients.EurekaAutoServiceRegistrationlisten onContextClosedEventbut it has been destroyed. ApplicationContext will try to create it again, got exception.Workaround
Make sure
InetUtilsandEurekaServiceRegistryare instituted beforeFeignContext. So the sequence become:FeignContextwhich will shutdown allApplicationContextassociated with FeignClients.EurekaAutoServiceRegistrationlisten onContextClosedEventand processed those events.InetUtilsorEurekaServiceRegistryto be destroyed.EurekaAutoServiceRegistrationfirst.InetUtilsandEurekaServiceRegistry.There are several ways to do that. The recommended solution is implement a BeanFactoryPostProcessor:
This workaround will eliminate the exception, but the problem is still there in
EurekaAutoServiceRegistration.onApplicationEventandFeignContext.destroy.@spencergibb I tried the latest snapshot version, still see the same stack trace without my workaround.
I think fix within
onApplicationEventmethod will not work. The problem isEurekaAutoServiceRegistrationbean had been destroyed, then it receivedContextClosedEventfor theApplicationContextassociated with FeignClients. BeanFactory try to create that bean again and triggered that exception.Here are the whole steps:
ApplicationContextshutdownEurekaAutoServiceRegistration.onApplicationEventget called and deregister Eureka instance.EurekaAutoServiceRegistrationbean is destroyed. (BecauseInetUtilsandEurekaServiceRegistryare destroyed)FeignContext.FeignContextwill destroyApplicationContextassociated with each FeignClient.ApplicationContexttry to notifyEurekaAutoServiceRegistration.onApplicationEvent, because ofEventListenerannotation. But that bean is destroyed, so it try to re-create it.我在junit里面加了@SpringBootTest(SpringBootTest.WebEnvironment.RANDOM_PORT)就可以调用了
@zhujunjie115197 It’s work to me, just add follow dependency in maven .
@spencergibb This problem is still reproducible in Spring Cloud Edgware.SR1. Here is the minimal code to reproduce it:
pom.xml
Application.java
The stack trace is:
i am also facing the same issyes, 太恶心了
感谢 提示,我的是 Finchley.SR1 添加 spring-boot-starter-web依赖 后问题得到解决
this problem persists. it is annoying enough in a web application, imagine how much more annoying it is in a console application which runs every hour and pollutes the log with this stack trace every time it shuts down.
感谢~~ Edgware.SR1 版本 用这个可以解决 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
See https://github.com/spring-cloud/spring-cloud-netflix/issues/2099 for potential hints (same message and an easy way to reproduce)
Since I have a workaround, I didn’t pay much attention to this issue anymore.
Today I found this issue has been fixed in Greenwich.M1 by https://github.com/spring-cloud/spring-cloud-netflix/commit/12583fd0c25638f95c14973d921ca28cdcd17df5.
Basically
@EventListeneris not handled properly on shutdown, butApplicationListenerinterface is.@spencergibb I think you can close this issue.