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 18:21:47 +0100

Nigel


Nigel Deakin <nigel.deakin_at_oracle.com> wrote on 02/08/2011 17:52:49:

> From: Nigel Deakin <nigel.deakin_at_oracle.com>
> To: jsr343-experts_at_jms-spec.java.net
> Date: 02/08/2011 17:53
> Subject: [jsr343-experts] Re: [jms-spec users] Re: Discussion point:
> deadlocks in MessageListener and ExceptionListener
>
> Graham,
>
> On 02/08/2011 16:45, Graham Wallis wrote:
> >
> > 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.
> >
>
> Let's see what the others think.
>
> >>>
> >>> 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.
>
> Perhaps it means that if you register the same ExceptionListener
> instance with multiple connections, and several
> connections fail at the same tine (which is quite likely), only one
> connection will invoke onException at a time.
>
> > 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.
>
> If a connection detects a problem and calls the ExceptionListener, I
> don't see why this should cause a call to receive()
> in some other thread to block. Can you clarify why you think this isthe
case?
>

I was thinking that during receive() the thread called ExceptionListener,
and ExceptionListener tried to stop the connection, that would be similar
to the MessageListener case.

> If there were a problem with the connection, then receive() could
> throw a (different) exception anyway.

Agreed - but we have seen providers invoking our ExceptionListener -
although I can't recall whether it was from receive() - and causing the
deadlock described.

>
> Nigel
>
> >
> >>
> >> Nigel
> >>