[
https://issues.apache.org/jira/browse/KARAF-7773?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17777582#comment-17777582
]
Amichai Rothman commented on KARAF-7773:
----------------------------------------
I'm still not sure what the full internal flow is, but when debugging, I see
the wab context has a PaxWebServletContextHandler with the listeners (in
rankedListeners, later added to _servletContextListeners and invoked). When
undeployed, PWSCH.doStop removes the two other listeners (Registering something
and jetty websocket something), but leaves the wab custom listener (it survives
the removal with the getRanklessPosition() >= 0 predicate).
Then there is a JettyServerWrapper.visitTransactionStateChange DISSOCIATE call,
which gets the same PWSCH and calls ensureServletContextStarted with it. That
in turn takes the default '/' as the highestRankedContext, and seems to
repurpose the same pwsch instance for this new context, e.g. calling things
like clearDynamicRegistrations (which does not remove the listener) and such,
but the listener, wab display name and maybe other fields survive these
modifications. It then calls sch.start(), which starts this mixed-up pwsch
which has some fields from the new context and some from the old, it adds the
rankedListeners again (still containing the old listener), invokes the old
listener on the new context, and the issue is recreated.
It seems the bug stems from reusing the same PWSCH instance for both the old
wab context and new default context, where some leftovers fields leak through.
> WAB ServletContextListener.contextInitialized invoked multiple times during
> re-deploy (and with wrong context)
> --------------------------------------------------------------------------------------------------------------
>
> Key: KARAF-7773
> URL: https://issues.apache.org/jira/browse/KARAF-7773
> Project: Karaf
> Issue Type: Bug
> Components: karaf
> Affects Versions: 4.4.3
> Reporter: Amichai Rothman
> Assignee: Grzegorz Grzybek
> Priority: Major
> Attachments: paxweb.log, paxweb.trace.log, paxweb.trace2.log
>
>
> When touching a WAB bundle with a context listener as described belower, the
> undeploy/deploy cycle, instead of just invoking destroy on the old context
> and initialize on the new one, seems to destroy the old one, re-initialize
> the old one (with the wrong "whiteboard extender" context), destroy it again,
> initialize the new one (with correct context), and initialize the old one
> once more (but without the filter init).
> I'll describe my full scenario, even though it's possible the issue can be
> reproduced with a simpler setup:
> I have an application consisting of multiple bundles in the karaf deploy
> folder. One of them is a WAB. It's web.xml only contains display-name and
> listener-class with a ServletContextListener. The listener contextInitialized
> implementation instantiates a custom Filter, whose class is imported from a
> different app bundle:
> {code:java}
> Filter filter = new MyFilter();
> context.addFilter("MyFilter", filter)
> .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST,
> DispatcherType.FORWARD), true, "/*");
> {code}
> The filter's init method is invoked successfully and all is good.
> Then, I update/touch the WAB bundle in the deploy folder.
> This causes a thread named "paxweb-config-3-thread-1 (undeploy /)" to call
> the listener's contextDestroyed method as expected, but then it also
> immediately calls the contextInitialized method again (still from the
> undeploy thread, and still the same old listener instance), this time with
> the servlet context of the pax-web-extender-whiteboard rather than the WAB
> bundle. It creates another filter instance, whose init method gets invoked
> with the pax-web-extender-whiteboard context as well (my init implementation
> throws an exception at this point when the context is wrong, resources aren't
> found etc.).
> Then a thread named "paxweb-config-3-thread-1 (deploy /)" (notice undeploy
> changed to deploy) calls contextDestroyed, still with the extender context.
> Finally, a new listener instance is craeted, contextInitialized is invoked
> again, this time with the correct WAB context, followed by the filter's init
> method. In addition, the old listener instance (which should be dead by now)
> contextInitialized also gets invoked again, but not followed by the filter
> init (maybe because it previously threw an exception on it? just guessing).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)