users@jms-spec.java.net

[jms-spec users] JMS_SPEC-134: Declarative Annotation Based JMS Listeners

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Mon, 24 Aug 2015 15:51:32 +0100

The Java Specification Request (JSR) for JMS 2.1 (https://www.jcp.org/en/jsr/detail?id=368) proposes a number of new
features. The first of these was described as follows:

"The ease-of-use improvements started in JMS 2.0 will be completed in JMS 2.1 by simplifying and extending the API
required to receive messages asynchronously, both in a Java SE environment and in Java EE.

"For Java EE applications an easier-to-use and more general alternative to JMS message-driven beans will be defined. The
details of this feature will be determined by the expert group. The intention is to provide a simpler and more compact
syntax than JMS MDBs, which will avoid the restrictions of the MDB lifecycle, and the JMS MessageListener interface, by
allowing any CDI managed bean to be used to listen for messages. If possible, this feature will be aligned with CDI
event observers."

As you know, I proposed some improvements to JMS MDBs a couple of months ago. These are described at
https://java.net/projects/jms-spec/pages/JMSListener2
and I'd still welcome comments.

Those proposals deliver a "simpler and more compact syntax" but they don't "avoid the restrictions of the MDB lifecycle"
or allow "any CDI managed bean to be used to listen for messages". I'd therefore like to start a discussion how we do that.

To start things off, I've written down some proposals which you can read at
https://java.net/projects/jms-spec/pages/CDIBeansAsJMSListeners

Here's a summary:

-------------------------------------------------------------------------------
It is now proposed we allow any CDI managed bean in a Java EE application to listen for JMS messages. The bean will
start listening for messages as soon as a bean instance is created, and it will continue to listen for messages until it
is destroyed. All that will be necessary is to define a suitable callback method on the bean and add method annotations
in the same way as is proposed for JMS MDBs. Here's an example of such a bean:

  @Dependent
  public class MyCDIBean21 {

    @JMSListener(lookup="java:global/java:global/Trades",type=JMSListener.Type.TOPIC )
    @JMSConnectionFactory("java:global/MyCF")
    @MessageSelector("ticker='ORCL'")
    public void processNewsItem(String newsItem) {
      ...
    }
  }

As can be seen, this looks very similar to the example of a JMS 2.1 MDB. This is deliberate: all the new annotations
that can be used on a callback method of a JMS MDB (@JMSListener etc) can also be used on a CDI managed bean. (Note also
that these annotations are still being designed: comments are invited.)

However note that this object is not a MDB. It does not have the MessageDriven annotation. Instead it is a CDI managed
bean which can have any CDI scope and can be injected into Java EE code just like any other CDI managed bean. When a CDI
bean is injected, the lifecycle of the bean instance is managed by the CDI container. When the bean instance is created,
if it is annotated with JMSListener then it will start listening for messages, and when the bean instance is destroyed
(such as when its scope ends) it will stop listening for messages.
-------------------------------------------------------------------------------

Please let me know what you think or if you have any questions. Do you think this would be a useful feature? How could
we improve it?

Nigel