Announcement Announcement Module
Collapse
No announcement yet.
Propagate Exception message in to a error channhel Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Propagate Exception message in to a error channhel

    Hi Guys,

    i know this question is a very very basic fundamental concept in spring integration. but i got little confused about it. hope u guys can help me to figure it out.

    i have a inbound file adapter like this

    Code:
    <int-file:inbound-channel-adapter id="filesIn" 
                                                  channel="filesReaderChannel" 
                                                  directory="file:D:/bsharp_projects/files/inbound" 
                                                  prevent-duplicates="true" 
                                                  auto-startup="true">
                  <int:poller fixed-rate="10000"/>
    </int-file:inbound-channel-adapter>
    
    <int:channel id="filesReaderChannel"/>
    and another jms event driven adapter like this

    Code:
     <int-jms:message-driven-channel-adapter id="jmsIn"
        			                        	  connection-factory="jms.connectionFactory"
        							  destination="jms.inbound.msgQueue"
       				 			  channel="bstXMLValidatorInChannel" 
       				 			  auto-startup="false"/>
    
    <int:channel id="bstXMLValidatorInChannel"/>
    and i am using a control bus to start these components when ever needs.

    then i am using the error channel to monitor the exceptions. but only the file inbound related exceptions are coming through the error channel, not the jms related ones. it seems JMS related ones are propagated back to the sender.

    in document it says

    Code:
    When sending a Message to a channel, the component that ultimately handles that Message may or may not be operating within the same thread as the sender. If using a simple default DirectChannel (with the <channel> element that has no <queue> sub-element and no 'task-executor' attribute), the Message-handling will occur in the same thread as the Message-sending. In that case, if an Exception is thrown, it can be caught by the sender (or it may propagate past the sender if it is an uncaught RuntimeException). So far, everything is fine. This is the same behavior as an Exception-throwing operation in a normal call stack. However, when adding the asynchronous aspect, things become much more complicated. For instance, if the 'channel' element does provide a 'queue' sub-element, then the component that handles the Message will be operating in a different thread than the sender. The sender may have dropped the Message into the channel and moved on to other things. There is no way for the Exception to be thrown directly back to that sender using standard Exception throwing techniques. Instead, to handle errors for asynchronous processes requires an asynchronous error-handling mechanism as well.
    in i can not understand how file inbound become asynchronous and jms become synchronous. can you huys pls help me to understand this scenario?

    thanks,
    kelum

  • #2
    Hi!
    Well, let me guess: your error channel has a name exactly "errorChannel".
    As you can see there is some difference in the configuration of <file:inbound-channel-adapter> & <jms:message-driven-channel-adapter>.
    Ther first one has a <poller>, but the second doesn't: it is a MessageListener in general.
    So, <poller> uses some ThreadPoolTaskScheduler with MessagePublishingErrorHandler to schedule the polling task from trigger config.
    In this case it will be a new Thread and there is no any ability to propagate Exception to the sender: he is just a task on the Scheduler. There is no sender at all!

    From other side: JMS Listener just connects to the broker via connection-factory. So, it has its own thread to receive messages, but it heppens via broker initiative. So, your Exception will be thrown to the broker at the same thread.

    Change your <jms:message-driven-channel-adapter> to the <jms:inbound-channel-adapter> and you'll get the same behaviour.


    HTH

    Artem

    Comment


    • #3
      Hello Artem,

      thanks for the reply.

      if we use <jms:inbound-channel-adapter>, we need to configure a poller as well right? as we did for file inbound.

      how about adding error-channel attribute to <jms:message-driven-channel-adapter> like follows

      Code:
      <int-jms:message-driven-channel-adapter id="jmsIn"
          			                        	connection-factory="jms.connectionFactory"
          										destination="jms.inbound.msgQueue"
         				 							channel="bstXMLValidatorInChannel" 
         				 							auto-startup="false"
         				 							error-channel="errorChannel"/>
      thanks
      kelumt

      Comment


      • #4
        how about adding error-channel
        Good catch!
        Does it work as you expected?

        Comment


        • #5
          There is an error-channel attribute on 'message-driven-channel-adapter'
          Code:
          <xsd:attribute name="error-channel" type="xsd:string">
          . . . .
          <xsd:documentation>
          If a (synchronous) downstream exception is thrown and an error-channel is specified,
          the MessagingException will be sent to this channel. Otherwise, any such exception
          will be propagated to the listener container and any JMS transaction will be
          rolled back. Any synchronous downstream exceptions in the error flow will
          also cause any JMS transaction to be rolled back.
          </xsd:documentation>

          Comment


          • #6
            Hello Artem and Oleg,

            yes it is working as expected. thanks guys for your help.

            but one more small question, since message driven adapters and all downstream components operates in same thread, how it works with this error channel. Can you please explain the theory behind it and what is the difference between asynchronous pooling adapters

            thanks,
            kelum

            Comment


            • #7
              Hi!
              how it works with this error channel
              Shortly:
              Here ChannelPublishingJmsMessageListener#onMessage:
              Code:
              this.gatewayDelegate.send(requestMessage);
              And further MessagingGatewaySupport#send

              So, as you can see JmsMessageDrivenEndpoint in the end invokes some method which catch the Exception and tries to recover the problem from original massage flow. The downstream error-flow is at the same Thread (except in the case your error-channel is a PollableChannel).
              The idea here is to use some gateway ability to allow do not send Exception back to the JMS Broker.
              There are several similar Endpoint components which connect to external system and have 'error-channel' to make recovery at the same Thread.
              From other side pooling means unidirectional flow, when the initiator of it is your application via TaskScheduler. So, the Exception in this case just break the Thread. That's why we provide a hook in the person of 'error-channel' for polling adapters.

              Is it clear?
              I'll be glad if Oleg provides other thoughts

              Comment

              Working...
              X