jsr343-experts@jms-spec.java.net

[jsr343-experts] Re: [jms-spec users] Re: JMS over CDI or something else?

From: John D. Ament <john.d.ament_at_gmail.com>
Date: Thu, 7 Jul 2011 15:07:36 -0400

Reza,

I agree, we can talk offline about individual projects that people work on.
There are really two points I was trying to make, really with regard to how
to integrate JMS and CDI (which seam jms is aiming to do, and hoping to
bring it as part of the jms 2.0 spec for parts at least).

1. The event model is a direct integration between serializables and sending
JMS messages. Obviously, the big limitation is that a created message needs
to be bound to a specific JMS session. For right now, there is no way to
guarantee that the JMS SEssion used to create a message fired is then
actually sent via that session, CDI doesn't have a scope that confirms
that. It maps destinations via a mapping interface, but I don't know that
this is the right approach. The simple example Adam published earlier is
exactly what I would think for sending events, perhaps with a message
implementation that allowed you to set headers/properties but didn't
actually send to JMS (forwarded, and internally was translated to some type
of JMS message).

2. The simplified APIs provided in Seam JMS are really just meant to
supplement the fact that an injected MessageProducer is completely unusable
as you need to guarantee that the JMS session injected for creating messages
is the same one used to create your producer. Consumer style APIs (e.g.
creating a listener) are to supplement the fact that it was just something
easy to do once all of this infrastructure was in place. If someone is
looking for capabilities around the session at the HTTP session level,
creating their own producers to support this is simple enough; though I
don't know if I would exclude it as something to do for the EG. Really
though, the event model was the main goal of the framework.

I guess a few questions to throw out there as well.

1. Is it useful to be able to capture the JNDI name of a JMS Destination as
a qualifier on the event when fired? We had some arguments over this topic
in particular. Not just JMS but in general. I came to the level of using a
mapping interface to describe what event object types to expect and what
destinations to route them through made the most sense. This was mostly
because CDI didn't support forwarding the annotations fired in the event
along with the payload. Other modules I see use a wrapper object to handle
their event mappings. I finally broke down and supported this format as
well for outbound (fired events turn into jms messages) events only.

2. One subject brought up a few times was the replacement of MDB. Seam JMS
can forward JMS messages, as both the native message object and the
underlying data element, as a CDI event. The problem with the approach was
more semantics of it. My preference would be to see some type of more JMS
appropriate method handler setup so that a single class could have multiple
methods handling JMS messages inbound, perhaps multiple queues/topics in a
single method, allowing for annotations to control the transaction state,
acknowledge mode. maybe something like

@Listens("jms/Queue1","jms/Queue2")
@Transacted
@AcknowledgeMode(Session.AUTO_ACKNOWLEDGE)
public void handleMessageOnQueue1(@MessageData String data) {
....
}

- John

On Thu, Jul 7, 2011 at 2:32 PM, Reza Rahman <reza_rahman_at_lycos.com> wrote:

> **
> John,
>
> If I understand what you are saying correctly, I think we are basically on
> the same page :-).
>
> I did not like the current version of Seam JMS because it abstracted some
> of the JMS APIs that really are general purpose and not just boilerplate
> "stuff" (this judgment being highly subjective based on my development
> experiences with JMS, Spring, Seam, etc).
>
> If it helps, I can give you a rough outline of what we had envisioned for
> Resin, but have not yet implemented or documented publicly. At this point
> though, I do think we should let Nigel take the lead on things so we can
> move things forward promptly.
>
> Cheers,
> Reza
>
>
>
> On 7/7/2011 8:41 AM, John D. Ament wrote:
>
> I'm curious to know why you don't like the Seam JMS approach, personally.
> I would love for it to be able to support @Inject Event<javax.jms.Message>
> msgEvent; msgEvent.fire(myMessage); however creating messages is based on a
> session, and the session and message are dependent in some cases, however
> the CDI scoping requirements make this a little difficult to do (which one
> of my goals is to make that work right), therefore we primarily support
> basic object firing and no properties (though, I am currently working on a
> JmsMessage implementation that supported the necessary payload and
> properties, but it still requires a translation.
>
> Some more comments in line...
>
> - John
>
> On Thu, Jul 7, 2011 at 5:44 AM, Adam Bien <abien_at_adam-bien.com> wrote:
>
>> Hi Rüdiger,
>> On 04.07.2011, at 18:42, Ruediger zu Dohna wrote:
>>
>> Hi Adam,
>>
>> On 6/30/2011 6:05 AM, Adam Bien wrote:
>>
>> On 29.06.2011, at 17:32, Rüdiger zu Dohna wrote:
>>
>> > most people on the EG seem to like the idea of using CDI events to
>> bind to JMS. I like that idea, too, as I love CDI, but there may be reasons
>> to use JMS without even that container. Namely starting the CDI context
>> takes a noticeable amount of time, and this may be too much for some use
>> cases.
>>
>> the startup CDI performance is only dependent on the implementation. The
>> is nothing inherently slow in the CDI spec.
>>
>>
>> There has to be done quite some class loading and scanning, hasn't it?
>> Sure, only for the jars that contain a beans.xml, so this doesn't *have* to
>> be a problem, but sometimes it can. Maybe performance isn't the reason
>> either, maybe it's just that it's not *P*OJO any more.
>>
>>
>> Whether it has to scan, or not, I really do not care when it is fast
>> enough :-) I don't think it is an issue.
>> What is actually the definition of POJO? No proxies allowed between or no
>> bytecode extension?
>>
>> I would like to see a strong integration of all Java EE 7 specs and
>> pruning all overlaps.
>>
>>
> Well, when you're using CDI you already have a call back to all classes in
> the bean archive, so that lets you filter it to what you're going to be
> interested in.
>
>
>>
>>
>> > I also prefer to have a verb for messages, not only a message object.
>>
>> >
>>
>> > I.e. I prefer
>>
>> > createCustomer("Joe", "Doe")
>>
>> > to
>>
>> > event.fire(new CreateCustomer("Joe", "Doe"))
>>
>> O.k. but I would still allow to send messages via CDI.
>>
>>
>> I love CDI, but I only like events. To me they feel somewhat foreign to
>> the DI concept. They look cool, but the little experience I had with them
>> was, that I often had to create a special message object class.
>>
>>
>> Why not a Qualifier?
>>
>> A method just seems more intuitive to me.
>>
>> Maybe it's just that REST is so hip nowadays and everybody thinks of
>> actions as some kind of resource. Don't take me wrong: I prefer REST over
>> WS-* by faaaaaaaar! But I don't think that this approach is universally
>> suitable to everything, either.
>>
>> Maybe there are good use cases for both. Maybe someone with a lot of CDI
>> event experience has to answer this question: How often do you create a new
>> message class only to a) group multiple parameters, or b) give the
>> parameters the semantic context of a action name? Or how often is the
>> message class already there and can be reused? If it's the former, I'd say
>> that CDI events produce boiler plate code.
>>
>>
>> In all my cases all event classes in CDI are just my domain classes. I
>> use Qualifiers as replacement for topic names.
>>
>>
> I'm curious how you're doing this, since there's currently an enhancement
> in CDI to support forwarding the qualifiers when firing an event, since the
> scoping rules are a bit unsavory (at least from my opinion).
>
>
>>
>> Then only an empty interface, annotated with e.g. @JMSSender would be
>> sufficient, right? If yes, then (dynamic) proxy would implement the heavy
>> lifting
>>
>>
>> One of the first feature requests in CDI 1.1 (Java EE 7) is the support
>> for interception of Abstract classes / interfaces:
>> https://issues.jboss.org/browse/CDI-110?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12589523#comment-12589523
>>
>> This would also solve this issue in a standard way.
>>
>>
>> The interface would contain at least one method. The dynamic proxy would
>> implement the heavy lifting of mapping the method name and the parameters to
>> a JMS message.
>>
>>
>> Or an interceptor / ServiceHandler. Why to re-invent the wheel?
>>
>>
>> > And I don't think that we should force all JMS implementations to run
>> outside of "their" environment, e.g. in plain vanilla Java SE. If we instead
>> would make sure that all JMS client code really runs without any
>> modification in any JMS implementation, that would be a *big* win. If the
>> JMS implementations specify the exact environment they need, clients would
>> be free to choose and change their minds at any time.
>>
>>
>> What do you mean by " force all JMS implementations to run outside of
>> "their" environment"?
>>
>>
>> There was a suggestion on the list to force all JMS implementations run in
>> plain Java SE. I don't think that's a good thing to require from all
>> providers, as they now can simply rely on a lot of their infrastructure.
>>
>> +1.
>>
>> I'm not too sure what this means to be honest. If the issue is that a
> JMS implementation should be bootable in an SE environment, then yes I think
> that should be included. What that actually boots (e.g. a full web
> container, EJB container, CDI container, etc) will vary.
>
>
>>
>> On 2011-06-30 10:47:07 -0400 Reza Rahman <reza_rahman_at_lycos.com> wrote:
>>
>> I agree with the CDI performance comment. CanDI starts up in seconds or
>> less, I believe OpenWebBeans does too.
>>
>>
>> Seconds may be too slow... I can even think of a use case to use the
>> @Inject keyword for your own mini container that supports only a CDI subset
>> without events.
>>
>> So far the performance of CDI (Weld in particular) was far better than
>> expected....
>>
>>
>> The approach mentioned is something I've seen before. The issue I have
>> with it is that it abstracts too much of the JMS API away and puts too much
>> that should be in code into configuration (XML in this case), potentially
>> reducing flexibility (it's still a very cool project though -- just probably
>> not right as a core standard). In some ways, Spring JmsTemplate gets it
>> right in that regard by not abstracting too much of JMS itself. The Resin
>> approach is similar, but more CDI/JMS centric. As an aside, I am not totally
>> sold on the Seam JMS Module approach either (again I think it reduces
>> flexibility too much). For our design we still kept things relatively
>> centered around javax.jms.Message and just focused on removing very common
>> boilerplate code (both for send and receive).
>>
>>
>> I understand your point, but I don't see a practical use case to put the
>> logical message format into code... that's actually twice: Once on the
>> sender, once on the receiver. Configuring the message format is supported
>> only for legacy systems, normally you'd stick with the default xml body.
>>
>> And when it comes to evolving the API, I prefer explicit versioning of
>> statically typed APIs over dynamically adding or removing things from a map
>> and hoping everybody will find bugs in integration tests.
>>
>> The xml configuration for the destination etc. that's currently required
>> by the MessageApi, could be replaced with annotations... CDI could read them
>> from the injection point, while it's to cumbersome to pass them into the
>> factory.
>>
>>
>> Have fun
>> Rüdiger
>>
>> <ruediger_dohna.vcf>
>>
>>
>>
>>
> ------------------------------
>
> No virus found in this message.
> Checked by AVG - www.avg.com
> Version: 10.0.1388 / Virus Database: 1516/3748 - Release Date: 07/06/11
>
>
>