spring-projects / spring-boot

Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
https://spring.io/projects/spring-boot
Apache License 2.0
75.22k stars 40.7k forks source link

Devtools restart does not work with reactor-netty #9146

Closed snicoll closed 6 years ago

snicoll commented 7 years ago

A WebFlux app using netty can lead to "ReactiveWebServerApplicationContext has been closed already"

2017-05-10 09:07:49.899 ERROR 14583 --- [ctor-http-nio-5] o.s.w.s.adapter.HttpWebHandlerAdapter    : Failed to handle request

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Cannot resolve reference to bean 'reactiveMongoTemplate' while setting bean property 'reactiveMongoOperations'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'spring.data.mongodb-org.springframework.boot.autoconfigure.mongo.MongoProperties': Initialization of bean failed; nested exception is java.lang.IllegalStateException: org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext@426027f3 has been closed already
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359) ~[spring-beans-5.0.0.RC1.jar:5.0.0.RC1]
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108) ~[spring-beans-5.0.0.RC1.jar:5.0.0.RC1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1604) ~[spring-beans-5.0.0.RC1.jar:5.0.0.RC1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1349) ~[spring-beans-5.0.0.RC1.jar:5.0.0.RC1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:574) ~[spring-beans-5.0.0.RC1.jar:5.0.0.RC1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:491) ~[spring-beans-5.0.0.RC1.jar:5.0.0.RC1]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) ~[spring-beans-5.0.0.RC1.jar:5.0.0.RC1]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-5.0.0.RC1.jar:5.0.0.RC1]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) ~[spring-beans-5.0.0.RC1.jar:5.0.0.RC1]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198) ~[spring-beans-5.0.0.RC1.jar:5.0.0.RC1]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:250) ~[spring-beans-5.0.0.RC1.jar:5.0.0.RC1]
bclozel commented 7 years ago

This behavior shows that after stopping and restarting a new server instance with the new Spring context, reactor-netty's HttpServer has still a reference to the previous handler, which holds itself a reference to the old Spring WebFlux infrastructure (beans, context and all).

I've opened reactor/reactor-netty#90 as our current use of the HttpServer API is wrong, or there might be a bug in reactor-netty.

wilkinsona commented 7 years ago

I can't reproduce this with the WebFlux and Reactive MongoDB starters. Have I missed something?

bclozel commented 7 years ago

Are you using Reactor Netty, or another server implementation instead (Tomcat, Undertow, Jetty?).

The other possible reason is that the changes you're making to your project aren't "incompatible" with the previous version which still runs. Declaring a WebFlux controller handler and changing its behavior (as I've done in the reactor netty issue I've created) should trigger the issue.

Note: technically, that BeanCreationException is not the issue to reproduce, but rather the application still using the context that has been closed already.

bclozel commented 7 years ago

Note: I've added a temporary workaround for this in 330aa70