jsr343-experts@jms-spec.java.net

[jsr343-experts] Re: [jms-spec users] Re: Discussion point: deadlocks in MessageListener and ExceptionListener

From: Graham Wallis <graham_wallis_at_uk.ibm.com>
Date: Tue, 2 Aug 2011 16:45:34 +0100



Nigel

Answers inline below...

Nigel Deakin <nigel.deakin_at_oracle.com> wrote on 02/08/2011 15:05:14:

> From: Nigel Deakin <nigel.deakin_at_oracle.com>
> To: jsr343-experts_at_jms-spec.java.net
> Date: 02/08/2011 15:06
> Subject: [jms-spec users] [jsr343-experts] Re: Discussion point:
> deadlocks in MessageListener and ExceptionListener
>
> Graham,
>
> On 02/08/2011 12:13, Graham Wallis wrote:
> >
> > Nigel et al,
> >
> > I wanted to bring this up for discussion to see whether others
recognise
> > these problems and to see whether other people think they are worth
> > addressing.
> >
> > In the current JMS 1.1 specification, there are various inconsistencies
> > that, if interpreted literally, can lead to deadlocks. My belief is
that
> > most/all providers will have taken steps to circumvent the problems,
but it
> > would be desirable to clean up the spec.
> >
> > The first example is in asynchronous consume:
> >
> > If an implementation of javax.jms.MessageListener calls Connection.stop
()
> > the wording of the current spec can lead to a deadlock. From JMS 1.1
> > chapter 4.3.4: "If MessageListeners are running when stop is invoked,
stop
> > must wait until all of them have returned before it may return. While
these
> > MessageListeners are completing, they must have the full services of
the
> > connection available to them.” If the "full services" can reasonably be
> > interpreted to include calling the stop() method itself, the system
will
> > deadlock.
>
> Very good issue. I suppose the first question to ask is whether stop
> () may be called from onMessage(), irrespective of
> what is going on in other threads.
>
> As the spec is currently written, the call to stop() cannot return
> until all MessageListeners have returned, but if the
> call to stop() is itself being performed from a MessageListener then
> this will never happen.
>
> Do you a suggestion? I am tempted to say that a MessageListener
> should not call connection.stop(), or connection.close,
> or session.close(). What do others think?
>

I think that prohibiting MessageListener from calling the above methods
would be desirable, but I'm worried about introducing a compatibility
issue. For a situation where the MessageListener really does need to cause
connection to stop, it may be better to specify an onMessage with a
non-void return type or recommend some non-blocking operation on the
connection that sets a condition that the connection must check on
completion of onMessage(). Neither is attractive, but nor is the current
situation.

> >
> > The second example is in exception listeners:
> >
> > A Connection serializes execution of its ExceptionListener, and if the
> > ExceptionListener attempts to stop the Connection, this will result
in
> > deadlock.
> > It is probably worth clarifying what an ExceptionListener is permitted
to
> > do.
>
> Hmm. What does "a Connection serializes execution of its
> ExceptionListener" (in 4.3.8) mean, in your view? Given that a
> Connection isn't associated with a particular thread, it's not
> immediately obvious to me what is meant to be blocked
> until onException() returns.

I read that to mean that the Connection will invoke the ExceptionListener
on one thread at a time; but I guess this still permits other threads to be
performing work, because the connection would only need to synchronise the
invocation of ExceptionListener. But I think the serialisation of the calls
to ExceptionListener may not be the issue here - I think it arises because
a JMS provider can invoke the ExceptionListener whilst the provider is in a
receive for example; and if the ExceptionListener invokes connection.stop()
you get a similar deadlock to the MessageListener one above - i.e. the stop
won't return until all receive threads have returned; and one of them
cannot because it's waiting for the ExceptionListener to return.

>
> Nigel
>