jsr343-experts@jms-spec.java.net

[jsr343-experts] Re: [jms-spec users] Re: Re: JMS Support for DI

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Wed, 07 Sep 2011 19:31:27 +0100

Notes from a call on 6 Sept 2011 to discuss dependency injection features in JMS 2.0
On the call: Nigel, John, Reza,
Minutes: John (thanks) extended by Nigel. Any errors or misrepresentation below are Nigel's fault.

CDI vs. AtInject support
------------------------

We discussed whether the new API should be based on CDI (JSR 330), AtInject (JSR 330) or be independent of either, as
@PersistenceContext appears to be.

It was felt that we should avoid re-inventing the wheel and try to make use of existing standards where possible, so
avoid inventing a completely new injection API like @PersistenceContext.

If we based the API on AtInject rather than CDI we would need to be more prescriptive about how the API should behave.
For example, although AtInject defines the concept of scope, it doesn't define any standard scopes as CDI does (though
even CDI's built-in scopes may be inadequate for us). In fact AtInject is in general much less fully-defined. There is
essentially no RI for AtInject, other than the code hosted on googlecode, and there is no TCK.

CDI is a Java EE standard, so using CDI would be consistent with the direction of Java EE. If we thought it necessary we
could seek improvements for CDI 1.1.

It was agreed that we could defer making a decision on this until we came across a reason to need to focus on one or the
other. We didn't yet know how much could be based on standard CDI and how much would need to be custom behaviour.
Initially we should focus on simply specifying what we need, and not be too constrained by exactly how it would be
implemented.

It was agreed that the focus of the new API would be Java EE, though allowing it to be implemented for Java SE should
remain a goal. We would assume that CDI 1.1 would mandate support for SE. Inevitably any new API for Java SE would lack
features which can be taken for granted in Java EE, such as global/XA transactions and the ability to inject JNDI
respources. There would probably need to be separate TCKs (compliance tests) for Java EE and Java SE.

Scope of injected objects
-------------------------

We discussed whether or not we needed to define exactly what the scope of injected JMS objects should be. It was agreed
that for appplications to be portable we needed to define this.

This scope would need not be used by application developers, but be used internally by JMS to manage all JMS objects
(producers, consumers, sessions, etc) within a life cycle.

We compared the degree to which AtInject and CDI define scopes and their behaviour. AtInject allows scopes to be defined
but doesn't define any particular scopes or their behaviour. CDI does define built-in scopes and their behaviour and
also offers support for custom scopes.

It was thought that the built-in CDI scopes may be inappropriate, and we needed a new "transaction scope" such as that
used in Resin. It was agreed that we should define what scope behaviour we required, and then look into whether this
could be standardised in CDI or whether it would need to be a custom scope used only by JMS.

It was observed that the RI might require app-server-specific code to access the transaction manager. Nigel said that if
possible we should request enhancements to the Java EE platform spec to avoid this.

Qualifiers vs. Annotations
--------------------------

AtInject has a special annotation called Qualifier that defines contextual injection of components. These qualifiers
are optional but define certain required characteristics within the CDI realm. Their dependency in non CDI injectors is
not specifically defined.

Review of annotations
---------------------

We started reviwing the various annotations proposed by John and the similar but slightly different annotations proposed
by Reza, but decided we needed to do some more work offline to review the complete set of injected objects, the data
they require, and the dependencies between them. Nigel agreed to look into this.

We did, however, talk about the API to inject a connection and a session. Ir was agreed that the same annotation could
be used to define both. In an EE environment, there is only one session per connection and configuration for transacted
and acknowledge mode are ignored. In SE they could be used.

Simplified messaging support
----------------------------

We discussed whether the API could allow users to send and receive messages without the need to handle javax.jms.Message
objects. Nigel observed that this was an issue with the basic JMS API, not just with this new dependency injection API.

One idea was to add two methods to the MessageProducer interface to support sendText(String) and
sendObject(Serializable) that would send a TextMessage and an ObjectMessage with the supplied argument as the payload.

However we thought that if we offered this we would need to offer corresponding receive() methods on MessageConsumer.
However this might lead to an explosion of methods:

reciveText()
receiveText(timeout)
receiveTextNoWait()
reciveObject()
receiveObject(timeout)
receiveObjectNoWait()

If we offered this for all 6 message types we would end up with 18 new methods. This didn't seem like an improvement in
usability.

What should happen if the next message was of the wrong type? Was there an implied message selector so only messages of
the expected type were returned? At the very least this was a complicating side-effect.

Another idea was to have simpler methods which simply took the method payload as an object and worked out what JMS
message type to send. This would reduce the amount of code needed but at the expense of type-safety.

None of the options we discussed looked ideal. It was agreed that this whole area was rather orthogonal to the
dependency injection discussion, which could continue without us needing to come to any particular decision on
"payload-only" messaging right now.

Factory methods for messages
----------------------------

We also discussed John's proposal for a generic factory metthod for messages:

public <T extends Message> T createMessage(Class<T> messageType);

The main benefit of this would be to allow vendor-specific message types to be created, such as XMLMessage. Nigel said
that this would be non-portable and we should discourage it. If there was a need for new message types (such as
XMLMessage) this could be considered as a general JMS 2.0 feature rather than something specific for the injection API.

We then discussed the existing API to create messages: Session.createTextMessage() etc. Allowing messages to be injected
would hide the slightly confusing use of a session as a message factory. It was agreed we should try to clarify the spec
to allow an implementation to send a message created by another session/connection.

Follow Up Items:
----------------

Nigel to review all configuration settings for domain objects in the javax.jms package, and come up with proposed
mapping to annotation(s)

John to review how transaction scoped was implemented for injection in Resin.

Next call
---------

Monday 12th September from 1000-1100 EDT, 1500-166 BST. Open to all EG members, contact Nigel for dial-in details.