users@jms-spec.java.net

[jms-spec users] Re: JMS_SPEC-116: JMS MDB improvements: simplifying the annotations

From: Werner Keil <werner.keil_at_gmail.com>
Date: Fri, 11 Sep 2015 10:30:12 +0200

Nigel,

Thanks for outlining those options.

I prefer B or C.

The "annotation hell" you see in A may feel a bit typesafe at first, but
for every string value like
@SubscriptionName("mySubName1") if you pick the wrong name it won't work
and you get an error during runtime or appropriate tests only.

Especially for "name" or "Id" types of information that feels
overengineered.

Werner

On Fri, Sep 11, 2015 at 3:13 AM, <users-request_at_jms-spec.java.net> wrote:

> Table of contents:
>
> 1. [jms-spec users] JMS_SPEC-116: JMS MDB improvements: simplifying the
> annotations - Nigel Deakin <nigel.deakin_at_oracle.com>
>
>
>
> ---------- Forwarded message ----------
> From: Nigel Deakin <nigel.deakin_at_oracle.com>
> To: users_at_jms-spec.java.net
> Cc:
> Date: Thu, 10 Sep 2015 17:21:09 +0100
> Subject: [jms-spec users] JMS_SPEC-116: JMS MDB improvements: simplifying
> the annotations
> I'm continuing to work through some of the issues raised on my proposals
> to improve JMS MDBs at
> https://java.net/projects/jms-spec/pages/JMSListener2. To help readers
> I'm starting a new thread for each issue.
>
> I'd like to review the proposed new method annotations for JMS MDBs in a
> bit more detail. These are the annotations that would (1) specify that a
> method was a callback method and (2) specify which messages should be
> delivered to it.
>
> Recap of current proposal
> -------------------------
>
> The following example illustrates the annotations currently proposed:
>
>
> @JMSListener(lookup="java:global/java:global/Trades",type=JMSListener.Type.TOPIC
> )
> @JMSConnectionFactory("java:global/MyCF")
> @SubscriptionDurability(SubscriptionDurability.Mode.DURABLE)
> @ClientId("myClientID1")
> @SubscriptionName("mySubName1")
> @MessageSelector("ticker='ORCL'")
> @JMSListenerProperty(name="foo1", value="bar1")
> @JMSListenerProperty(name="foo2", value="bar2")
> @Acknowledge(Acknowledge.Mode.DUPS_OK_ACKNOWLEDGE)
> public void giveMeAMessage(Message message) {
> ...
> }
>
> Obviously, this is an extreme example which demonstrates the use of every
> annotation. I'm including the new @JMSListenerProperty annotation I
> proposed a few days ago.
>
> @JMSListener is always required: this is the annotation that signifies
> that this is a callback method. That's why the name is "JMSListener" rather
> than "JMSDestination", despite its role being to specify the queue or topic.
>
> In @JMSListener, the lookup attribute can be omitted. This was to allow
> the MDB to use "legacy" ways to define the queue or topic, such as using
> the MessageDriven's mappedName attribute. This would also allow an
> additional attribute such as "name" to be added in the future which allows
> the queue or topic's "non-portable" name to be specified.
>
> However in @JMSListener, the type attribute would always be required. I
> proposed this because the spec does not define a default value and it
> seemed useful to allow the app server/resource adapter to know what type of
> destination was expected.
>
> Otherwise, there is a separate annotation corresponding to each of the
> standard activation properties.
>
> Discussion
> ----------
>
> There are a number of things we should review here. I think the main thing
> we need to consider is which is better:
>
> a. to have lots of separate annotations, almost all of which have a
> single attribute, or
>
> b. to have a smaller number of annotations, each of which set multiple
> attributes.
>
> An alternative proposal
> -----------------------
>
> I'd like to suggest an alternative set of annotations:
>
> One for queues:
>
> @JMSQueueListener(destinationLookup="java:global/java:global/Trades",
> connectionFactoryLookup="java:global/MyCF",
> messageSelector=""ticker='ORCL'",
> acknowledge=JMSQueueListener.Mode.DUPS_OK_ACKNOWLEDGE)
> @JMSListenerProperty(name="foo1", value="bar1")
> @JMSListenerProperty(name="foo2", value="bar2")
> public void giveMeAMessage(Message message) {
> ...
> }
>
> One for durable topic subscriptions:
>
>
> @JMSDurableTopicListener(destinationLookup="java:global/java:global/Trades",
> connectionFactoryLookup="java:global/MyCF",
> clientId="myClientID1",
> subscriptionName="mySubName1",
> messageSelector=""ticker='ORCL'",
> acknowledge=JMSQueueListener.Mode.DUPS_OK_ACKNOWLEDGE)
> @JMSListenerProperty(name="foo1", value="bar1")
> @JMSListenerProperty(name="foo2", value="bar2")
> public void giveMeAMessage(Message message) {
> ...
> }
>
>
> One for nondurable topic subscriptions:
>
>
> @JMSNonDurableTopicListener(destinationLookup="java:global/java:global/Trades",
> connectionFactoryLookup="java:global/MyCF",
> messageSelector=""ticker='ORCL'",
> acknowledge=JMSQueueListener.Mode.DUPS_OK_ACKNOWLEDGE)
> @JMSListenerProperty(name="foo1", value="bar1")
> @JMSListenerProperty(name="foo2", value="bar2")
> public void giveMeAMessage(Message message) {
> ...
> }
>
> Some of these attributes would need to be specified, others would be
> optional.
>
> Having separate annotations for queues, durable subscriptions and
> non-durable subscriptions would remove the need for the user to specify
> destinationType or subscriptionDurability as attributes.
>
> Possible further option
> -----------------------
>
> In addition to the alternative above, we could also offer a completely
> generic annotation, though this would strictly be unnecessary:
>
>
> @JMSDestinationListener(destinationLookup="java:global/java:global/Trades",
> type=JMSListener.DestinationType.TOPIC,
> connectionFactoryLookup="java:global/MyCF",
> clientId="myClientID1",
> subscriptionDurability=JMSListener.SubscriptionDurability.DURABLE
> subscriptionName="mySubName1",
> messageSelector=""ticker='ORCL'",
> acknowledge=JMSQueueListener.Mode.DUPS_OK_ACKNOWLEDGE)
> @JMSListenerProperty(name="foo1", value="bar1")
> @JMSListenerProperty(name="foo2", value="bar2")
> public void giveMeAMessage(Message message) {
> ...
> }
>
> This generic annotation would need to allow destinationType and
> subscriptionDurability to be specified.
>
> What do you think?
> ------------------
>
> What do you think? Do you prefer:
>
> A. One annotation @JMSListener to define the callback method and the
> destination
> One small annotation for every other activation property
> (the original proposals)
>
> B. One big annotation JMSQueueListener for queues,
> One big annotation JMSDurableTopicListener for durable topic
> subscriptions,
> One big annotation JMSNonDurableTopicListener for nondurable topic
> subscriptions,
> One small annotation JMSListenerProperty for each non-standard
> activation property
> (the alternative proposals above).
>
> C The same as B plus
> The generic JMSDestinationListener annotation
>
> D. The generic JMSDestinationListener annotation (only)
> One small annotation JMSListenerProperty for each non-standard
> activation property
>
> I don't have a strong view on which is better: it's mainly a matter of
> style. One advantage of having annotations with multiple attributes is that
> once the user has decided which annotation to use, the IDE would offer
> hints as to which attributes to set.
>
> Nigel
>
>
>
>
> End of digest for list users_at_jms-spec.java.net - Fri, 11 Sep 2015
>
>