(Changing subject line)
On 26/04/2015 01:24, David Blevins wrote:
> As Abhishek notes, we got those changes into EJB 3.2.
>
> Still some work required now on the JMS side to take advantage. Been on my TODO list to dig into this area -- the
> entire reason I joined the JMS EG :)
>
> Anyone want to help work on this? Thinking we could do some prototyping on the GlassFish side of things.
Yes, I do!
David and I have exchanged emails about this. The thing to look into initially is just how much we can achieve simply by
extending the JMS resource adapter (for those app servers which use resource adapters for JMS), and what changes, if
any, might be needed in the EJB container.
As I mentioned in my last email, there have been several proposals to improve the ways that JMS applications can consume
messages asynchronously:
* In JMS_SPEC-116 John Ament proposed (back in March 2013, just as JMS 2.0 was being finalised) improving the ways that
JMS MDBs were defined, taking advantage of some new features that were added to EJB 3.2 and JCA 1.7 just before they
were released. Those new features were the brainchild of David Blevins, and I am delighted that David has joined the JMS
expert group to help guide us in how to make use of them.
* In JMS_SPEC-134 Reza Rahman proposed that JMS defined some annotations that allowed any CDI bean to listen for JMS
messages
* In JMS_SPEC-100 Bruno Borges proposed improving the ways that JMS MDBs were defined, though there was some subsequent
discussion of whether this could be extended to other types of Java EE class such as session beans. I think this is
essentially a combination of the other two proposals.
I think we should start by following the lead taken by John and David and see just how far we can get in improving MDBs.
Although there is definitely a demand for allowing other types of Java EE object to listen for messages (arbitrary CDI
beans, WebSocket endpoints, etc), I think we should focus initially on MDBs.
MDBs provide a lot of useful features which we would have to re-invent (both in the spec and in the implementation) if
we tried to replace them. For example, MDBs already provide a mechanism for instantiating a listener object (or a pool
of listener objects) simply by adding a @MessageDriven annotation to the class. They also also come with a well-defined
portability layer, the connector API, that allows them to implemented with any JMS provider using a resource adapter.
Keeping these all this allows us to focus initially on annotations to define the callback method, the queue or topic
being listened to, the message selector being used, and the particular parameters of the callback method.
Once we've finished improving JMS MDBs we can then consider whether we can make the same annotations available in other
types of Java EE object.
So, what would a improved JMS MDB look like? I was thinking that we would need to define:
0. Marker interface
1. Annotations on the class
2. Annotations in the callback method
3. Annotations on individual method arguments
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?
1. Annotations on the class
---------------------------
@MessageDriven - mandatory, specifies that this is a MDB. 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.
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)
* @cknowledgeMode
* @MessageSelector
* @DestinationType
* @SubscriptionDurability
* @ClientId
* @SubscriptionName
So we might have
@Destination("inboundQueue") @MessageSelector("foo=bar")
public void method1(Message message){
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.
Any comments before I work this into a more detailed proposal?
Nigel