Announcement Announcement Module
Collapse
No announcement yet.
In my example how to handle errors with agregator ? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • In my example how to handle errors with agregator ?

    Hello,

    I have some problems to understand and to be able to manage error handling with Spring integration, especially with agregator.

    In the following example, I expose a servlet, send Json in the request content, transform it as object input, parallelize 3 calls (one raise errors), aggregate the results and return a json representation of an account list.

    My XML config :

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:si="http://www.springframework.org/schema/integration"
    	xmlns:int="http://www.springframework.org/schema/integration"
    	xmlns:task="http://www.springframework.org/schema/task"
    	xmlns:int-http="http://www.springframework.org/schema/integration/http"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
    		http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http-2.0.xsd
    		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
    
    	<!--==============-->
    	<!-- Channels     -->
    	<!--==============-->
    	
    	<si:channel id="input" />
    	<si:channel id="transformedInput" datatype="google.il.share.dto.Input"/>
    	<si:channel id="outputAggregator" />
    	<si:channel id="channel2Pivot" />
    	<si:channel id="outputPivot"/>
    	<si:channel id="output" />
    		
    	<int:channel id="channel1">	
    		<int:dispatcher task-executor="executor"/>
    	</int:channel>
    	
    	<int:channel id="channel2" >
    		<int:dispatcher task-executor="executor"/>
    	</int:channel>
    	
    	<int:channel id="channel3" >
    		<int:dispatcher task-executor="executor" />
    	</int:channel>
    		
    	<task:executor id="executor" pool-size="5" keep-alive="5"/>
    
    	<!--==============-->
    	<!-- Gateways     -->
    	<!--==============-->
    	
    	<bean id="inboundGateway" class="google.blank.springintegration.tutorial.http.HttpGateway" >
    		<property name="requestChannel" ref="input" />
    		<property name="replyChannel" ref="outputAggregator" />
    		<property name="requestPayloadType" value="java.lang.String" />
    		<property name="replyTimeout" value="10000"></property>
    <!-- 		<property name="errorChannel" ref="exceptionTransformationChannel"></property> -->
    	</bean>
    	
    <!-- 	<si:channel id="exceptionTransformationChannel" />
    	<int:transformer input-channel="exceptionTransformationChannel"
            ref="exceptionTransformer" method="handleError" output-channel="output"/> -->
        
    	<!--==============-->
    	<!-- Activators   -->
    	<!--==============-->
    	
     	<si:service-activator input-channel="channel1" output-channel="output" ref="serviceFacade1" method="getAccounts" />		
    	<si:service-activator input-channel="channel2" output-channel="outputPivot" ref="serviceFacade1" method="getAccountsBis" />	
     	<si:service-activator input-channel="channel3" output-channel="output" ref="serviceFacade1" method="getAccountsWithFailure" />
    	
    	<!--==============-->
    	<!-- Facades      -->
    	<!--==============-->
    	
    	<bean id="serviceFacade1" class="google.il.impl.ServiceFacadeImpl" />
    
    	<!--==============-->
    	<!-- Transformers -->
    	<!--==============-->
    	<bean id="exceptionTransformer" class="google.blank.springintegration.tutorial.http.ExceptionTransformer" />
    	
    	<int:json-to-object-transformer input-channel="input" output-channel="transformedInput" type="google.il.share.dto.Input" />	
    	
    	<int:transformer id="testTransformer" ref="testTransformerBean" input-channel="outputPivot"
                 method="transform" output-channel="output"/>
    	
    	<bean id="testTransformerBean" class="google.blank.springintegration.tutorial.http.TestTransformer" />
    	
    	<int:transformer id="inputTransformer" ref="inputTransformerBean" input-channel="channel2Pivot"
                 method="transform" output-channel="channel2"/>
    	
    	<bean id="inputTransformerBean" class="google.blank.springintegration.tutorial.http.InputTransformer" />
    
    	<!--==============-->
    	<!-- Routers 	  -->
    	<!--==============-->
    	
    	<int:recipient-list-router id="customRouter" input-channel="transformedInput" apply-sequence="true">
    		<int:recipient channel="channel1" />
    		<int:recipient channel="channel2Pivot" />
    		 <int:recipient channel="channel3" />
    	</int:recipient-list-router>
    
    	<!--==============-->
    	<!-- Aggregators  -->
    	<!--==============-->
    			
    	<int:aggregator input-channel="output" output-channel="outputAggregator" method="aggregate" ref="resultAggregator" 		
    		release-strategy-expression="#root.size() eq 3"/>	
    	
    	<bean id="resultAggregator" class="google.blank.springintegration.tutorial.http.ResultAggregator"/>	
    	
    </beans>
    The serviceFacade1 is called with 3 methods that return List of Accounts. One of those methods raises an exception, like this :

    Code:
    ...
    	@Override
    	public List<AccountDto> getAccountsWithFailure(Input input) throws MyBusinessException {
    		long threadId = Thread.currentThread().getId();
    		System.out.println("getAccountsWithFailure on thread id: "+ threadId + " - " + Thread.currentThread().getName());
    		throw new MyBusinessException("I am the MyBusinessException....huhhuuuu");
    	}
    ...
    When I execute my client, it returns an errors like this :

    Code:
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
    <title>Error 500 google.il.share.facade.MyBusinessException: I am the MyBusinessException....huhhuuuu</title>
    </head>
    <body><h2>HTTP ERROR: 500</h2><pre>google.il.share.facade.MyBusinessException: I am the MyBusinessException....huhhuuuu</pre>
    <p>RequestURI=/inboundGateway</p><h3>Caused by:</h3><pre>org.springframework.integration.MessageHandlingException: google.il.share.facade.MyBusinessException: I am the MyBusinessException....huhhuuuu
    	at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:76)
    	at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:67)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:134)
    	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:115)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.access$000(UnicastingDispatcher.java:52)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher$1.run(UnicastingDispatcher.java:97)
    	at org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:52)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    	at java.lang.Thread.run(Thread.java:662)
    Caused by: google.il.share.facade.MyBusinessException: I am the MyBusinessException....huhhuuuu
    	at google.il.impl.ServiceFacadeImpl.getAccountsWithFailure(ServiceFacadeImpl.java:64)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:69)
    	at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:110)
    	at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:57)
    	at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:102)
    	at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:102)
    	at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:126)
    	at org.springframework.integration.util.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:227)
    	at org.springframework.integration.util.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:127)
    	at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:73)
    	... 10 more
    </pre>
    <h3>Caused by:</h3><pre>google.il.share.facade.MyBusinessException: I am the MyBusinessException....huhhuuuu
    	at google.il.impl.ServiceFacadeImpl.getAccountsWithFailure(ServiceFacadeImpl.java:64)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    ...
    ...
    ...
    I would like to return the aggregation of getAccounts and getAccountsBis even if there is an exception inside getAccountsWithFailure.

    How is it possible ?

    Additionnaly, all advices are welcome because I am newbie with Spring Integration.

    Thx by advance.
    Eric

  • #2
    I am not familiar with "google.blank.springintegration.tutorial.http.Http Gateway"

    Why don't you use the framework's <int-http:inbound-gateway/> ?

    However, you have the error-chanel commented out, which is why you're not getting the expected results...

    <!-- <property name="errorChannel" ref="exceptionTransformationChannel"></property> -->

    Comment


    • #3
      Originally posted by Gary Russell View Post
      I am not familiar with "google.blank.springintegration.tutorial.http.Http Gateway"

      Why don't you use the framework's <int-http:inbound-gateway/> ?

      However, you have the error-chanel commented out, which is why you're not getting the expected results...
      :-) Sorry but google.blank.springintegration.tutorial.http.HttpG ateway only extends org.springframework.integration.http.inbound.HttpR equestHandlingMessagingGateway , it was for debugging purpose.

      What is the differences between <int-http:inbound-gateway/> and org.springframework.integration.http.inbound.HttpR equestHandlingMessagingGateway ( described here http://static.springsource.org/sprin.../#http-inbound )

      Yes the error-chanel is commented because it was not working as I want, the Message containing the payload exception is correctly sent to the transformer but after I really don't know what to do...

      Any idea ?

      Comment


      • #4
        What is the difference...
        It's the same thing; the namespace is just a convenience and more concise http://static.springsource.org/sprin...http-namespace

        The transformer gets an ErrorMessage; the payload is a MessagingException with two properties "failedMessage" and "cause" (the exception).

        It can simply transform this into some error message and forward it to the aggregator, perhaps something as simple as

        Code:
        <int:transformer input-channel="exceptionTransformationChannel"
            output-channel="output"
            expression="payload.cause.message" />
        But if you want to include data from the failed message, you might want extra code in your "exceptionTransformer".

        Comment


        • #5
          When I add :

          <int:transformer input-channel="exceptionTransformationChannel"
          output-channel="output"
          expression="payload.cause.message" />
          I receive the following error : Null correlation not allowed. Maybe the CorrelationStrategy is failing?

          My aggregator aggregates List of accounts.

          See the stacktrace :

          <html>
          <head>
          <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
          <title>Error 500 failure occurred in error-handling flow</title>
          </head>
          <body><h2>HTTP ERROR: 500</h2><pre>failure occurred in error-handling flow</pre>
          <p>RequestURI=/inboundGateway</p><h3>Caused by:</h3><pre>org.springframework.integration.MessagingE xception: failure occurred in error-handling flow
          at org.springframework.integration.gateway.MessagingG atewaySupport.doSendAndReceive(MessagingGatewaySup port.java:252)
          at org.springframework.integration.gateway.MessagingG atewaySupport.sendAndReceiveMessage(MessagingGatew aySupport.java:207)
          at org.springframework.integration.http.inbound.HttpR equestHandlingEndpointSupport.actualDoHandleReques t(HttpRequestHandlingEndpointSupport.java:406)
          at org.springframework.integration.http.inbound.HttpR equestHandlingEndpointSupport.doHandleRequest(Http RequestHandlingEndpointSupport.java:327)
          at org.springframework.integration.http.inbound.HttpR equestHandlingMessagingGateway.handleRequest(HttpR equestHandlingMessagingGateway.java:101)
          at org.springframework.web.context.support.HttpReques tHandlerServlet.service(HttpRequestHandlerServlet. java:67)
          at javax.servlet.http.HttpServlet.service(HttpServlet .java:831)
          at org.mortbay.jetty.servlet.ServletHolder.handle(Ser vletHolder.java:487)
          at org.mortbay.jetty.servlet.ServletHandler$CachedCha in.doFilter(ServletHandler.java:1097)
          at lu.google.blank.springintegration.tutorial.http.De bugFilter.doFilter(DebugFilter.java:21)
          at org.mortbay.jetty.servlet.ServletHandler$CachedCha in.doFilter(ServletHandler.java:1088)
          at lu.fwk.rsa.gwt.facade.server.spring.LocaleFilter.d oFilter(LocaleFilter.java:62)
          at org.mortbay.jetty.servlet.ServletHandler$CachedCha in.doFilter(ServletHandler.java:1088)
          at com.google.rsa.context.web.ContextManagerServletFi lter.doFilter(ContextManagerServletFilter.java:66)
          at org.mortbay.jetty.servlet.ServletHandler$CachedCha in.doFilter(ServletHandler.java:1088)
          at lu.fwk.rsa.icc.security.filter.IccSecurityFilter.d oFilterChain(IccSecurityFilter.java:263)
          at lu.fwk.rsa.icc.security.filter.IccSecurityFilter.d oHttpFilter(IccSecurityFilter.java:248)
          at lu.fwk.rsa.icc.security.filter.IccSecurityFilter.d oFilter(IccSecurityFilter.java:237)
          at org.springframework.web.filter.DelegatingFilterPro xy.invokeDelegate(DelegatingFilterProxy.java:237)
          at org.springframework.web.filter.DelegatingFilterPro xy.doFilter(DelegatingFilterProxy.java:167)
          at org.mortbay.jetty.servlet.ServletHandler$CachedCha in.doFilter(ServletHandler.java:1088)
          at com.google.rsa.securitymanager.SecurityManagerServ letFilter.doFilter(SecurityManagerServletFilter.ja va:75)
          at org.mortbay.jetty.servlet.ServletHandler$CachedCha in.doFilter(ServletHandler.java:1088)
          at com.google.rsa.commons.http.SessionLostFilter.doFi lter(SessionLostFilter.java:47)
          at org.mortbay.jetty.servlet.ServletHandler$CachedCha in.doFilter(ServletHandler.java:1088)
          at com.google.rsa.commons.loadbalancer.LoadBalancerFi lter.doFilterInternal(LoadBalancerFilter.java:212)
          at com.google.rsa.commons.loadbalancer.LoadBalancerFi lter.doFilter(LoadBalancerFilter.java:102)
          at org.mortbay.jetty.servlet.ServletHandler$CachedCha in.doFilter(ServletHandler.java:1088)
          at org.mortbay.jetty.servlet.ServletHandler.handle(Se rvletHandler.java:360)
          at org.mortbay.jetty.security.SecurityHandler.handle( SecurityHandler.java:216)
          at org.mortbay.jetty.servlet.SessionHandler.handle(Se ssionHandler.java:181)
          at org.mortbay.jetty.handler.ContextHandler.handle(Co ntextHandler.java:729)
          at org.mortbay.jetty.webapp.WebAppContext.handle(WebA ppContext.java:405)
          at org.mortbay.jetty.handler.HandlerWrapper.handle(Ha ndlerWrapper.java:152)
          at org.mortbay.jetty.Server.handle(Server.java:324)
          at org.mortbay.jetty.HttpConnection.handleRequest(Htt pConnection.java:505)
          at org.mortbay.jetty.HttpConnection$RequestHandler.co ntent(HttpConnection.java:843)
          at org.mortbay.jetty.HttpParser.parseNext(HttpParser. java:647)
          at org.mortbay.jetty.HttpParser.parseAvailable(HttpPa rser.java:211)
          at org.mortbay.jetty.HttpConnection.handle(HttpConnec tion.java:380)
          at org.mortbay.jetty.bio.SocketConnector$Connection.r un(SocketConnector.java:228)
          at org.mortbay.thread.QueuedThreadPool$PoolThread.run (QueuedThreadPool.java:488)
          Caused by: org.springframework.integration.MessageHandlingExc eption: error occurred in message handler [org.springframework.integration.aggregator.Aggrega tingMessageHandler#0]
          at org.springframework.integration.handler.AbstractMe ssageHandler.handleMessage(AbstractMessageHandler. java:79)
          at org.springframework.integration.dispatcher.Unicast ingDispatcher.doDispatch(UnicastingDispatcher.java :115)
          at org.springframework.integration.dispatcher.Unicast ingDispatcher.dispatch(UnicastingDispatcher.java:1 02)
          at org.springframework.integration.channel.AbstractSu bscribableChannel.doSend(AbstractSubscribableChann el.java:77)
          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.handler.AbstractRe plyProducingMessageHandler.sendMessage(AbstractRep lyProducingMessageHandler.java:216)
          at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.sendReplyMessage(Abstra ctReplyProducingMessageHandler.java:200)
          at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.produceReply(AbstractRe plyProducingMessageHandler.java:165)
          at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.handleResult(AbstractRe plyProducingMessageHandler.java:159)
          at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.handleMessageInternal(A bstractReplyProducingMessageHandler.java:141)
          at org.springframework.integration.handler.AbstractMe ssageHandler.handleMessage(AbstractMessageHandler. java:73)
          at org.springframework.integration.dispatcher.Unicast ingDispatcher.doDispatch(UnicastingDispatcher.java :115)
          at org.springframework.integration.dispatcher.Unicast ingDispatcher.dispatch(UnicastingDispatcher.java:1 02)
          at org.springframework.integration.channel.AbstractSu bscribableChannel.doSend(AbstractSubscribableChann el.java:77)
          at org.springframework.integration.channel.AbstractMe ssageChannel.send(AbstractMessageChannel.java:157)
          at org.springframework.integration.core.MessagingTemp late.doSend(MessagingTemplate.java:288)
          at org.springframework.integration.core.MessagingTemp late.doSendAndReceive(MessagingTemplate.java:318)
          at org.springframework.integration.core.MessagingTemp late.sendAndReceive(MessagingTemplate.java:239)
          at org.springframework.integration.gateway.MessagingG atewaySupport.doSendAndReceive(MessagingGatewaySup port.java:249)
          ... 41 more
          Caused by: java.lang.IllegalStateException: Null correlation not allowed. Maybe the CorrelationStrategy is failing?
          at org.springframework.util.Assert.state(Assert.java: 384)
          at org.springframework.integration.aggregator.Abstrac tCorrelatingMessageHandler.handleMessageInternal(A bstractCorrelatingMessageHandler.java:211)
          at org.springframework.integration.handler.AbstractMe ssageHandler.handleMessage(AbstractMessageHandler. java:73)
          ... 62 more
          Any ideas ?

          Comment


          • #6
            Ah yes - your transformer also needs to copy the correlationId from the payload.failedMessage to the ErrorMessage.

            The ErrorMessage is a new message and doesn't inherit the headers from the failed message.

            Or, you can do it with a <header-enricher/> before the transformer
            Code:
            <int:header-enricher ...>
                <int:correlation-id expression="payload.failedMessage.headers.correlationId" />
            </int:header-enricher>

            Comment


            • #7
              Now I have this ( u will see ... in the stackstrace because the present message length was reached ):

              Code:
              ...
               	<si:channel id="exceptionTransformationChannel" />
              
              	<int:transformer input-channel="exceptionTransformationChannel" output-channel="output" expression="payload.cause.message" />
              
              	<int:header-enricher input-channel="exceptionTransformationChannel" output-channel="output">
                  	<int:correlation-id expression="payload.failedMessage.headers.correlationId" />
              	</int:header-enricher>
              ...
              And now I have the following exception :

              Code:
              org.springframework.integration.MessagingException: failure occurred in error-handling flow
              	at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:252)
              	at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:207)
              	at org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.actualDoHandleRequest(HttpRequestHandlingEndpointSupport.java:406)
              	at org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.doHandleRequest(HttpRequestHandlingEndpointSupport.java:327)
              	at org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway.handleRequest(HttpRequestHandlingMessagingGateway.java:101)
              	at org.springframework.web.context.support.HttpRequestHandlerServlet.service(HttpRequestHandlerServlet.java:67)
              	at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
              	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
              ...
              	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
              	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
              	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
              	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
              	at org.mortbay.jetty.Server.handle(Server.java:324)
              	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
              	at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
              	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
              	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
              	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
              	at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
              	at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
              Caused by: org.springframework.integration.dispatcher.AggregateMessageDeliveryException: All attempts to deliver Message to MessageHandlers failed. Multiple causes:
                  error occurred in message handler [org.springframework.integration.aggregator.AggregatingMessageHandler#0]
                  error occurred in message handler [org.springframework.integration.aggregator.AggregatingMessageHandler#0]
              See below for the stacktrace of the first cause.
              	at org.springframework.integration.dispatcher.UnicastingDispatcher.handleExceptions(UnicastingDispatcher.java:165)
              	at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:128)
              	at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:102)
              	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
              	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
              	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
              	at org.springframework.integration.core.MessagingTemplate.doSendAndReceive(MessagingTemplate.java:318)
              	at org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:239)
              	at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:249)
              	... 41 more
              Caused by: org.springframework.integration.MessageHandlingException: error occurred in message handler [org.springframework.integration.aggregator.AggregatingMessageHandler#0]
              	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:79)
              	at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:115)
              	at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:102)
              	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
              ...
              	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:159)
              	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:141)
              	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
              	at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:115)
              	... 48 more
              Caused by: java.lang.IllegalStateException: Failed to process message list
              	at org.springframework.integration.aggregator.MethodInvokingMessageListProcessor.process(MethodInvokingMessageListProcessor.java:72)
              	at org.springframework.integration.aggregator.MethodInvokingReleaseStrategy.canRelease(MethodInvokingReleaseStrategy.java:54)
              	at org.springframework.integration.aggregator.AbstractCorrelatingMessageHandler.handleMessageInternal(AbstractCorrelatingMessageHandler.java:233)
              	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
              	... 62 more
              Caused by: org.springframework.expression.AccessException: Unable to access property 'payload' through getter
              	at org.springframework.expression.spel.support.ReflectivePropertyAccessor$OptimalPropertyAccessor.read(ReflectivePropertyAccessor.java:517)
              	at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:195)
              ...
              	at org.springframework.integration.util.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:227)
              	at org.springframework.integration.util.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:132)
              	at org.springframework.integration.aggregator.MethodInvokingMessageListProcessor.process(MethodInvokingMessageListProcessor.java:66)
              	... 65 more
              Caused by: java.lang.reflect.InvocationTargetException
              	at sun.reflect.GeneratedMethodAccessor7.invoke(Unknown Source)
              	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              	at java.lang.reflect.Method.invoke(Method.java:597)
              	at org.springframework.expression.spel.support.ReflectivePropertyAccessor$OptimalPropertyAccessor.read(ReflectivePropertyAccessor.java:514)
              	... 75 more
              Caused by: java.lang.IllegalStateException: Invalid method parameter for payload: was expecting collection.
              	at org.springframework.util.Assert.state(Assert.java:384)
              	at org.springframework.integration.util.MessagingMethodInvokerHelper$ParametersWrapper.getPayload(MessagingMethodInvokerHelper.java:656)
              	... 79 more

              Comment


              • #8
                Unable to access property 'payload' through getter
                As I said, the enricher has to be before the transformer - it's too late afterwards because you've already transformed the payload to a String.

                Comment


                • #9
                  Sorry for the late answer but because of days off and after a lots of test, I still have problems :-)

                  I splitted my configuration files :

                  One file expose my service and import my business-service.xml :

                  <?xml version="1.0" encoding="UTF-8"?>
                  <beans xmlns="http://www.springframework.org/schema/beans"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns:si="http://www.springframework.org/schema/integration"
                  xmlns:int="http://www.springframework.org/schema/integration"
                  xmlns:task="http://www.springframework.org/schema/task"
                  xmlns:int-http="http://www.springframework.org/schema/integration/http"
                  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schem...ring-beans.xsd
                  http://www.springframework.org/schema/integration http://www.springframework.org/schem...ntegration.xsd
                  http://www.springframework.org/schema/integration/http http://www.springframework.org/schem...n-http-2.0.xsd
                  http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">


                  <import resource="business-service.xml"/>

                  <!--==============-->
                  <!-- Gateways -->
                  <!--==============-->
                  <int-http:inbound-gateway id="inboundGateway" request-channel="input" reply-channel="outputAggregator" request-payload-type="java.lang.String" reply-timeout="10000" error-channel="failed-channel"/>

                  <!--==============-->
                  <!-- Channels -->
                  <!--==============-->
                  <si:channel id="input" />

                  <!--==============-->
                  <!-- Transformers -->
                  <!--==============-->
                  <int:json-to-object-transformer input-channel="input" output-channel="transformedInput" type="google.il.share.dto.Input" />

                  </beans>
                  The business-service.xml looks like :

                  <?xml version="1.0" encoding="UTF-8"?>
                  <beans xmlns="http://www.springframework.org/schema/beans"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns:si="http://www.springframework.org/schema/integration"
                  xmlns:int="http://www.springframework.org/schema/integration"
                  xmlns:task="http://www.springframework.org/schema/task"
                  xmlns:int-http="http://www.springframework.org/schema/integration/http"
                  xmlns:stream="http://www.springframework.org/schema/integration/stream"
                  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schem...ring-beans.xsd
                  http://www.springframework.org/schema/integration http://www.springframework.org/schem...ntegration.xsd
                  http://www.springframework.org/schema/integration/http http://www.springframework.org/schem...n-http-2.0.xsd
                  http://www.springframework.org/schema/task http://www.springframework.org/schem...g-task-3.0.xsd
                  http://www.springframework.org/schem...gration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd">

                  <!--==============-->
                  <!-- Channels -->
                  <!--==============-->

                  <si:channel id="transformedInput" datatype="google.il.share.dto.Input" />
                  <si:channel id="outputAggregator" />
                  <si:channel id="channel2Pivot" />
                  <si:channel id="outputPivot"/>
                  <si:channel id="output" />
                  <si:channel id="failed-channel" />

                  <int:channel id="channel1">
                  <int:dispatcher task-executor="executor"/>
                  </int:channel>

                  <int:channel id="channel2" >
                  <int:dispatcher task-executor="executor"/>
                  </int:channel>

                  <int:channel id="channel3" >
                  <int:dispatcher task-executor="executor"/>
                  </int:channel>

                  <task:executor id="executor" pool-size="5" keep-alive="5"/>

                  <!--==============-->
                  <!-- Activators -->
                  <!--==============-->

                  <int:transformer input-channel="failed-channel" output-channel="output" ref="exceptionTransformer" method="handleError" />

                  <!--==============-->
                  <!-- Activators -->
                  <!--==============-->

                  <si:service-activator input-channel="channel1" output-channel="output" ref="serviceFacade1" method="getAccounts" />
                  <si:service-activator input-channel="channel2" output-channel="outputPivot" ref="serviceFacade1" method="getAccountsBis" />
                  <si:service-activator input-channel="channel3" output-channel="output" ref="serviceFacade1" method="getAccountsWithFailure" />

                  <!--==============-->
                  <!-- Facades -->
                  <!--==============-->

                  <bean id="serviceFacade1" class="google.poc.il.impl.ServiceFacadeImpl" />

                  <!--==============-->
                  <!-- Transformers -->
                  <!--==============-->
                  <bean id="exceptionTransformer" class="google.poc.transformers.ExceptionTransforme r" />

                  <int:transformer id="testTransformer" ref="testTransformerBean" input-channel="outputPivot"
                  method="transform" output-channel="output"/>

                  <bean id="testTransformerBean" class="google.poc.transformers.TestTransformer" />

                  <int:transformer id="inputTransformer" ref="inputTransformerBean" input-channel="channel2Pivot"
                  method="transform" output-channel="channel2"/>

                  <bean id="inputTransformerBean" class="google.poc.transformers.InputTransformer" />

                  <!--==============-->
                  <!-- Routers -->
                  <!--==============-->

                  <int:recipient-list-router id="customRouter"
                  input-channel="transformedInput" apply-sequence="true"
                  ignore-send-failures="true">
                  <int:recipient channel="channel1" />
                  <int:recipient channel="channel2Pivot" />
                  <int:recipient channel="channel3" />
                  </int:recipient-list-router>

                  <!--==============-->
                  <!-- Aggregators -->
                  <!--==============-->

                  <int:aggregator input-channel="output"
                  output-channel="outputAggregator" method="aggregate"
                  ref="resultAggregator" />

                  <bean id="resultAggregator" class="google.poc.aggregators.ResultAggregator"/>


                  </beans>
                  My method raising exception :

                  Code:
                  	
                  ...
                  @Override
                  	public List<AccountDto> getAccountsWithFailure(Input input) throws MyBusinessException {
                  		long threadId = Thread.currentThread().getId();
                  //		try {
                  //			Thread.currentThread().sleep(20000);
                  //		} catch (Exception e) {
                  //			// TODO: handle exception
                  //		}
                  		System.out.println("getAccountsWithFailure on thread id: "+ threadId + " - " + Thread.currentThread().getName());
                  		//throw new MyBusinessException("I am the MyBusinessException....huhhuuuu");
                  		input.setInputString("getAccounts on thread id: "+ threadId + " - " + Thread.currentThread().getName());
                  		System.out.println(input.getInputString());
                  		List<AccountDto> result = blFacade.getAccounts(input);
                  		return result;
                  	}
                  ...
                  When I execute it, it works correctly and returns 30 results on my client (java code calling the servlet and tranforming the JSON result as list of Objects ), but when I uncomment the line raising the MyBusinessException I receive nothing in the response content and so this exception on the client side, but no exception on server side :

                  Code:
                  java.io.EOFException: No content to map to Object due to end of input
                  	at org.codehaus.jackson.map.ObjectMapper._initForReading(ObjectMapper.java:2775)
                  	at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2718)
                  	at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1877)
                  	at google.poc.client.HttpClientDemo.mapJsonToObjectList(HttpClientDemo.java:91)
                  	at google.poc.client.HttpClientDemo.main(HttpClientDemo.java:68)
                  When I breakpoint the results of my ResultAggregator it contains 20 elements (that is right because 2 services returns 10 results each ):

                  Code:
                  public class ResultAggregator {
                  	public List<AccountDto> aggregate(List<List<AccountDto>> param) {
                  
                  		List<AccountDto> results = new ArrayList<AccountDto>();
                  
                  		for (List<AccountDto> list : param) {
                  			results.addAll(list);
                  		}
                  
                  		return results;
                  	}
                  }
                  Could you help me please ? ;-(

                  Thx by advance

                  Eric

                  Comment


                  • #10
                    It's impossible (or at least very hard) to debug something like this just looking at the static configuration.

                    Turn on DEBUG logging; follow all the messages through the flow and it will become obvious where the problem is.

                    Comment


                    • #11
                      :-) On my side it is not really obvious, this is the logs with DEBUG activated joined to the message.

                      Maybe more clear for you ?

                      Comment


                      • #12
                        And when I comment the exception sent, I receive my results and you can see the DEBUG log in attachments looking differently.

                        Comment


                        • #13
                          I don't know your application or what your "exceptionTransformer" is doing but what I see in the log is an error at line 194; this is transformed to what looks like a single AccountDTO which is sent to the aggregator, which releases the group, containing 21 AccountDTOs (line 213); this is sent as a reply to the gateway.

                          At line 159 I see a payload with 10 DTOs arriving at the aggregator (sequenceNumber=1, sequenceSize=3); the next 10 arrive at line 199 (sequenceNumber2) and the single (failed) DTO arrives at line 206 and the 21 DTOs are released.

                          This looks like a single list so it looks like your 'resultsAggregator' merges the lists in the 3 payloads.

                          So it all looks fine to me.

                          Comment


                          • #14
                            And when I comment the exception sent...

                            Right; and the only difference in the second log is the line "postSend (sent=true) on channel 'outputAggregator" contains 30 DTOs instead of 21.

                            Comment


                            • #15
                              Strange...

                              My exceptionTranformer simply create a new list with on DTOs, it explains the 21 DTOs relased.


                              My exceptionTranformer :
                              public class ExceptionTransformer {

                              public Message handleError(MessageHandlingException input) {

                              List<AccountDto> list = new ArrayList<AccountDto>();

                              AccountDto accountDto = new AccountDto();
                              accountDto.setConfidential("EXCEPTION");
                              list.add(accountDto);

                              GenericMessage<List<AccountDto>> genericMessage = new GenericMessage<List<AccountDto>>(list);

                              MessageBuilder messageBuilder = MessageBuilder.withPayload(list).copyHeaders(input .getFailedMessage().getHeaders()).setHeader("monit oring", new MonitoringContext());

                              return messageBuilder.build();
                              }

                              }
                              Now, I don't know why I obtain my results without exception raised and no return on my client with the exception.

                              Any ideas ?

                              Comment

                              Working...
                              X