users@jms-spec.java.net

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

From: David Blevins <dblevins_at_tomitribe.com>
Date: Tue, 30 Jun 2015 01:00:09 -0700

Realize I'm late on this. Don't have changes in yet, but plumbed in the
annotations from the JavaDoc as I need an IDE to "think" when it comes to
API design.

 -
https://github.com/dblevins/jms-mdb-improvements/tree/master/src/main/java/javax/jms

More tomorrow. Definitely I have a bunch of thoughts.

I'll be on vacation next week and lame as it sounds I'm hoping to get time
to work on this :)


On Wed, Jun 17, 2015 at 2:06 AM, Rüdiger zu Dohna <ruediger.dohna_at_1und1.de>
wrote:

> 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
> >
> >
>
>