Search code examples
error-handlingjunit4spring-integrationspring-junit

Spring integration errorChannel no messages in JUnit


I have a simple JUnit test in which I am testing errorChannel by hooking up a service activator. However, nothing comes to this channel the config is as follows,

<int:channel id="in"/>

<int:service-activator id="inSA" input-channel="in" ref="thrower" 
      output-channel="nullChannel"/>
          <bean id="thrower" 
class="com.att.datalake.ifr.loader.exceptions.handler.Thrower" />

<int:service-activator input-channel="errorChannel" ref="errorManager" 
        id="errorMgr" method="handleMessage" />

<bean id="errorManager" 
    class="com.att.datalake.ifr.loader.exceptions.handlers.ErrorManager"/> 

The ErrorMgr is as follows:

public class ErrorManager {
@ServiceActivator
public void handleMessage(Message<MessageHandlingException> exception) {
    System.out.println("In cleaner");

}

}

The Thrower class is as follows:

public class Thrower {

public Message<FileMessage> process(final Message<FileMessage> message) throws PublisherException {
    System.out.println("In the Thrower SA at:"+new Date());
    // get error type
    String errorType = (String) message.getHeaders().get("ERROR_TYPE");
    if (errorType.equals("PublisherError")) {
        System.out.println("*****About to throw");
        throw new PublisherException("Simple Publisher Exception at:"+new Date());
    }
    return message;
  }
}

The Thrower SA simply throws an exception, which is reported by JUnit test, but nothing goes to errorChannel

The log in debug is :

2015-01-23 10:53:20.597 DEBUG   --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'integrationHeaderChannelRegistry'
2015-01-23 10:53:20.597 DEBUG   --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'globalChannelInterceptorProcessor'
2015-01-23 10:53:20.598 DEBUG   --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'inSA'
2015-01-23 10:53:20.598 DEBUG   --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'errorMgr'
2015-01-23 10:53:20.598 DEBUG   --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean '_org.springframework.integration.errorLogger'
2015-01-23 10:53:20.598 DEBUG   --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'lifecycleProcessor'
2015-01-23 10:53:20.599  INFO   --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase -2147483648
2015-01-23 10:53:20.600 DEBUG   --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting bean 'globalChannelInterceptorProcessor' of type [class org.springframework.integration.config.GlobalChannelInterceptorProcessor]
2015-01-23 10:53:20.602 DEBUG   --- [           main] .s.i.c.GlobalChannelInterceptorProcessor : No global channel interceptors.
2015-01-23 10:53:20.603 DEBUG   --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Successfully started bean 'globalChannelInterceptorProcessor'
2015-01-23 10:53:20.604  INFO   --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2015-01-23 10:53:20.605 DEBUG   --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting bean 'inSA' of type [class org.springframework.integration.config.ConsumerEndpointFactoryBean]
2015-01-23 10:53:20.605  INFO   --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {service-activator:inSA} as a subscriber to the 'in' channel
2015-01-23 10:53:20.606  INFO   --- [           main] o.s.integration.channel.DirectChannel    : Channel 'org.springframework.context.support.GenericApplicationContext@6f3b5d16.in' has 1 subscriber(s).
2015-01-23 10:53:20.606  INFO   --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started inSA
2015-01-23 10:53:20.606 DEBUG   --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Successfully started bean 'inSA'
2015-01-23 10:53:20.606 DEBUG   --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting bean 'errorMgr' of type [class org.springframework.integration.config.ConsumerEndpointFactoryBean]
2015-01-23 10:53:20.607  INFO   --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {service-activator:errorMgr} as a subscriber to the 'errorChannel' channel
2015-01-23 10:53:20.607  INFO   --- [           main] o.s.i.channel.PublishSubscribeChannel    : Channel 'org.springframework.context.support.GenericApplicationContext@6f3b5d16.errorChannel' has 1 subscriber(s).
2015-01-23 10:53:20.607  INFO   --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started errorMgr
2015-01-23 10:53:20.607 DEBUG   --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Successfully started bean 'errorMgr'
2015-01-23 10:53:20.607 DEBUG   --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting bean '_org.springframework.integration.errorLogger' of type [class org.springframework.integration.config.ConsumerEndpointFactoryBean]
2015-01-23 10:53:20.607  INFO   --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2015-01-23 10:53:20.607  INFO   --- [           main] o.s.i.channel.PublishSubscribeChannel    : Channel 'org.springframework.context.support.GenericApplicationContext@6f3b5d16.errorChannel' has 2 subscriber(s).
2015-01-23 10:53:20.607  INFO   --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started _org.springframework.integration.errorLogger
2015-01-23 10:53:20.608 DEBUG   --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Successfully started bean '_org.springframework.integration.errorLogger'
2015-01-23 10:53:20.610 DEBUG   --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.integration.config.IdGeneratorConfigurer#0'
2015-01-23 10:53:20.612 DEBUG   --- [           main] o.s.c.e.PropertySourcesPropertyResolver  : Searching for key 'spring.liveBeansView.mbeanDomain' in [systemProperties]
2015-01-23 10:53:20.612 DEBUG   --- [           main] o.s.c.e.PropertySourcesPropertyResolver  : Searching for key 'spring.liveBeansView.mbeanDomain' in [systemEnvironment]
2015-01-23 10:53:20.613 DEBUG   --- [           main] o.s.c.e.PropertySourcesPropertyResolver  : Could not find key 'spring.liveBeansView.mbeanDomain' in any property source. Returning [null]
2015-01-23 10:53:20.614 DEBUG   --- [           main] c.DefaultCacheAwareContextLoaderDelegate : Storing ApplicationContext in cache under key [[MergedContextConfiguration@105fece7 testClass = ErrorHandlerTests, locations = '{classpath:com/att/datalake/ifr/loader/flowtests/ErrorHandlerTests-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]
2015-01-23 10:53:20.615 DEBUG   --- [           main] org.springframework.test.context.cache   : Spring test ApplicationContext cache statistics: [ContextCache@7a1a14a4 size = 1, hitCount = 0, missCount = 1, parentContextCount = 0]
2015-01-23 10:53:20.620 DEBUG   --- [           main] o.s.b.f.annotation.InjectionMetadata     : Processing injected method of bean 'com.att.datalake.ifr.loader.flowtests.ErrorHandlerTests': AutowiredFieldElement for private org.springframework.messaging.MessageChannel com.att.datalake.ifr.loader.flowtests.ErrorHandlerTests.in
2015-01-23 10:53:20.623 DEBUG   --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'in'
2015-01-23 10:53:20.623 DEBUG   --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'nullChannel'
2015-01-23 10:53:20.624 DEBUG   --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'errorChannel'
2015-01-23 10:53:20.625 DEBUG   --- [           main] f.a.AutowiredAnnotationBeanPostProcessor : Autowiring by type from bean name 'com.att.datalake.ifr.loader.flowtests.ErrorHandlerTests' to bean named 'in'
2015-01-23 10:53:20.642 DEBUG   --- [           main] o.s.i.handler.ServiceActivatingHandler   : ServiceActivator for [org.springframework.integration.handler.MethodInvokingMessageProcessor@49ff7d8c] (inSA) received message: GenericMessage [payload=FileMessage [name=2.txt, path=input/2.txt], headers={ERROR_TYPE=PublisherError, correlationId=1, id=dd662ff5-9790-77e2-cceb-f43afc97de81, timestamp=1422028400642}]
In the Thrower SA at:Fri Jan 23 10:53:20 EST 2015
*****About to throw
2015-01-23 10:53:20.648 DEBUG   --- [           main] .c.s.DirtiesContextTestExecutionListener : After test method: context [DefaultTestContext@40e6dfe1 testClass = ErrorHandlerTests, testInstance = com.att.datalake.ifr.loader.flowtests.ErrorHandlerTests@1b083826, testMethod = test@ErrorHandlerTests, testException = org.springframework.messaging.MessageHandlingException: ; nested exception is com.att.datalake.ifr.loader.exceptions.PublisherException: Simple Publisher Exception at:Fri Jan 23 10:53:20 EST 2015, mergedContextConfiguration = [MergedContextConfiguration@105fece7 testClass = ErrorHandlerTests, locations = '{classpath:com/att/datalake/ifr/loader/flowtests/ErrorHandlerTests-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class dirties context [false], class mode [null], method dirties context [false].
2015-01-23 10:53:20.657 DEBUG   --- [           main] .c.s.DirtiesContextTestExecutionListener : After test class: context [DefaultTestContext@40e6dfe1 testClass = ErrorHandlerTests, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@105fece7 testClass = ErrorHandlerTests, locations = '{classpath:com/att/datalake/ifr/loader/flowtests/ErrorHandlerTests-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], dirtiesContext [false].
2015-01-23 10:53:20.662  INFO   --- [       Thread-0] o.s.c.support.GenericApplicationContext  : Closing org.springframework.context.support.GenericApplicationContext@6f3b5d16: startup date [Fri Jan 23 10:53:19 EST 2015]; root of context hierarchy
2015-01-23 10:53:20.663 DEBUG   --- [       Thread-0] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.integration.config.IdGeneratorConfigurer#0'
2015-01-23 10:53:20.664 DEBUG   --- [       Thread-0] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'integrationHeaderChannelRegistry'
2015-01-23 10:53:20.664 DEBUG   --- [       Thread-0] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'globalChannelInterceptorProcessor'
2015-01-23 10:53:20.664 DEBUG   --- [       Thread-0] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'inSA'
2015-01-23 10:53:20.664 DEBUG   --- [       Thread-0] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'errorMgr'
2015-01-23 10:53:20.664 DEBUG   --- [       Thread-0] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean '_org.springframework.integration.errorLogger'
2015-01-23 10:53:20.665 DEBUG   --- [       Thread-0] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'lifecycleProcessor'
2015-01-23 10:53:20.665  INFO   --- [       Thread-0] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase 0
2015-01-23 10:53:20.666 DEBUG   --- [       Thread-0] o.s.c.support.DefaultLifecycleProcessor  : Asking bean 'inSA' of type [class org.springframework.integration.config.ConsumerEndpointFactoryBean] to stop
2015-01-23 10:53:20.667  INFO   --- [       Thread-0] o.s.i.endpoint.EventDrivenConsumer       : Removing {service-activator:inSA} as a subscriber to the 'in' channel
2015-01-23 10:53:20.667  INFO   --- [       Thread-0] o.s.integration.channel.DirectChannel    : Channel 'org.springframework.context.support.GenericApplicationContext@6f3b5d16.in' has 0 subscriber(s).
2015-01-23 10:53:20.667 DEBUG   --- [       Thread-0] o.s.c.support.DefaultLifecycleProcessor  : Bean 'inSA' completed its stop procedure
2015-01-23 10:53:20.667  INFO   --- [       Thread-0] o.s.i.endpoint.EventDrivenConsumer       : stopped inSA
2015-01-23 10:53:20.667 DEBUG   --- [       Thread-0] o.s.c.support.DefaultLifecycleProcessor  : Asking bean 'errorMgr' of type [class org.springframework.integration.config.ConsumerEndpointFactoryBean] to stop
2015-01-23 10:53:20.667  INFO   --- [       Thread-0] o.s.i.endpoint.EventDrivenConsumer       : Removing {service-activator:errorMgr} as a subscriber to the 'errorChannel' channel
2015-01-23 10:53:20.667  INFO   --- [       Thread-0] o.s.i.channel.PublishSubscribeChannel    : Channel 'org.springframework.context.support.GenericApplicationContext@6f3b5d16.errorChannel' has 1 subscriber(s).
2015-01-23 10:53:20.668 DEBUG   --- [       Thread-0] o.s.c.support.DefaultLifecycleProcessor  : Bean 'errorMgr' completed its stop procedure
2015-01-23 10:53:20.668  INFO   --- [       Thread-0] o.s.i.endpoint.EventDrivenConsumer       : stopped errorMgr
2015-01-23 10:53:20.668 DEBUG   --- [       Thread-0] o.s.c.support.DefaultLifecycleProcessor  : Asking bean '_org.springframework.integration.errorLogger' of type [class org.springframework.integration.config.ConsumerEndpointFactoryBean] to stop
2015-01-23 10:53:20.668  INFO   --- [       Thread-0] o.s.i.endpoint.EventDrivenConsumer       : Removing {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2015-01-23 10:53:20.668  INFO   --- [       Thread-0] o.s.i.channel.PublishSubscribeChannel    : Channel 'org.springframework.context.support.GenericApplicationContext@6f3b5d16.errorChannel' has 0 subscriber(s).
2015-01-23 10:53:20.668 DEBUG   --- [       Thread-0] o.s.c.support.DefaultLifecycleProcessor  : Bean '_org.springframework.integration.errorLogger' completed its stop procedure
2015-01-23 10:53:20.668  INFO   --- [       Thread-0] o.s.i.endpoint.EventDrivenConsumer       : stopped _org.springframework.integration.errorLogger
2015-01-23 10:53:20.668  INFO   --- [       Thread-0] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase -2147483648
2015-01-23 10:53:20.668 DEBUG   --- [       Thread-0] o.s.b.f.s.DefaultListableBeanFactory     : Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@25ce9dc4: defining beans [org.springframework.context.support.PropertySourcesPlaceholderConfigurer#0,channelInitializer,$autoCreateChannelCandidates,IntegrationConfigurationBeanFactoryPostProcessor,integrationEvaluationContext,org.springframework.integration.expression.IntegrationEvaluationContextAwareBeanPostProcessor#0,integrationGlobalProperties,integrationHeaderChannelRegistry,globalChannelInterceptorProcessor,toStringFriendlyJsonNodeToStringConverter,converterRegistrar,integrationConversionService,DefaultConfiguringBeanFactoryPostProcessor,datatypeChannelMessageConverter,messageBuilderFactory,in,org.springframework.integration.config.ServiceActivatorFactoryBean#0,inSA,thrower,org.springframework.integration.config.ServiceActivatorFactoryBean#1,fixedSubscriberChannelBeanFactoryPostProcessor,errorMgr,errorManager,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor,nullChannel,errorChannel,_org.springframework.integration.errorLogger,taskScheduler,org.springframework.integration.config.IdGeneratorConfigurer#0]; root of factory hierarchy
2015-01-23 10:53:20.694 DEBUG   --- [       Thread-0] o.s.b.f.s.DefaultListableBeanFactory     : Retrieved dependent beans for bean '(inner bean)#74589991': [_org.springframework.integration.errorLogger]
2015-01-23 10:53:20.696 DEBUG   --- [       Thread-0] o.s.b.f.s.DefaultListableBeanFactory     : Retrieved dependent beans for bean 'in': [com.att.datalake.ifr.loader.flowtests.ErrorHandlerTests]
2015-01-23 10:53:20.697 DEBUG   --- [       Thread-0] o.s.b.f.support.DisposableBeanAdapter    : Invoking destroy() on bean with name 'taskScheduler'
2015-01-23 10:53:20.698  INFO   --- [       Thread-0] o.s.s.c.ThreadPoolTaskScheduler          : Shutting down ExecutorService 'taskScheduler'
2015-01-23 10:53:20.699 DEBUG   --- [       Thread-0] o.s.b.f.s.DefaultListableBeanFactory     : Retrieved dependent beans for bean '(inner bean)#4b213651': [taskScheduler]

Solution

  • The ErrorMessage with an Exception is thrown to the error-channel only if the downstream flow is within the separate Thread. Otherwise the Exception is rethrown to the call. It is thrown to the caller anyway, but shifted to the error-channel, if there is no original caller control from Spring Integration.

    See more info here: http://docs.spring.io/spring-integration/docs/latest-ga/reference/html/configuration.html#namespace-errorhandler