On 26/08/2015 12:10, John D. Ament wrote:
On Wed, Aug 26, 2015 at 6:53 AM Nigel Deakin <nigel.deakin(a)oracle.com
<mailto:nigel.deakin@oracle.com>> wrote:
On 26/08/2015 10:51, arjan tijms wrote:
> On Wed, Aug 26, 2015 at 11:09 AM, Romain Manni-Bucau
> <rmannibucau(a)gmail.com <mailto:rmannibucau@gmail.com>> wrote:
>> Agree for provided scope but JMS + short time scopes will not match well
in
>> practise so i would worry more about not "default" scopes which
can miss
>> these events.
>
> Short lived scopes like @RequestScoped may not be the best match indeed.
>
> Additionally, @RequestScoped is kinda assumed to be an
"@ThreadScoped"
> thing, e.g. there's the expectation that only the current thread will
> access it. If the JMS provider will asynchronously call a method on
> the bean instance from another thread, then this breaks this
> assumption.
That's an interesting point. Is there anything in the CDI spec which would forbid
the use of a @RequestScoped JMS
listener bean from another thread?
The CDI spec still mandates that a request scope is started for delivery to MDBs. See
http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#request_context
The JMS provider would be responsible for retrieving a contextual reference to the bean
and then invoking the method.
The container should still be responsible for starting the request context (If I read
this correctly).
In the case of a "JMS listener bean" with @RequestScoped (or any scope, really)
then the JMS consumer (the thread which
receives a message from the JMS server and invokes the listener) is associated with the
actual bean instance. We should
think of it as an extension to that instance. The bean instance would be created when the
request (e.g. the HTTP
request) started, and will be destroyed when the request ends. Likewise the JMS consumer
is created when the request
starts and will be destroyed when the request ends. The consumer thread that is calling
the listener doesn't "retrieve a
contextual reference to the bean" since it is already associated with a specific
instance.
However once you're inside the callback method then this request scope (which relates
to a different thread) is not
available. As John suggests, we should probably define that a request scope is started
when the callback method is
invoked, and ended when the callback method returns. The listener method itself could
inject @RequestScoped objects
(including JMSContexts, which are request-scoped if there were no transaction), where the
request scope used is the one
associated with this particular callback.
Likewise, we could say that a @TransactionScoped bean also applies
here, since a JTA transaction should have been
started by the RA.
If the listener bean were @TransactionScoped then the JTA transaction would (by
definition) have been started before the
bean was created, and before the consumer was created. That would be separate from any
transaction started by the
resource adapter (which would be in a different thread).
Once again, the bean instance being used would be the one associated with the consumer,
and which lives for as long as
the first (application's) transaction.
However the callback method would be called in the context of the second transaction
(since that it's in the same thread
as that transaction). The listener method itself could inject @TransactionScoped objects
(including JMSContexts), where
the transaction used would be the one started and ended by the JMS provider/RA.
Nigel