users@jms-spec.java.net

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

From: Rüdiger zu Dohna <ruediger.dohna_at_1und1.de>
Date: Mon, 4 May 2015 07:45:53 +0000

On 01.05.2015, at 17:52, Nigel Deakin <nigel.deakin_at_oracle.com> wrote:
> 0. Marker interface
> -------------------
>
> John suggests that the class would need to implement a marker interface (e.g. JMSMessageEndpoint), to satisfy a requirement of EJB 3.2 (described in https://java.net/projects/ejb-spec/lists/jsr345-experts/archive/2013-03/message/49)
>
> Should we propose a change to the EJB spec for Java EE 8 that makes this unnecessary?

Making the marker interface optional would be a nice feature... David has been talking about this as a natural second step for the EJB side of things.

It's not essential for JMS, though.


> 1. Annotations on the class
> ---------------------------
>
> @MessageDriven - mandatory, specifies that this is a MDB.

Maybe we could also propose a change to the EJB/RA spec to allow this annotation to be inherited from an interface, like the @Remote annotation is.

> The optional activationConfig attribute would still be available, though hopefully the need for this would be much reduced.
>
> This is also where we could configure the size of the MDB pool and other attributes. Currently there is no standard way of configuring this, though it can usually be configured using activation properties. I would suggest that this is not a priority. Both the EJB container and the resource adapter itself may pool MDBs; we would need to be clear which we are configuring.

Standardizing on this would be good for portability. But it's not a core requirement.

IMHO it's generally better to configure such things in the container (if the default value is not suitable), not on the MDB.

Still there are use-cases, where it would help. But do we need to be able to configure both? Or can we define that this is the job of one or the other?


> 2. Annotations on the method
> ----------------------------
>
> One or more callback methods could be defined, using annotations that specify
>
> * @DestinationLookup or @DestinationName
> * @ConnectionFactoryLookup (with a suitable default)
> * @AcknowledgeMode
> * @MessageSelector
> * @DestinationType
> * @SubscriptionDurability
> * @ClientId
> * @SubscriptionName
>
> So we might have
>
> @Destination("inboundQueue") @MessageSelector("foo=bar")
> public void method1(Message message){

I assume that most of these are optional. Only a default @Destination/_at_DestinationName or @DestinationLookup needs to be discussed.

I think it would be good to just use the fully qualified class name of the bean.


> 3. Annotations on individual method arguments
>
> My idea here is that a callback method may have any number of arguments, with perhaps the option to add annotations to each argument in the cases where it is not obvious from the argument type what needs to be passed in. Arguments could be
>
> * The message as a javax.jms.Message
>
> public void method1(Message message){
>
> * The message as a particular subtype of javax.jms.Message such as javax.jms.TextMessage
>
> public void method2(TextMessage textMessage)
>
> * The message body. In this case the argument would be annotated with the expected class, as with Message#getBody
>
> public void method3(@BodyType(String.class) String text)
>
> * Message headers. In this case the argument would be annotated with the expected header name
>
> public void method4(@JMSMessageID String messageID)
>
> * message properties. In this case the argument would be annotated with the expected property name and type
>
> public void method5(@JMSBooleanProperty("foo") boolean booleanValue)
>
> public void method6(@JMSStringProperty("foo") String stringValue)
>
> ...or any combination of these, such as
>
> public void method3(@BodyType(String.class) String text, @JMSMessageID String messageID)
>
> Further variants might allow messages to be delivered in batches.

* If it's a MapMessage, maybe the individual values could be assigned:

public void method4(@MapMessageField("foo") String foo, @MapMessageField("bar") boolean bar)

* If the Java-8 argument names or debug information is available, the @MapMessageField annotation could be optional:

public void method5(String foo, boolean bar)

* If the argument is a pojo with corresponding fields, they could be filled:

class Pojo {
    String foo;
    @MapMessageField("bar") boolean b;
}

public void method6(Pojo pojo)

* I could continue this list ;-)



Rüdiger

> Any comments before I work this into a more detailed proposal?
>
> Nigel