users@jms-spec.java.net

[jms-spec users] Re: JMS_SPEC-116: Take advantage of EJB 3.2's RA improvement for MDBs

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Mon, 7 Sep 2015 16:01:56 +0100

(Just to avoid any confusion, this email thread refers to my proposals to improve JMS MDBs. I published the latest
version of these four weeks ago at four weeks ago at https://java.net/projects/jms-spec/pages/JMSListener2.

These proposals didn't receive a huge response but what comments were received seemed positive. However I know there are
quite a few details we need to get right. I am now going to work through these details in turn. To make it easy for
people to make comments so I'll do this by email initially and then follow it up by publishing a third version of the
proposals on the Wiki.

Here's the first issue I'd like to discuss: this proposes the addition of an extra annotation for JMS MDBs:
*JMSListenerProperty *

I think we need to define an additional annotation to allow proprietary activation properties to be specified on the
callback method. Many application servers (and resource adapters) use these to offer additional non-standard features.
Examples of such properties are the Glassfish-specific activation properties reconnectAttempts and reconnectInterval,
though just about every other application server or resource adapter defines its own set of proprietary activation
properties.

Without such an annotation, applications would have to continue defining these properties in the same way as now,
thereby forcing applications to mix the new JMS-specific method annotations on the callback method with the old generic
class annotations:

@MessageDriven(activationConfig = {
   @ActivationConfigProperty(propertyName = "foo1", propertyValue = "bar1"),
   @ActivationConfigProperty(propertyName = "foo2", propertyValue = "bar2")
})
public class MyMessageBean implements JMSMessageDrivenBean {

   @JMSListener(lookup="java:global/Trades", type=JMSListener.Type.QUEUE)
     public void processTrade(TextMessage tradeMessage){
     ...
   }

}

I'm therefore suggesting that a new method annotation @JMSListenerProperty be defined which the application can use to
specify arbitrary activation properties. This annotation would be a "repeatable annotation" so that it could be used
multiple times to set multiple properties.

@MessageDriven
public class MyMessageBean implements JMSMessageDrivenBean {

   @JMSListenerProperty(name="foo1", value="bar2")
   @JMSListenerProperty(name="foo2", value="bar2")
   @JMSListener>(lookup="java:global/Trades", type=JMSListener.Type.QUEUE)
   public void processTrade(TextMessage tradeMessage){
     ...
   }

}

Since this annotation is a repeatable annotation, a composite annotation needs to be defined as well which the compiler
will insert automatically when it encounters a repeatable annotation. This will be called @JMSListenerProperties.

Here are the javadocs for javax.jms.JMSListenerProperty
https://jms-spec.java.net/2.1-SNAPSHOT/apidocs/javax/jms/JMSListenerProperty.html

Here are the javadocs for javax.jms.JMSListenerProperties
https://jms-spec.java.net/2.1-SNAPSHOT/apidocs/javax/jms/JMSListenerProperties.html

Since this gives us yet another way to define activation properties we need to define some override rules. Here's a
suggestion:

  * A property set using the existing activation property annotations or XML elements will override any value set using
    the @JMSListenerProperty annotation. This allows values to be overridden (for the MDB as a whole) by defining
    activation properties in the deployment descriptor.

  * If @JMSListenerProperty is used to specify one of the JMS standard activation properties then this will override any
    value set using the corresponding new JMS-specific annotation. This order is chosen to be consistent with the
    previous rule.

Any comments? Have I missed anything?

Nigel