[
https://issues.apache.org/jira/browse/CXF-8973?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17812317#comment-17812317
]
Andriy Redko commented on CXF-8973:
-----------------------------------
[~cheesemaster] AFAIK this is the intended (and desired) behavior when Apache
CXF is used with Spring Framework: when context shuts down, the registered
beans are destroyed. In this regards, the test does not look right to me - the
JAXRSServerFactoryBean should be a part of the application context (or part of
the parent application context), or alternately use the non-Spring aware Bus
instance in order to not interfere with the test at all.
> 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)