jsr343-experts@jms-spec.java.net

[jsr343-experts] Re: [jms-spec users] Re: (JMS_SPEC-33) Improving the JMS API with API simplifications, annotations and CDI

From: Reza Rahman <reza_rahman_at_lycos.com>
Date: Mon, 01 Aug 2011 14:33:27 -0400

Rudiger,

Just to be clear, are you proposing this as an even higher level
abstraction or a replacement to what I had outlined earlier? Do you have
detailed documentation on this solution other than the article you sent
earlier?

As I mentioned earlier, the biggest practical issue I see with this is
that it reduces flexibility a bit too much -- which might be fine for a
third-party JMS plugin but pretty risky for a standard API (I think this
is ultimately what Nigel was getting at). The other imminent problem I
can see with the approach is that it relies on a relatively
unfamiliar/unproven paradigm -- metadata on an artifact not otherwise
part of the business logic. I think at this point it's best to gain
better acceptance of this paradigm outside the standard. I don't want to
be a naysayer, but I think it might not sit all that well with
developers used to the current POJO paradigm of placing meta-data on
objects that are a functional part of the application otherwise and
using general purpose APIs that translates that metadata when applicable.

The closest thing I can think of is annotated entity mappings, but even
that is more transparent/intuitive to the average developer. If we go
this route, we might want to see if that model suffices instead of
placing mappings on something that looks like a business logic artifact
but is not really a business logic artifact at all (which is basically
what John was saying I think). Other than some arguably semantic
benefit, this approach requires creating a fairly mechanical interface
that really has no other purpose than serving as a redundant artifact
for the framework. To be very specific, this would basically be the JPA
equivalent of creating "empty" interfaces such as OrderDao.addOrder and
placing ORM meta-data on that as opposed to simply having the general
purpose EntityManager API that reads developer configured ORM meta-data
on a POJO that also serves as a domain/entity object on its own right.

Hope this is sensible. It's a good idea that might indeed eventually be
broadly accepted (or not), I just don't think it's right for a standard
API at this point. Maybe others see this differently?...

Cheers,
Reza


On 8/1/2011 5:01 AM, Ruediger zu Dohna wrote:
> [I'm on the expert group by now, but not yet on the EG mailing list. I
> wanted to get this out now, so I send it on the users list... I hope
> everybody interested is on this list as well, esp. Reza and John]
>
> Hi,
>
> I agree that we should use CDI as much as possible to make JMS more
> usable. I also agree with Reza that it would be great, if this would
> be a CDI layer on top of the existing JMS APIs that would allow the
> user to get anything they need injected or even simply produce the
> message objects they want to send.
>
> *But I think we could do much more than that!*
>
> I'll need to do a bit of a round-trip to make my point clear...
> starting with the example from Nigel:
>
> @Resource(name="myQueue") Destination destination;
> @Resource(name="myConnectionFactory") ConnectionFactory
> connectionFactory;
>
> private void send(String messageText) throws JMSException {
> Connection connection = connectionFactory.createConnection();
> try {
> Session session = connection.createSession(false,
> Session.AUTO_ACKNOWLEDGE);
> MessageProducer producer = session.createProducer(destination);
> Message message = session.createTextMessage(messageText);
> producer.send(message);
> } finally {
> if (connection!=null) connection.close();
> }
> }
>
> This code hides JMS from the business code that calls this method. But
> if we want to replace it completely by something the container
> provides, it has to be generic, which it is not for functional and
> non-functional reasons. I'll concentrate on the functional aspects
> first: The destination defines the semantic of the message and should
> be named accordingly. E.g. it could be a destination for twitter
> messages named TwitterDestination or a destination to delete customers
> by their id named DeleteCustomerDestination. So the method name should
> also not be "send" but e.g. "tweet" or "deleteCustomer".
>
> Adding more methods, you'd either have to add more destinations, or
> group functionality into one destination and put the desired operation
> into the message... either as a message property or into the message
> payload. I mostly prefer the latter, but you can change that without
> touching the clients of the existing method. Also the exact message
> format could change without the business code being affected... nice
> design.
>
> If the class gets too big and/or to make testing the business code
> easier, I'd refactor these JMS-methods and the resources they envy
> into a delegate... probably even extracting an interface.
>
> public interface CustomerService {
> public void createCustomer(String first, String last);
> public void deleteCustomer(String id);
> }
>
> *This* is what the business code programmer wants to see... nothing
> more. Now all the boiler plate code is in one place, and... magic
> fairy dust sparkle sound... we can get completely rid of it! Assuming
> that the exact message format, the destination name, and some other
> things are not really interesting as long as the sender and the
> receiver agree, this code can be implemented in a generic fashion!
> Convention-over-configuration.
>
> If we need to explicitly configure these things, e.g. in order to
> communicate with some legacy system, or in order to serve some
> non-functional requirements, like a QoS, priority, etc., we could use
> use CDI qualifiers:
>
> @Inject
> @DestinationName("myQueue") // required by legacy system
> @Priority(HIGH) // non-functional requirement
> CustomerService sender;
>
> This would run in Java EE as well as in Java SE with only a CDI
> container. For clients without CDI, there would have to be a factory
> method... and the non-functional aspects would have to be configured
> with a builder.
>
> There are use cases that require more control on the message format...
> stream messages come to my mind. But I consider them as border cases
> that require additional API.
>
> I think it would be a great leap forward to hide *all* of this by
> default... and when you need to specify something, add an annotation
> and let the container figure out how to obey. If the reference
> implementation only delegates to the JMS 1.1 API, all JMS
> implementations would be supported right away, while a more direct
> binding to an implementation might provide additional benefits (as
> Reza pointed out).
>
> Nigel sees the asynchronous receiver side as a separate issue, as the
> current specs force us to use MDBs. The goal IMHO would be that the
> business code would simply implement e.g. the CustomerService
> interface and not care about the message format, etc. While it could
> be possible to generate the required MDB classes on the fly, it would
> be easier if we could use the MessageListener interface, as we can
> bind those generically to any destination. But how can we have a
> single transaction for the consumption of the message and the business
> code that is called? I'm optimistic that this can be resolved, but I
> agree this would require a deeper integration into the container... a
> completely separate layer on top of JMS, desirable as it is, may not
> suffice.
>
> Is this not a good thing to aim at? But maybe I completely miss
> something. Are there any real objections, other than we might have to
> completely rewrite the spec? I believe that hiding JMS behind a pure
> business interface is a logical result from viewing asynchronous
> messaging radically from the business programmer perspective, but I
> may have lost sight of some other, elemental features. Please tell me,
> if this is so! Or should I provide more detail?
>
>
> Regards
> Rüdiger
>
>
>
> -----
> No virus found in this message.
> Checked by AVG - www.avg.com
> Version: 10.0.1390 / Virus Database: 1518/3801 - Release Date: 07/31/11
>
>