Announcement Announcement Module
Collapse
No announcement yet.
ChannelResolutionException: no output-channel or replyChannel header available Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • ChannelResolutionException: no output-channel or replyChannel header available

    Hi everyone, I am new to spring integration and I am trying to send and recieve messages from a rabbit-mq messaging server. I keep getting the following ChannelResolutionException

    ...
    INFO: started org.springframework.integration.endpoint.EventDriv enConsumer@1bbd3e2
    01-Feb-2011 12:05:36 org.springframework.amqp.rabbit.listener.AbstractM essageListenerContainer invokeErrorHandler
    WARNING: Execution of Rabbit message listener failed, and no ErrorHandler has been set.
    org.springframework.integration.support.channel.Ch annelResolutionException: no output-channel or replyChannel header available
    at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.sendReplyMessage(Abstra ctReplyProducingMessageHandler.java:166)
    at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.produceReply(AbstractRe plyProducingMessageHandler.java:125)
    at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.handleResult(AbstractRe plyProducingMessageHandler.java:119)
    at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.handleMessageInternal(A bstractReplyProducingMessageHandler.java:101)
    at org.springframework.integration.handler.AbstractMe ssageHandler.handleMessage(AbstractMessageHandler. java:78)
    at org.springframework.integration.dispatcher.Unicast ingDispatcher.doDispatch(UnicastingDispatcher.java :110)
    at org.springframework.integration.dispatcher.Unicast ingDispatcher.dispatch(UnicastingDispatcher.java:9 7)
    at org.springframework.integration.channel.AbstractSu bscribableChannel.doSend(AbstractSubscribableChann el.java:44)
    at org.springframework.integration.channel.AbstractMe ssageChannel.send(AbstractMessageChannel.java:157)
    at org.springframework.integration.channel.AbstractMe ssageChannel.send(AbstractMessageChannel.java:128)
    at org.springframework.integration.core.MessagingTemp late.doSend(MessagingTemplate.java:288)
    at org.springframework.integration.core.MessagingTemp late.send(MessagingTemplate.java:149)
    at org.springframework.integration.endpoint.MessagePr oducerSupport.sendMessage(MessageProducerSupport.j ava:92)
    at org.springframework.integration.amqp.AmqpInboundEn dpoint.access$000(AmqpInboundEndpoint.java:34)
    at org.springframework.integration.amqp.AmqpInboundEn dpoint$1.onMessage(AmqpInboundEndpoint.java:55)
    at org.springframework.amqp.rabbit.listener.AbstractM essageListenerContainer.doInvokeListener(AbstractM essageListenerContainer.java:298)
    at org.springframework.amqp.rabbit.listener.AbstractM essageListenerContainer.invokeListener(AbstractMes sageListenerContainer.java:246)
    at org.springframework.amqp.rabbit.listener.AbstractM essageListenerContainer.doExecuteListener(Abstract MessageListenerContainer.java:222)
    at org.springframework.amqp.rabbit.listener.AbstractM essageListenerContainer.executeListener(AbstractMe ssageListenerContainer.java:192)
    at org.springframework.amqp.rabbit.listener.SimpleMes sageListenerContainer$AsyncMessageProcessingConsum er.receiveAndExecute(SimpleMessageListenerContaine r.java:388)
    at org.springframework.amqp.rabbit.listener.SimpleMes sageListenerContainer$AsyncMessageProcessingConsum er.run(SimpleMessageListenerContainer.java:307)
    at java.lang.Thread.run(Thread.java:619)
    01-Feb-2011 12:05:36 org.springframework.amqp.rabbit.listener.SimpleMes sageListenerContainer$AsyncMessageProcessingConsum er run
    INFO: Closing consumer on channel: AMQChannel(amqp://[user]@[host]:[port]/,1)

    My inbound channel adapter is configured as follows:

    HTML Code:
    <amqp:inbound-channel-adapter queue-name="[valid-queue-name]" channel="httpResponseChannel" connection-factory="rabbitConnectionFactory" />
    Can anyone explain to me what is going on? Or maybe even what i need to do to get past this? I can submit more of the applicationContext.xml or provide more information if you need. At the moment I'm not sure what is wrong so I'm not sure what would help.

    Thanks in advance
    Last edited by k9000; Feb 1st, 2011, 09:12 AM. Reason: removed potentially sensitive information

  • #2
    You have an inbound-adapter which is unidirectional but you seem to have an endpoint downstream that produces reply and since reply channel is not available (not defined) you see this exception.
    Could you provide more of your configuration?

    Comment


    • #3
      Ok, here is everything...

      HTML Code:
      	<int-http:inbound-gateway 
      		id="httpInboundGateway" 
      		request-channel="httpRequestChannel"
      		supported-methods="POST"
      		name="/hello/"
      		reply-channel="httpResponseChannel" />
      
      	<int:channel id="httpRequestChannel" />
      
      	<bean id="httpRequestExtractor" class="com.idna.commandprocessor.message.serviceactivator.HttpRequestExtractor" />
      
      	<int:service-activator 
      		output-channel="messageOutputChannel" 
      		input-channel="httpRequestChannel" 
      		method="getRequest" 
      		ref="httpRequestExtractor" />
      
      	<int:channel id="messageOutputChannel" />
      
      	<amqp:outbound-channel-adapter channel="messageOutputChannel" exchange-name="[valid-exchange]" routing-key="[valid-routing-key]" amqp-template="rabbitRequestTemplate" />
      
      	<amqp:inbound-channel-adapter queue-name="[valid-queue]" channel="httpResponseChannel" connection-factory="rabbitConnectionFactory" />
      
      	<int:channel id="httpResponseChannel" />
      
      	<bean id="rabbitRequestTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate" >
      		<constructor-arg ref="rabbitConnectionFactory" />
      	</bean>
      	
      	<bean id="rabbitConnectionFactory" class="org.springframework.amqp.rabbit.connection.SingleConnectionFactory" >
      		<constructor-arg value="[host]" />
      		<property name="port" value="[port]" />
      		<property name="username" value="[username]" />
      		<property name="password" value="[password]" />
      	</bean>

      Comment


      • #4
        I'll try to reproduce your error today and let you know.

        Comment


        • #5
          Hi Helena,

          I havn't heard anything back from you so I thought I post a bit more, see below for the HttpRequestExtractor class, maybe this will help?

          Code:
          public class HttpRequestExtractor {
          
              public Message<String> getRequest(Message<?> message) {
                  @SuppressWarnings("unchecked")
                  LinkedMultiValueMap<String, Object> httpReqestParameters = (LinkedMultiValueMap<String, Object>)message.getPayload();
                  return MessageBuilder.withPayload(httpReqestParameters.get("message").get(0).toString()).copyHeaders(message.getHeaders()).build();
              }
              
          }

          Comment


          • #6
            When using gateways we auto-create create a reply-channel and set it as MessageHeader - 'replyChannel'. If user specifies its own reply-channel, then we are creating a Bridge which correlates the user defined channel and the auto-created channel. However, since you are using outbound/inbound adapters, the original 'replyChannel' header is lost once the inbound-adapter receives a message, so when the message is sent to 'httpResponseChannel' BridgeHandler attempts to retrieve 'replyChannel' from the header and since its not there it throws exception.

            Ideally for this to work we need AMQP Inbound/Outbound Gateway (not just adapters) which we don't have yet.
            I've created a JIRA https://jira.springsource.org/browse/AMQP-98

            Let me see if I can figure out an interim solution

            Comment


            • #7
              Thanks a million, I was starting to get really worried about this.

              Comment


              • #8
                I don't think the problem is to do with the AMQP adapter because I don't think the use case here is bidirectional for either of the amqp adapters. An outbound gateway might be a neat way to avoid having two adapters, but that's a different question I think.

                The inbound adapter is doing its job, and sending a message downstream for processing. It's downstream that the error is occurring. However it's a bit hard to correlate the stack trace with your configuration: the http gateway should have already complained that its reply-channel was not pollable; and the amqp-inbound-adapter sends its messages to a direct channel that has no endpoint attached (except the http one that shouldn't be working). If anything I would expect the dispatcher in that channel to be the first one to complain ("Dispatcher has no subscribers").

                Are we seeing everything?

                Comment


                • #9
                  Dave, yes we are seeing everything.
                  As i described earlier, the problem is with the gateway and the fact that it generates BridgeHandler every time user explicitly specifies reply-channel or default-reply-channel. Once that happens, BridgeHandler attempts to bridge user defined reply-channel with auto-created replyChannel which is injected into MessageHeaders by the gateway, but is lost in the remote adapters. Its not just AMQP. You can model this with any combination of outbound/inbound adapters.
                  Code:
                  if (this.replyChannel != null && this.replyMessageCorrelator == null) {
                  	this.registerReplyMessageCorrelator();
                  }
                  . . . .
                  private void registerReplyMessageCorrelator() {
                  . . . .
                     MessageHandler handler = new BridgeHandler();
                     if (this.replyChannel instanceof SubscribableChannel) {
                  	correlator = new EventDrivenConsumer(
                  			(SubscribableChannel) this.replyChannel, handler);
                     }
                  . . .
                  }
                  Last edited by oleg.zhurakousky; Feb 3rd, 2011, 11:09 AM.

                  Comment


                  • #10
                    Which gateway do you think is throwing the exception in this case then (would be nice if the stack trace would tell us, but don't get me started)?

                    Comment


                    • #11
                      Think? I know which one

                      The one that is an entry point of the flow. So in the above case its HTTP Inbound Gateway, but you can easily substitute it with the regular gateway and you'll get the same thing

                      Comment


                      • #12
                        I just committed the initial version of an AMQP 'outbound-gateway' in the sandbox. I moved the issue from the Spring AMQP project to the Spring Integration project. Here's the new link:
                        https://jira.springsource.org/browse/INT-1780

                        You can find a really simple example here:
                        http://git.springsource.org/spring-i...d9772000ac3494

                        I also updated the spring-amqp dependency to 1.0.0.M2 now that it has been released.

                        Please re-build, try it, and let us know how it goes.

                        Thanks!
                        -Mark

                        Comment

                        Working...
                        X