|
From: Henning B. <hen...@gm...> - 2008-09-18 13:15:17
|
Hi,
I observed a deadlock in Jetty 6.1.0, actually twice, but
unfortunately I didn't manage to reproduce it today and didn't keep the
stack traces (but at least I saw them). Thought I can explain it
nevertheless. Btw. I think the relevant code did not change in later
6.1.x releases. Ok, here it is:
When using Jetty's org.mortbay.management.MBeanContainer, e.g. via a
jetty.xml like this one:
<Configure class="org.mortbay.jetty.Server">
<!-- ... -->
<!-- initialize the Jetty MBean container -->
<Get name="container">
<Call name="addEventListener">
<Arg>
<New class="org.mortbay.management.MBeanContainer">
<Arg>
<Ref id="MBeanServer" />
</Arg>
<Call name="start" />
</New>
</Arg>
</Call>
</Get>
<!-- .. -->
the MBean container gets registered with an
org.mortbay.component.Container. Now, in the MBeanContainer
implementation, at line 171, within the synchronized removeBean()
method, it calls the Container instances synchronized method update(...).
It seems that when starting a web app, while another webapp is stopping,
this can lead to a deadlock, as AbstractHandler calls
Container.removeBean (which is not synchronized, just as
Container.addBean) that calls MBeanContainer.removeBean (that is
synchronized) which in turn calls Container.update (which is
synchronized). So that thread locks MBeanContainer and tries to lock
Container.
Another thread may have entered the scenery via Container.update
(synchronized), for example via ContextHandler, that calls
Container.remove/addBean and consequently will try to lock
MBeanContainer by calling MBeanContainer.removeBean (or addBean) and
we're stuck, since that thread locks Container and waits to lock
MBeanContainer.
If the call sequence Container-->MBeanContainer can be guaranteed (not
sure that is true), then making Container.addBean and
Container.removeBean synchronized should fix that problem - I would guess.
For now, I will simply remove the MbeanContainer from my setup.
Thanks,
Henning
|