Nov 23rd, 2007, 09:36 AM
Message-Driven POJOs in app server: JCA or JMS?
we want to move from MDBs to Message-Driven POJOs (MDPs) in JBoss. JTA transaction support is essential. The JMS provider is ActiveMQ, installed as a RAR in JBoss. I.e., the to-be-replaced MDBs used to be configured via a JCA activation-config.
In Spring 2.5 there are 2 options to configure MDPs listening in JMS destinations:
A. the JCA-way using JmsMessageEndpointManager
B. the JMS-way using DefaultMessageListenerContainer
I'd be very grateful for answers to these questions:
1. What's the advantage of setting up MDPs (listening on JMS destinations) via JCA (A.) rather then JMS (B.)?
I suppose that only the JCA-way supports inbound transactions and thread-management via the JCA WorkManager?
Is this correct? Anything else? Any clear preference?
2. The primary reason we need to move from MDBs to MDPs is that we need to dynamically change the JMS message selector. (MDBs require a re-deployment in that case, which is unacceptable.)
Is this possible with both the JCA-way (A.) and the JMS-way (B.)?
I suppose with JCA this requires creating a new JmsActivationSpecConfig object and passing it to JmsMessageEndpointManager.setActivationSpecConfig( )?
Will i then need to stop() and start() the JmsMessageEndpointManager?
And i suppose with JMS this requires calling DefaultMessageListenerContainer.setMessageSelector ()?
Will i then need to stop() and start() the DefaultMessageListenerContainer?
thank you very much in advance,
Dec 27th, 2007, 04:51 PM
The primary difference between the JCA style and the JMS style of setting up a listener is that the JCA style has built-in support for dynamic scaling (in terms of concurrent receiving of messages), whereas the JMS style requires the listener container to 'emulate' scaling (which works reasonably well too but can't react to sudden bursts as efficiently and as quickly as the JCA style).
A custom Spring TaskExecutor or JCA WorkManager, representing a custom thread pool, can be specified with both the JCA and the JMS style. Spring ships corresponding adapters between those APIs, so this is not really a differentiating factor between the JCA setup style and the JMS setup style in a Spring environment.
In general, the JMS style is more flexible, since it allows for using any native JMS functionality: e.g. local transactions or custom acknowledge modes. It also allows for fine-granular changes at runtime, which seems to be what you're interested in. Concurrency settings, the selector value, even the destination and the target listener object itelf may be replaced at runtime, with the listener container - more or less - immediately adapting to those changes (provided that DMLC's cache level is less than CACHE_CONSUMER, in which case you don't even need to stop/restart the listener container!).
With the JCA style, changes to the ActivationSpec object generally require deactivation and subsequent reactivation of the endpoint, i.e. a stop() / start() call sequence on the affected GenericMessageEndpointManager. This is certainly more disruptive than when using DMLC here. Is it a surprise that, in J2EE 1.4 and above, EJB MDBs are effectively deployed using the very same JCA contract? ;-) Nevertheless, Spring's use of the JCA style provides the ability to preserve the listener instance while re-registering the endpoint, so this is still far more flexible than the use of standard EJB MDBs.
Mar 27th, 2008, 10:48 AM
Iam in a similar situation. This discussion did help me in identifying the pros and cons of each approach.I still have this one quesion about using Message Listeners.
Is it okay to have a listener creating threads and listnening for messages within the J2EE container ? The concern is that the Application server will not be able to control the lifecycle of these threads. I am not sure if this is a valid concern or not.
In contrast the JCA approach will make sure the application server manages the threads for the listener.
Is this observation right ? Any information on this is greatly appreciated.
May 27th, 2008, 10:12 AM
Please configure org.jboss.resource.work.JBossWorkManagerMBean in jBoss and also see the
org.springframework.jca.work.jboss.JBossWorkManage rTaskExecutor to configure server manager thread pool and you can use that for jms container as well search the forum and you will find many examples (mostly for websphere and weblogic but you can adapt using these tow classes).