Announcement Announcement Module
Collapse
No announcement yet.
"no output-channel ..." when using jms channels instead of standard channels Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • "no output-channel ..." when using jms channels instead of standard channels

    Hi,

    I have the problem that I'm getting an "no output-channel or replyChannel header available" when I use JMS backed message channels instead of the standard channels.

    I basically have a gateway, which puts a request into the request channel. This one is then read by the service-activator, which executes a simple batch job and puts the return code into the reply channel. The reply channel is read by the gateway, which then returns the result.

    The normal, working configuration looks like this:
    Code:
      <int:channel id="dynamic.channel.select.request.channel" />
      <int:channel id="dynamic.channel.select.reply.channel" />
        
      <int:gateway id="dynamic.channel.select.gateway" 
                   service-interface="ch.mobi.batch.poc.dynamicbatch.job.integration.activation.JobActivatorInterface"
                   default-request-channel="dynamic.channel.select.request.channel" 
                   default-reply-channel="dynamic.channel.select.reply.channel"/>
        
      <int:service-activator input-channel="dynamic.channel.select.request.channel" 
                             output-channel="dynamic.channel.select.reply.channel">
        <bean class="ch.mobi.batch.poc.dynamicbatch.job.integration.activation.JobActivator">
          <property name="jobName" value="dynamic.channel.select.job" />
        </bean>
      </int:service-activator>
    This works with pure channels.

    My problem is, that when I change the channels to jms backed channels with this configuration (note: nothing else is changed beside adding the ConnectionFactory for the HornetQ)

    Code:
      <int-jms:channel id="dynamic.channel.select.request.channel" queue-name="jms.channel.select.request" />
      <int-jms:channel id="dynamic.channel.select.reply.channel" queue-name="jms.channel.select.reply" />
    I'm getting the mentioned exception. The whole code is still running in the same VM. The queue system is a standalone hornetq instance.

    When I debug the flow of the message, I can see, that the request message is put in the request channel and is recieved by the service activator. The service activator executes its task and creates the reply message. The reply message is sent to the reply queue as well (I can see it in my amdin console of the queue server).

    In the stacktrace, I can also see, that a DefaultMesssageListenerContainer$AsyncMessageListe nerInvoker (listening to the reply queue) is being invoked as soon as the reply message arrives.

    Code:
    Thread [DefaultMessageListenerContainer-1] (Suspended)	
    	BridgeHandler(AbstractReplyProducingMessageHandler).sendReplyMessage(Message<?>, Object) line: 165	
    	BridgeHandler(AbstractReplyProducingMessageHandler).produceReply(Object, MessageHeaders) line: 124	
    	BridgeHandler(AbstractReplyProducingMessageHandler).handleResult(Object, MessageHeaders) line: 118	
    	BridgeHandler(AbstractReplyProducingMessageHandler).handleMessageInternal(Message<?>) line: 100	
    	BridgeHandler(AbstractMessageHandler).handleMessage(Message<?>) line: 73	
    	UnicastingDispatcher.doDispatch(Message<?>) line: 114	
    	UnicastingDispatcher.dispatch(Message<?>) line: 101	
    	SubscribableJmsChannel$DispatchingMessageListener.onMessage(Message) line: 116	
    	DefaultMessageListenerContainer(AbstractMessageListenerContainer).doInvokeListener(MessageListener, Message) line: 560	
    	DefaultMessageListenerContainer(AbstractMessageListenerContainer).invokeListener(Session, Message) line: 498	
    	DefaultMessageListenerContainer(AbstractMessageListenerContainer).doExecuteListener(Session, Message) line: 467	
    	DefaultMessageListenerContainer(AbstractPollingMessageListenerContainer).doReceiveAndExecute(Object, Session, MessageConsumer, TransactionStatus) line: 325	
    	DefaultMessageListenerContainer(AbstractPollingMessageListenerContainer).receiveAndExecute(Object, Session, MessageConsumer) line: 263	
    	DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener() line: 1058	
    	DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop() line: 1050	
    	DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run() line: 947	
    	Thread.run() line: 619
    Does anybody know, what I'm doing wrong?

    Thanks
    Hansjoerg

  • #2
    You are not doing anything wrong per se; this is a limitation of using persistent channels in a flow; the flow won't work if it starts with a gateway. The problem is that the calling thread is waiting on a live java object (a temporary reply channel); since we can't persist that to JMS, the header containing a reference to the reply channel is lost; it is stripped by the serialization process. When the final consumer is done with the message, there is nowhere to send it. You can't send it explicitly to the gateway's reply channel because that channel gets bridged to the reply channel header, which is no longer there.

    When using JMS-backed channels (or any persistent channels), you need to use an asynch model - for example, a gateway method that returns void, and a service activator that sends the reply to your application - the application is responsible to correlate responses to requests.

    When not using persistent channels, the gateway can perform the correlation, by means of the reply channel object in the message header.

    Hope that helps.

    Comment

    Working...
    X