[cdi-dev] JMS 2.1: Proposal to allow any CDI managed bean in a Java EE application to listen for JMS messages

arjan tijms arjan.tijms at gmail.com
Mon Aug 24 19:18:36 EDT 2015


Hi,

On Mon, Aug 24, 2015 at 9:47 PM, Nigel Deakin <nigel.deakin at oracle.com> wrote:
> As I understand it, if you want to create a CDI managed bean (so that it is
> managed by CDI) then you have to inject it into some code somewhere.

This is not exclusively the case really;

There are generally 3 options:

1. Bean is injected
2. Bean is named (using @Named annotation or getName() of a Bean<T>
returns non null) and referenced by EL
3. Bean is programmatically created via BeanManager

In saw that the proposal essentially has an example of 3. already;
using the Instance injection. There are 2 variants on this where code
either uses the BeanManager directly or uses the "shortcut"
CDI.current().select(...);

Option 3. is often used when something needs a bean of a specific type
to do something. E.g. in JSF 2.3 a user would define a bean like this:

@FacesDataModel(forClass = MyCollection.class)
public class MyCollectionModel<E> extends DataModel<E> { ... }

And it just sits there (the user doesn't have to create it).

When a component needs this, it tries to obtain it programmatically,
via something like:

cdi.select(
    DataModel.class,
    new FacesDataModelAnnotationLiteral(MyCollection.class)
).get();

So the *expectation* may be that a user just defines a CDI based JMS
listener bean, and that the container will then find those beans when
it needs to deliver a message.

Of course this is not entirely trivial in the JMS listener case. The
JMS runtime can not easily ask CDI for all active instances of say the
request scope, and then ask for beans to be created in all those
scopes and then deliver the message to all of them.


> If I understand things correctly, if this is a normal CDI bean then this
> alone is not sufficient to cause an instance of the bean to be created.
>
> You also need to
> (1) inject it into some other bean
> (2) create that other bean and
> (3) call a method on the MyListenerBean to trigger lazy initialisation.

This is one way for sure, but one alternative worth mentioning is to
eagerly instantiatie the scoped bean whenever its scope starts. For
OmniFaces we have implemented a separate annotation for this for CDI
1.0, see http://showcase.omnifaces.org/cdi/Eager

For CDI 1.1, there's the @Initialized and @Destroyed annotations that
can be used to observe any scope where the implementing Context throws
events for these (which are all Java EE provided scopes as far as I
know). See https://rmannibucau.wordpress.com/2015/03/10/cdi-and-startup
and https://issues.jboss.org/browse/CDI-86

One CDI technicality is that if the listener method is called via the
proxy, I think it will resolve to the current scope that thread is in.
So this may mean the JMS endpoint that calls the JMS listener bean can
only call the actual bean's method, not the proxied one. I'm sure the
CDI experts here will have more knowledge about this.

Hope this helps.

Kind regards,
Arjan Tijms










>
> I'm trying to avoid getting ahead of myself here. My current proposals
> simply apply to normal CDI managed beans created in the normal way (via
> injection and lazy initialisation). But I could certainly see a benefit in
> extending this to allow JMS listener beans to be created in other ways. In
> particular:
>
> (a) Creating the bean instance as soon as the bean into which it is injected
> enters a new scope rather than waiting for the application to call a method
> on it (so-called eager initialisation). That sounds relatively
> straightforward to me; this could either be a new standard CDI feature
> available to all normal-scoped beans, or something specific to beans
> annotated with @JMSListener.
>
> (b) Creating the bean instance without the need to inject it anywhere.  As
> you suggest, in the case of ApplicationScoped beans this would make JMS
> listener beans more like MDBs. But it might be equally useful to support
> this for other normal scopes. For example, could we annotate a
> @RequestScoped bean so that every time a new request scope started, an
> instance of the bean for that scope was automatically created?
>
> Or if we manage to get the @Startup annotation to Commons Annotation :
>
> @Startup
> public class MyListenerBean{
>
>
> @JMSListener(lookup="java:global/java:global/Trades",type=JMSListener.Type.TOPIC
> )
>    public void deliver(Message message) {
>      ...
>    }
> }
>
>
> That looks as if it's tied to ApplicationScoped. I'd rather look for
> something more general.
>
> Thanks for your comments so far. You're raising issues I have been thinking
> about for some time.
>
> Nigel
>
>
>
>
> Just thinking here
>
> Antonio
>
> On Mon, Aug 24, 2015 at 6:30 PM, Nigel Deakin <nigel.deakin at oracle.com>
> wrote:
>>
>> Over in the JMS 2.1 expert group I've just published some proposals to
>> allow any CDI managed bean in a Java EE
>> application to listen for JMS messages. This would be implemented as a
>> standard CDI portable extension and would become
>> a mandatory part of a full Java EE 8 application server.
>>
>> I would welcome any comments from the CDI spec experts here. If you're
>> interested in helping, please take a look at
>> https://java.net/projects/jms-spec/pages/CDIBeansAsJMSListeners
>> and send comments or questions to me or to the public
>> users at jms-spec.java.net alias.
>>
>> Thanks,
>>
>> Nigel
>> JMS 2.1 specification lead
>> _______________________________________________
>> cdi-dev mailing list
>> cdi-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/cdi-dev
>>
>> Note that for all code provided on this list, the provider licenses the
>> code under the Apache License, Version 2
>> (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas
>> provided on this list, the provider waives all patent and other intellectual
>> property rights inherent in such information.
>
>
>
>
> --
> Antonio Goncalves
> Software architect, Java Champion and Pluralsight author
>
> Web site | Twitter | LinkedIn | Pluralsight | Paris JUG | Devoxx France
>
>
>
> _______________________________________________
> cdi-dev mailing list
> cdi-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> Note that for all code provided on this list, the provider licenses the code
> under the Apache License, Version 2
> (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas
> provided on this list, the provider waives all patent and other intellectual
> property rights inherent in such information.


More information about the cdi-dev mailing list