[ 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)