[mule-user] JMS Transaction with websphere MQ

35 views
Skip to first unread message

Meunier Pierre-Emmanuel

unread,
Nov 9, 2007, 6:28:17 AM11/9/07
to us...@mule.codehaus.org

Hello

 

I am trying to use mule to read a message from a JMS queue (using Websphere MQ), send it to a Session Bean (running on a remote Websphere) and put the response back to a JMS queue (still on MQ). I use a ChainingRouter to send the message to the SessionBean and then put the result on a queue.

 

If for some reasons Mule crashes or something unexpected happens, I want the message to stay on the inbound queue, so I was thinking about using transaction. The problem is if I configure Mule to use transactions on my inbound router, I receive the following error:

 

Jms connector does not support synchronous receive in transacted mode

 

Any ideas what’s causing this?

 

I am using Mule 1.4.3 with the IBM JDK 1.4.2 (not ideal but it’s the only way I found to communicate with the SessionBean on a remote Websphere)

 

Thanks in advance

 

Here are the relevant parts of the mule config and the full stack trace:

 

      <connector name="JMSConnector" className="org.mule.providers.jms.JmsConnector">

            <properties>

                  <property name="name" value="MQConnector" />

                  <property name="hostname" value="MyHost" />

                  <property name="connectionFactoryClass" value="com.ibm.mq.jms.MQQueueConnectionFactory" />

                  <map name="connectionFactoryProperties">

                        <property name="hostName" value="xxxxxxxxxx" />

                        <property name="port" value="xxxx" />

                        <property name="queueManager" value="xxxxx" />

                        <property name="channel" value="xxxxxx" />

                        <property name="transportType" value="1" />

                        <property name="specification" value="1.1" />

                  </map>

            </properties>

      </connector>

 

      <model name="default">

            <mule-descriptor name="CPS" implementation="org.mule.components.simple.BridgeComponent">

                  <inbound-router>

                        <endpoint name="jmsPS" address="jms://PM.IN"

                              transformers="JMSMessageToObject XmlToDTO">

                              <transaction action="ALWAYS_BEGIN"

                                    factory="org.mule.providers.jms.JmsTransactionFactory" />

                        </endpoint>

                  </inbound-router>

                  <outbound-router>

                        <router className="org.mule.routing.outbound.ChainingRouter">

                              <global-endpoint name="ejbPSFacade">

                                    <properties>

                                          <property name="method" value="requestUsername" />

                                    </properties>

                              </global-endpoint>

                              <global-endpoint name="out.queue" transformers="DTO2Xml ObjectToJMSMessage" />

                        </router>

                  </outbound-router>

            </mule-descriptor>

 

 

 

ERROR 2007-11-09 11:04:09,720 [MQConnector.receiver.1] org.mule.impl.DefaultExceptionStrategy:

********************************************************************************

Message               : Jms connector does not support synchronous receive in transacted mode

Type                  : org.mule.transaction.IllegalTransactionStateException

Code                  : MULE_ERROR-91302

JavaDoc               : http://mule.mulesource.org/docs/apidocs/org/mule/transaction/IllegalTransactionStateException.html

********************************************************************************

Exception stack is:

1. Jms connector does not support synchronous receive in transacted mode (org.mule.transaction.IllegalTransactionStateException)

  org.mule.providers.jms.JmsMessageDispatcher:104 (http://mule.mulesource.org/docs/apidocs/org/mule/transaction/IllegalTransactionStateException.html)

********************************************************************************

Root Exception stack trace:

org.mule.transaction.IllegalTransactionStateException: Jms connector does not support synchronous receive in transacted mode

      at org.mule.providers.jms.JmsMessageDispatcher.dispatchMessage(JmsMessageDispatcher.java:104)

      at org.mule.providers.jms.JmsMessageDispatcher.doSend(JmsMessageDispatcher.java:330)

      at org.mule.providers.AbstractMessageDispatcher.send(AbstractMessageDispatcher.java:224)

      at org.mule.providers.AbstractConnector.send(AbstractConnector.java:1629)

      at org.mule.impl.ImmutableMuleEndpoint.send(ImmutableMuleEndpoint.java:955)

      at org.mule.impl.MuleSession.sendEvent(MuleSession.java:327)

      at org.mule.impl.MuleSession.sendEvent(MuleSession.java:210)

      at org.mule.routing.outbound.AbstractOutboundRouter.send(AbstractOutboundRouter.java:120)

      at org.mule.routing.outbound.ChainingRouter.route(ChainingRouter.java:102)

      at org.mule.routing.outbound.OutboundRouterCollection$1.doInTransaction(OutboundRouterCollection.java:66)

      at org.mule.transaction.TransactionTemplate.execute(TransactionTemplate.java:39)

      at org.mule.routing.outbound.OutboundRouterCollection.route(OutboundRouterCollection.java:71)

      at org.mule.routing.inbound.ForwardingConsumer.process(ForwardingConsumer.java:51)

      at org.mule.routing.inbound.InboundRouterCollection.route(InboundRouterCollection.java:86)

      at org.mule.providers.AbstractMessageReceiver$DefaultInternalMessageListener.onMessage(AbstractMessageReceiver.java:581)

      at org.mule.providers.AbstractMessageReceiver.routeMessage(AbstractMessageReceiver.java:322)

      at org.mule.providers.AbstractReceiverWorker$1.doInTransaction(AbstractReceiverWorker.java:107)

      at org.mule.transaction.TransactionTemplate.execute(TransactionTemplate.java:92)

      at org.mule.providers.AbstractReceiverWorker.doRun(AbstractReceiverWorker.java:124)

      at org.mule.providers.AbstractReceiverWorker.run(AbstractReceiverWorker.java:60)

      at org.mule.impl.work.WorkerContext.run(WorkerContext.java:310)

      at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:987)

      at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:528)

      at java.lang.Thread.run(Thread.java:568)

 

********************************************************************************

************************************************************************
DISCLAIMER
The information contained in this e-mail is confidential and is intended
for the recipient only.
If you have received it in error, please notify us immediately by reply
e-mail and then delete it from your system. Please do not copy it or
use it for any other purposes, or disclose the content of the e-mail
to any other person or store or copy the information in any medium.
The views contained in this e-mail are those of the author and not
necessarily those of Admenta UK Group.
 
Admenta UK plc is a company incorporated in England and Wales
under company number 3011757 and whose registered office
is at Sapphire Court, Walsgrave Triangle, Coventry CV2 2TX
************************************************************************
 

Yuen-Chi Lian

unread,
Nov 12, 2007, 12:00:40 AM11/12/07
to us...@mule.codehaus.org

Hello Meunier,

Do you mind to provide the complete configuration file? It looks like you
have configured your JMS endpoint (global) with remoteSync="true". Can you
try to disable it (by setting it "false") and see if the same error still
occurs?

Regards,
Yuen-Chi Lian

--
View this message in context: http://www.nabble.com/JMS-Transaction-with-websphere-MQ-tf4777128.html#a13699864
Sent from the Mule - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Meunier Pierre-Emmanuel

unread,
Nov 13, 2007, 4:19:40 AM11/13/07
to us...@mule.codehaus.org
Thanks for your reply Yuen-Chi

I have tried to set remoteSync to false on the JMS endpoint but I still
have the same error.

Here is my config:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mule-configuration PUBLIC "-//MuleSource //DTD
mule-configuration XML V1.0//EN"

"http://mule.mulesource.org/dtds/mule-configuration.dtd">

<mule-configuration id="Default" version="1.0">


<description>Default Configuration</description>

<connector name="ejbConnector"
className="org.mule.providers.ejb.EjbConnector">
<properties>
<property name="jndiInitialFactory"
value="com.ibm.websphere.naming.WsnInitialContextFactory" />
<property name="jndiUrlPkgPrefixes"
value="com.ibm.ws.naming" />
<property name="securityPolicy"
value="conf/security.policy" />
<map name="jndiProviderProperties">
<property
name="com.ibm.ws.naming.wsn.factory.initial"

value="com.ibm.ws.naming.util.WsnInitCtxFactory" />
<property name="org.omg.CORBA.ORBClass"
value="com.ibm.CORBA.iiop.ORB" />
</map>
</properties>
</connector>

<connector name="JMSConnector"
className="org.mule.providers.jms.JmsConnector">
<properties>
<property name="name" value="MQConnector" />
<property name="hostname" value="MyHost" />
<property name="connectionFactoryClass"
value="com.ibm.mq.jms.MQQueueConnectionFactory" />
<map name="connectionFactoryProperties">
<property name="hostName"

value="xxxxxxxx" />
<property name="port" value="xxxxxx" />
<property name="queueManager"
value="xxxxxx" />
<property name="channel" value="xxxxxxx"


/>
<property name="transportType" value="1"
/>
<property name="specification"
value="1.1" />
</map>
</properties>
</connector>

<transformers>
<transformer name="JMSMessageToObject"

className="org.mule.providers.jms.transformers.JMSMessageToObject"
returnClass="java.lang.String" />

<transformer name="ObjectToJMSMessage"

className="org.mule.providers.jms.transformers.ObjectToJMSMessage" />

<transformer name="XmlToDTO"
className="org.mule.transformers.xml.XmlToObject" />
<transformer name="DTO2Xml"
className="org.mule.transformers.xml.ObjectToXml" />
<transformer name="Object2String"
className="org.mule.transformers.simple.ObjectToString" />
</transformers>

<model name="default">
<mule-descriptor name="CPS"
implementation="org.mule.components.simple.BridgeComponent">
<inbound-router>

<endpoint address="jms://PM.IN"


transformers="JMSMessageToObject XmlToDTO">
<transaction
action="ALWAYS_BEGIN"

factory="org.mule.providers.jms.JmsTransactionFactory" />
</endpoint>
</inbound-router>
<outbound-router>
<router
className="org.mule.routing.outbound.ChainingRouter">

<endpoint

address="ejb://localhost:2809/ejb/test/MyTest?method=testThis" />
<endpoint address="jms://PM.OUT"
transformers="DTO2Xml ObjectToJMSMessage" remoteSync="false" />
</router>
</outbound-router>
</mule-descriptor>
</model>
</mule-configuration>


Thanks for your help

Pierre

Meunier Pierre-Emmanuel

unread,
Nov 13, 2007, 4:45:25 AM11/13/07
to us...@mule.codehaus.org
I have used the debugger to try to find out what is going on...

When I run my config without transactional support, the route method of
the ChainingRouter is called with its parameter "synchronous" set to
false. In that case, it works fine.

If I run my config with transactional support, the same route method of
the ChainingRouter is called with its "synchronous" parameter set to
true this time. In that case, the "send" method is called instead of
"dispatch" and generates the error I receive.

Any idea why the "synchronous" parameter is set to true?

Many thanks

Pierre

Meunier Pierre-Emmanuel

unread,
Nov 13, 2007, 5:40:47 AM11/13/07
to us...@mule.codehaus.org
Looking deeper and deeper at the code, I found out that in the
AbstractReceiverWork class, in the doRun method, if a transaction is
present then a synchronous flag will be set to true and send to the
outbound routers and then endpoints.

Is there any reason for this?

Andrew Perepelytsya

unread,
Nov 13, 2007, 8:47:26 AM11/13/07
to us...@mule.codehaus.org


On Nov 13, 2007 5:40 AM, Meunier Pierre-Emmanuel <pierre-emma...@lloydspharmacy.co.uk> wrote:
Looking deeper and deeper at the code, I found out that in the
AbstractReceiverWork class, in the doRun method, if a transaction is
present then a synchronous flag will be set to true and send to the
outbound routers and then endpoints.

Is there any reason for this?


Chaining router will force endpoints to be sync, as it needs to chain the results. Additionally, JMS sybsystem is giving you the correct error - there's no way you can get a reply when sending a jms message transactionally, simply because in JMS the message will never be even sent out until after the TX had been committed.

There are 2 ways to solve your problem:
  1. Use different components to implement the flow. Often you can achieve the desired effect by plugging and extra bridge instead of talking to endpoints directly. The bridge could then better control sync/async.
  2. http://mule.mulesource.org/display/MULE/JMS+Transactional+Send+All+or+Nothing+with+DLQ . The page has got the listings and compiled classes attached for a special router which may help in your case.
Andrew

Meunier Pierre-Emmanuel

unread,
Nov 13, 2007, 9:14:36 AM11/13/07
to us...@mule.codehaus.org

Hi Andrew

 

Thanks for your reply. It makes perfect sense. I assumed that the ChainingRouter would be able to handle asynchronous calls on its last endpoint.

 

Also, thanks for the possible solutions. I’ll give it a go now.

 

Mule is a great product!

 

Pierre

 


From: Andrew Perepelytsya [mailto:aper...@gmail.com]
Sent: 13 November 2007 13:47
To: us...@mule.codehaus.org
Subject: Re: [mule-user] JMS Transaction with websphere MQ

 

 

On Nov 13, 2007 5:40 AM, Meunier Pierre-Emmanuel <pierre-emma...@lloydspharmacy.co.uk> wrote:

************************************************************************

Andrew Perepelytsya

unread,
Nov 13, 2007, 9:17:16 AM11/13/07
to us...@mule.codehaus.org


Thanks for your reply. It makes perfect sense. I assumed that the ChainingRouter would be able to handle asynchronous calls on its last endpoint.

 

Pierre, it doesn't do it, as the intent is to query the last endpoint and send the results back to the caller. You can, however, set this last endpoint's sync attribute to false.

Andrew

Meunier Pierre-Emmanuel

unread,
Nov 13, 2007, 11:43:27 AM11/13/07
to us...@mule.codehaus.org

Andrew

 

It’s me again…

 

I tried to put the last endpoint’s synchronous attribute to false but it does not work. The reason is that if a transaction is present, the synchronous attribute is overridden to true (see AbstractReceiverWork.java where receiver.routeMessage(…) is called).

 

Every time that my config is using transaction, it’s failing to put the response on my jms queue due to the fact that the sync attribute is overridden (it’s trying to use the synchronous send(event) method instead of the asynchronous dispatch(event) method)

 

I also tried to use the replyTo field in my JMS message (to send the response back the my jms queue) and a custom component to do the communication with my remote session bean. Here is my config:

 

<model name="default">

            <mule-descriptor name="CPS" implementation="couk.lloyds.mule.ProfessionalServicesFacade">

                  <inbound-router>

                        <endpoint address="jms://PM.IN" responseTransformers="DTO2Xml ObjectToJMSMessage"

                              transformers="JMSMessageToObject XmlToDTO">

                              <transaction action="ALWAYS_BEGIN"

                                    factory="org.mule.providers.jms.JmsTransactionFactory" />

                        </endpoint>

                  </inbound-router>

            </mule-descriptor>

      </model>

 

 

Again it works fine when I don’t use transaction; otherwise I receive the following error:

 

javax.jms.JMSException: MQJMS1013: operation invalid whilst session is using asynchronous delivery

 

Apparently this is because the JMS spec is broken because it’s trying to send a JMS Message with a JMS session also used to receive message (from what I understood from google searches…)

 

I guess I will have to create a custom Router? Or I am doing something very stupid and I haven’t spotted it yet?

 

Any thoughs?

 

Thanks in advance for your help

 

Pierre

 


From: Andrew Perepelytsya [mailto:aper...@gmail.com]
Sent: 13 November 2007 14:17
To: us...@mule.codehaus.org
Subject: Re: [mule-user] JMS Transaction with websphere MQ

 

 

Thanks for your reply. It makes perfect sense. I assumed that the ChainingRouter would be able to handle asynchronous calls on its last endpoint.

 

Pierre, it doesn't do it, as the intent is to query the last endpoint and send the results back to the caller. You can, however, set this last endpoint's sync attribute to false.

Andrew

************************************************************************

Andrew Perepelytsya

unread,
Nov 13, 2007, 1:03:31 PM11/13/07
to us...@mule.codehaus.org
My comment referred to a more general case, it won't work in case of transactions (TX enforces sync). Sorry for confusing you.

You don't have to create a custom router, as it has already been created, check the URL I posted before.

Andrew

Yuen-Chi Lian

unread,
Nov 16, 2007, 2:11:50 AM11/16/07
to us...@mule.codehaus.org

Oh yea,

That's the point that I have missed out. If there's a Tx, Mule will
implicitly make it synchronous.

Regards,
Yuen-Chi Lian

--
View this message in context: http://www.nabble.com/JMS-Transaction-with-websphere-MQ-tf4777128.html#a13788101

Meunier Pierre-Emmanuel

unread,
Nov 23, 2007, 3:14:04 AM11/23/07
to us...@mule.codehaus.org
Thanks Andrew and Yuen-Chi for your help.

I got it working using the URL Andrew gave me:
http://mule.mulesource.org/display/MULE/JMS+Transactional+Send+All+or+No
thing+with+DLQ

Thanks again!

rletient

unread,
Nov 30, 2007, 9:21:59 AM11/30/07
to us...@mule.codehaus.org

Hello,

Have you found the solution ?
Because I have a simular problem (JmsException : MQJMS1013) in the case of
maxRedivelery property management.

--------------------------------------
My Configuration
--------------------------------------
<connector name="myQueueConnector"
className="org.mule.providers.jms.JmsConnector">
<properties>
<property name="connectionFactoryClass"
value="com.ibm.mq.jms.MQQueueConnectionFactory" />
<property name="maxRedelivery" value="1" />
<map name="connectionFactoryProperties">
<property name="hostName" value="x.x.x.x" />


<property name="port" value="xxxx" />
<property name="queueManager" value="xxxxx" />

<property name="channel" value="xxxxx" />


<property name="transportType" value="1" />
<property name="specification" value="1.1" />
</map>
</properties>

<exception-strategy
className="org.mule.impl.DefaultExceptionStrategy">
<endpoint address="jms://batchDeadLetter"
synchronous="false" remoteSync="false">
<!-- <transaction action="JOIN_IF_POSSIBLE" />-->
<properties>
<property name="reuseConsumer" value="true" />
<property name="reuseSession" value="false" />
</properties>
</endpoint>
</exception-strategy>
</connector>

----------------------------------------
My stack trace :
----------------------------------------
org.mule.umo.provider.DispatchException: Failed to route event via endpoint:
MuleEndpoint{endpointUri=jms://batchDeadLetter,
connector=JmsConnector{this=4218cb, started=true, initialised=true,
name='z2xeu1QueueConnector', disposed=false,
numberOfConcurrentTransactedReceivers=1,
createMultipleTransactedReceivers=true, connected=true,
supportedProtocols=[jms],
serviceOverrides={response.transformer=org.mule.transformers.NoActionTransformer}},
transformer=ObjectToJMSMessage{this=13c6654, name='ObjectToJMSMessage',
ignoreBadInput=false, returnClass=null, sourceTypes=[]},
name='endpoint.jms.batchDeadLetter', type='sender',
properties={reuseConsumer=true, reuseSession=false},
transactionConfig=Transaction{factory=null, action=NONE, timeout=30000},
filter=null, deleteUnacceptedMessages=false, initialised=true,
securityFilter=null, synchronous=false, initialState=started,
createConnector=0, remoteSync=false, remoteSyncTimeout=10000,
endpointEncoding=null}. Message payload is of type: ExceptionMessage
at
org.mule.providers.AbstractMessageDispatcher.send(AbstractMessageDispatcher.java:252)


at org.mule.providers.AbstractConnector.send(AbstractConnector.java:1629)
at org.mule.impl.ImmutableMuleEndpoint.send(ImmutableMuleEndpoint.java:955)
at

org.mule.impl.AbstractExceptionListener.routeException(AbstractExceptionListener.java:244)
at
org.mule.impl.DefaultExceptionStrategy.handleMessagingException(DefaultExceptionStrategy.java:30)
at
org.mule.impl.AbstractExceptionListener.exceptionThrown(AbstractExceptionListener.java:104)
at
org.mule.transaction.TransactionTemplate.execute(TransactionTemplate.java:115)
at
org.mule.providers.AbstractReceiverWorker.doRun(AbstractReceiverWorker.java:124)
at
org.mule.providers.AbstractReceiverWorker.run(AbstractReceiverWorker.java:60)
at org.mule.impl.work.WorkerContext.run(WorkerContext.java:310)
at


edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:987)
at
edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:528)

at java.lang.Thread.run(Unknown Source)
Caused by: javax.jms.JMSException: MQJMS1013: Opération incorrecte tant que
la session utilise la distribution asynchrone.
at
com.ibm.mq.jms.services.ConfigEnvironment.newException(ConfigEnvironment.java:553)
at com.ibm.mq.jms.MQMessageProducer.send(MQMessageProducer.java:1000)
at org.mule.providers.jms.Jms102bSupport.send(Jms102bSupport.java:239)
at
org.mule.providers.jms.JmsMessageDispatcher.dispatchMessage(JmsMessageDispatcher.java:273)


at
org.mule.providers.jms.JmsMessageDispatcher.doSend(JmsMessageDispatcher.java:330)
at
org.mule.providers.AbstractMessageDispatcher.send(AbstractMessageDispatcher.java:224)

... 12 more

--
View this message in context: http://www.nabble.com/JMS-Transaction-with-websphere-MQ-tf4777128.html#a14063972

Meunier Pierre-Emmanuel

unread,
Nov 30, 2007, 10:30:11 AM11/30/07
to us...@mule.codehaus.org
Look at the following URL, for XA transaction:

http://mule.mulesource.org/display/MULE/JMS+Transactional+Send+All+or+Nothing+with+DLQ

In my case (writing a reply to a JMS queue), I could also solve this problem by using a synchronous service to put the JMS message in the response queue, for example a Session Bean call which write the JMS message instead of using a JMS endpoint.

Hope that helps

-----Original Message-----
From: rletient [mailto:remy.l...@laposte.net]
Sent: 30 November 2007 14:22
To: us...@mule.codehaus.org
Subject: RE: [mule-user] JMS Transaction with websphere MQ


Hello,

http://xircles.codehaus.org/manage_email

************************************************************************
DISCLAIMER
The information contained in this e-mail is confidential and is intended
for the recipient only.
If you have received it in error, please notify us immediately by reply
e-mail and then delete it from your system. Please do not copy it or
use it for any other purposes, or disclose the content of the e-mail
to any other person or store or copy the information in any medium.
The views contained in this e-mail are those of the author and not
necessarily those of Admenta UK Group.

Admenta UK plc is a company incorporated in England and Wales
under company number 3011757 and whose registered office
is at Sapphire Court, Walsgrave Triangle, Coventry CV2 2TX
************************************************************************

---------------------------------------------------------------------

Reply all
Reply to author
Forward
0 new messages