[ 
https://issues.apache.org/jira/browse/CXF-8973?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17812269#comment-17812269
 ] 

Eric commented on CXF-8973:
---------------------------

Shall I provide a PullRequest?

> NettyHttpServerEngineFactory shuts down all netty instances when 
> SpringContext is shutdown
> ------------------------------------------------------------------------------------------
>
>                 Key: CXF-8973
>                 URL: https://issues.apache.org/jira/browse/CXF-8973
>             Project: CXF
>          Issue Type: Bug
>            Reporter: Eric
>            Priority: Major
>
> {color:#000000}NettyHttpServerEngineFactory{color} and 
> {color:#000000}{color:#000000}JettyHttpServerEngineFactory are very similar 
> in how they manage their ports and their lifecycle. There seems, however, to 
> be minor difference in the Netty...Factory which seems to be the potential 
> cause of bugs:
> {color}{color}
> {color:#000000}{color:#000000}{color:#000000}
> {color}{color}{color}
> {code:java}
> class JettyHTTPServerEngineFactory {
>  ...
>  JettyHTTPServerEngineFactory(Bus bus) {
>    setBus(bus);
>  }
>  void setBus(Bus bus) {
>     this.bus = bus;
>     if (bus != null) {
>         bus.setExtension(this, JettyHTTPServerEngineFactory.class);
>         lifeCycleManager = bus.getExtension(BusLifeCycleManager.class);
>         if (null != lifeCycleManager) {
>             lifeCycleManager.registerLifeCycleListener(new 
> JettyBusLifeCycleListener());
>         }
>     }
>   }
>   class JettyBusLifeCycleListener implements BusLifeCycleListener { ... }
>   ...
> {code}
> {color:#000000}{color:#000000}vs{color}{color}
>  
> {code:java}
> class NettyHttpServerEngineFactory implements BusLifeCycleListener { 
>   NettyHttpServerEngineFactory (Bus bus) {
>     setBus(bus);
>   }
>   void setBus(Bus bus) {
>     this.bus = bus;
>     if (bus != null) {
>         bus.setExtension(this, NettyHttpServerEngineFactory.class);
>         lifeCycleManager = bus.getExtension(BusLifeCycleManager.class);
>         if (null != lifeCycleManager) {
>             lifeCycleManager.registerLifeCycleListener(this);
>         }
>     }
>   }
>   ...
> {code}
> {color:#000000}{color:#000000}Both Variants seem to be very similar, however 
> there is a subtle difference when it comes to this class:{color}{color}
>  
> {code:java}
> class CXFBusLifeCycleManager implements BusLifeCycleManager {
>   void initComplete() {
>     if (bus != null){
>       bus.getExtension(ConfiguredBeanLocator.class)
>         .getBeansOfType(BusLifeCycleListener.class);
>     }
>     ...
>   } 
>   ...
> }{code}
> {color:#000000}{color:#000000}Because NettyHttpServerEngineFactory implements 
> BusLifeCycleListener, it can be found as an Extension in the 
> LifeCycleManager, which cause the Constructor with the Bus Parameter to be 
> call, which in turn automatically registers the Factory for automatic 
> shutdown when a spring context is closed.{color}{color}
>  
> {color:#000000}{color:#000000}This can have unexpected side-effects, when, 
> for example in tests, Spring Contexts are created and destroyed on demand and 
> combined with indendenpend server instances, like this:
> {color}{color}
> {code:java}
> class TestWithNetty {
>   @BeforeAll
>   static void setupServer() {
>     JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
>     sf.setResourceClasses(SomeWebResource.class);
>     sf.setAddress("http://localhost:9000";);
>     Server server = sf.create();
>   }
>   @RepeatedTest(2)
>   void runtTestWithSpringContext(@Autowired ApplicationContextRunner runner) {
>      runner.run(ctx -> // do something with spring context, calling 
> localhost:9000);
>   }
> }
> {code}
> {color:#000000}{color:#000000}This scenario, when called with a dependency on 
> this works:{color}{color}
> {code:java}
> org.apache.cxf:cxf-rt-transports-http-jetty {code}
> {color:#000000}{color:#000000}That is, since netty is never registered as a 
> outside of the beforeblock{color}{color}
>  
>  
> {color:#000000}{color:#000000}The same scenario with netty, however 
> fails:{color}{color}
> {code:java}
> org.apache.cxf:cxf-rt-transports-http-netty-server {code}
> {color:#000000}{color:#000000}That is the Case because after the first test, 
> the spring context is shutdown, which has the side effekt of destroying all 
> netty servers, even those which where never managed by spring at all, simply 
> because the constructor NettyHttpServerEngineFactory (Bus bus) was implicitly 
> called by .getBeansOfType(BusLifeCycleListener.class), which registered the 
> factory in the LifeCycle of the SpringBus{color}{color}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to