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: Wed, 17 Jun 2015 09:06:15 +0000

sorry for taking so long to reply... the proposal is a lot to consider and these are busy times... as always ;)

• Issue I2: I agree with your colleague that the return type should be defined to be void. Anything else would be non-portable now and maybe could be specified in the future.

• Issue I3: "The EJB specification does not define a standard way to associate a MDB with a resource adapter.” Is this about different RAs existing in the container and associating an MDB with one of them? If so, it would be more clear to have the word ‘specific’ before ‘resource adapter’. I think this is a separate issue that could be discussed independently.

• Issue I4: It would be _very_ helpful to have more than one callback method, e.g. to receive different types of messages. We would have to specify the selection algorithm, though. Annotations could be placed on the method _or_ the class, with the usual logic that method level annotations overwrite class level annotations. And the RA can decide whether it needs different consumers for different methods (e.g. only when they have different destinations).

• Issue I6: I don’t understand, why the RA cannot access the onMessage method to fetch annotations. This should be just some interface for the RA, shouldn’t it? And ignoring them may be confusing. I’d prefer if they either where an error, or be allowed. Maybe I should take a look at the RI code ;-)

• Issue I11: The destination name is generally simpler than the JNDI name. It can be used to specify the destination on a more abstract, business-oriented level, e.g. ‘trades’. So, objecting to your colleague, I think it would be desirable to use that, yes... portable or not.

• Issue I13: We can assume that the destination already exits in the container. The RA then can simply look it up to see if it’s a queue or a topic. Then it would even be possible to swap one for the other without changing the application. The queue topology shouldn’t be relevant for an application, should it? This is why I prefer @JMSListener to @JMSQueue/TopicListener.

• Specify the connection factory: I think it’s worth to note that there is a default connection factory, so this annotation is optional.

• Issue I14: I think it would be more consistent to have separate annotations even here.

• Parameters for message body: It should be an error to have more than one method parameter for the message body, i.e. the container should report and fail to load an application with MDBs that has methods with more than one parameter without a @MessageHeader or @MessageProperty annotation. Annotation processors could mark this error even in the IDE.

• Message properties: Should we make the value of the @MessageProperty annotation optional in Java 8? Even though the default is not to include the parameter names in the class file (which I consider a bad decision, as it reduces adoption, which already has effectively killed the assert keyword), it can really reduce repetition of the name.

• Issue I16: I also agree with you colleague that we should consider to finally specify DLQs. They are one of the fundamental messaging patterns, and official support is overdue. Routing messages that can’t be converted are just one use case; they also should be usable for messages that can’t be delivered due to technical as well as application problems in the consumer.

• Question 1: Will it be possible to use @Stereotypes for all the annotations?

• Question 2: If the container sets method parameters to message headers and message parameters, wouldn’t it be useful to have it also set method parameters to message fields of a MapMessage?


@David: I would have *loved* to go to Devoxx UK. We probably would have missed most sessions just talking ;-) I sadly skipped Antwerp last year, but will make it this year for sure.



Rüdiger


> On 11.06.2015, at 16:22, Nigel Deakin <nigel.deakin_at_oracle.com> wrote:
>
> > 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
>
>