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: Thu, 11 Jun 2015 15:22:02 +0100

> Please take a look and send your comments as soon as possible and by *Friday 26th June* at the latest.
> Depending on what people say I'll work on an updated version in the light of comments.
>
> I've listed 16 issues on which I would be particularly interested to receive feedback.

Here are some comments I've received from a colleague. I'm reporting them here to help stimulate discussion....

> Issue I1: Any alternative proposals for JMSMessageDrivenBean?
>
> Issue I2: Any alternative proposals for JMSListener?

[Colleague] How about replacing @JMSListener with separate @JMSQueueListener and @JMSTopicListener annotations? This
would remove the need for a separate "type" attribute.

[Colleague] Also, by allowing the listener method to have any return type (and defining that it will be ignored) we are
making it impossible to define more useful behaviour in a future version of JMS, since that would break backward
compatible. For example Spring has a mechanism which sends the returned value back to the caller. We might not want
exactly that, but if we require callback methods to return void now, we keep open the option to define behaviour like
this in the future.

> Issue I3: The EJB specification does not define a standard way to associate a MDB with a resource adapter. JMS MDBs that
> require the use of a resource adapter will continue to need to specify the resource adapter in a non-portable way,
> either using the app-server-specific deployment descriptor (e.g. glassfish-ejb-jar.xml) or by using a default resource
> adapter provided by the application server.
>
> Issue I4: The current proposal is that a JMS MDB has a single listener method. However EJB 3.2 section 5.4.2 and JCA 1.7
> does allow a MDB to have more than one listener method, with the resource adapter deciding which method is invoked. Is
> this something we would want to allow? Would these be alternative callback methods for the same consumer, with the
> container choosing which one to call depending on the message and the method signature, or would these represent two
> completely different consumers, on different destinations?
>
> Issue I5: It would be desirable to avoid the need to implement javax.jms.JMSMessageDrivenBean since this is needed
> purely to satisfy EJB 3.2. EJB_SPEC-115 proposes removal of this requirement from the next version of EJB.
>
> Issue I6: The reason why these annotations cannot be applied to the onMessage method of a MessageListener is that
> MessageListener is not a no-method interface, which means the resource adapter cannot access the methods of the MDB
> implementation class. It may be possible to change the EJB specification to allow this restriction to be removed.
>
> Issue I7: Any alternative proposals for the @JMSConnectionFactory, @Acknowledge, @SubscriptionDurability, @ClientId,
> @SubscriptionName or @MessageSelector annotations?

[Colleague] Currently the acknowledgeMode activation property is rather confusing, as it is only used when the MDB is
configured to use bean-managed transactions, which is configured using the class-level annotation
@TransactionManagement(TransactionManagementType.CONTAINER) . The same confusion will apply if we define the new
@Acknowledge annotation to work the same way as acknowledgeMode .

[Colleague] In fact if you want the MDB to consume messages without a transaction and using automatic-acknowledgement
then all you need to do is to set @TransactionManagement(TransactionManagementType.CONTAINER). You don't actually need
to set the acknowledgeMode activation property, since it defaults to auto-ack anyway. The only reason you would ever
need to use the acknowledgeMode activation property is if you wanted to specify the asutomatic acknowledgement to have
the DUPS_OK QoS.

[Colleague] It would be better if we could replace the @TransactionManagement (existing) and @AcknowledgeMode (proposed)
annotations with a single method annotation which could define both at the same time.

> Issue I8: Should JMS define a set of deployment descriptor which correspond to these annotations, and which can be used
> by a deployer to override them? This would require a major change to the EJB and JCA specs since a resource adapter
> cannot currently access the deployment descriptor. A slightly simpler alternative might be to require the EJB container
> to convert these deployment descriptor elements to activation properties and pass them to the resource adapter in the
> activation spec.
>
> Issue I9: What happens if the same attribute is specified using an activation property and using one of these new
> annotations? It is proposed that a value defined using an activation property always overrides the same property defined
> using one of these new annotations, since this would provide a way to override these new annotations in the deployment
> descriptor.
>
> Issue I10: Is an additional annotation required to allow non-standard properties to be passed to the resource adapter or
> container? Or are activation properties adequate for this purpose?
>
> Issue I11: Allowing the queue or topic to be specified by destination name rather than by JNDI name is a new feature.
> Since it is not portable, is this actually desirable?

[Colleague] No. Since queue and topic name is not portable we shouldn't be encouraging its use by supporting it
explicitly in these new annotations.

[Colleague] I know some users don't want to define their queue or topic using JNDI. It would be good if JMS 2.1 were to
define an alternative way to obtain a Queue or Topic object that don't require it, though this should be kept as a
separate issue. Using the attribute "name" to define the non-portable name of the means we can't use it to refer for a
more portable name in the future.

>
> Issue I12: The EJB and Java EE specifications currently define a number of other ways of defining the destination used
> by the MDB, such as by setting the mappedName attribute of the @MessageDriven annotation. The specification will need to
> clarify the override order used if the destination is specified in multiple ways.
>
> Issue I13: Is it right that the @JMSListener attribute type is mandatory,? The existing EJB 3.2 activation property
> destinationType does not define a default value. Should it remain optional, in which case should the specification
> designate a default value when @JMSListener is used?
>
> Issue I14: Should the @SubscriptionDurability, @SubscriptionName and @ClientId annotations (or perhaps the first two) be
> combined into a single annotation?
>
> Issue I15: Any alternative proposals for the @MessageProperty or MessageHeader annotations?
>
> Issue I16: The table above is based on the principle that if a parameter cannot be set to the required value due to it
> having an unsuitable type then it should simple be set to null (or a default primitive value) rather than throwing an
> exception and triggering message delivery. This is because there is no point in redelivering the message since it will
> simply fail again (and JMS does not define any dead message functionality). Is this the correct approach?

[Colleague] I don't like this at all. Using nulls/default values for this purpose is ambiguous, since null might be a
valid message body, header or property value. It would also be difficult to debug, as there would normally not be access
to the message object itself.

What does Spring do? (does anyone know?)

My colleague and I had a discussion about this and came up with several alternative ways of handling conversion errors:

1. Forcing all callback method to have an additional boolean parameter which allowed a status code to be passed in. This
could be used to provide information to the MDB about what the conversion error was.

2. Allowing an MDB to define a second callback method with javax.jms.Message as the only paramater, something like

@FailedDelivery
void failedDelivery(Message m){
   ...

If there was a conversion error whilst setting the arguments for the normal callback method then this "failed delivery"
method would be called instead. The application could examine the specified Message object to find out what was wrong.

3. Treat the listener method parameters as creating an implicit message selector. So if the listener method has a
parameter of type TextMessage then no attempt would be made to deliver messages of other types. These would be left on
the queue or topic.

4. Take the opportunity to define a dead message queue. Then, any if there was a conversion error whilst setting the
arguments for the normal callback method then the message would be sent the dead message queue.

[Colleague] Can we take advantage of defining a new type of MDB to define some better rules for handling the case where
the listener cannot process the message? Since this is completely new we don't have a problem of maintaining compatibility.

[Colleague] In particular, can we define a way for the MDB implementation to force redelivery?
* In the transacted case the application can simply call setRollbackOnly.
* However in the non-transacted case all the application can do is to throw an exception, in which case the bean will be
destroyed. Can we define a way to force redelivery which does not cause the bean to be destroyed?




Nigel