title: Integration issues with Spring Batch and Spring Integration - "No poller has been defined for endpoint" exception
body: <p>I went through the <a href="http://docs.spring.io/spring-integration/reference/html/sftp.html" rel="nofollow">Spring Integration guide</a> and the <a href="https://github.com/spring-projects/spring-integration-samples/tree/master/basic/sftp" rel="nofollow">examples here</a> and got a working sample for Spring Integration SFTP program. I already have a working Spring Batch program that reads a bunch of file and dumps into the Database. </p>
  
  <p>I am now trying to integrate both Spring Batch and Spring Integration programs by going through the <a href="http://docs.spring.io/spring-batch/reference/html/springBatchIntegration.html" rel="nofollow">Spring docs</a> and I created the below configuration. </p>
  
  <pre><code>&lt;bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory"&gt;
          &lt;property name="host" value="${host}"/&gt;
          &lt;property name="port" value="${port}"/&gt;
          &lt;property name="user" value="${user}"/&gt;
          &lt;property name="password" value="${password}"/&gt;
      &lt;/bean&gt;
  
      &lt;int:channel id="inboundFileChannel"&gt;&lt;int:queue/&gt;&lt;/int:channel&gt;
      &lt;int:channel id="outboundJobRequestChannel"/&gt;
      &lt;int:channel id="jobLaunchReplyChannel"/&gt;
  
      &lt;int-sftp:inbound-channel-adapter id="sftpInbondAdapter"
              channel="inboundFileChannel"
              session-factory="sftpSessionFactory"
              local-directory="file:/chofac/data/mex/registry/outbox"
              remote-directory="/chofac/SFTP/MEX/outbox"
              auto-create-local-directory="true"
              delete-remote-files="false"
              filename-pattern="*.txt"&gt;
          &lt;int:poller max-messages-per-poll="-1" fixed-rate="1000" /&gt;
      &lt;/int-sftp:inbound-channel-adapter&gt;
  
      &lt;int:transformer input-channel="inboundFileChannel"
          output-channel="outboundJobRequestChannel"&gt;
          &lt;bean class="com.chofac.mint.integration.FileMessageToJobRequest"&gt;
              &lt;property name="job" ref="responseFileReaderJob"/&gt;
              &lt;!-- &lt;property name="fileParameterName" value="input.file.name"/&gt; --&gt;
          &lt;/bean&gt;
      &lt;/int:transformer&gt;
  
      &lt;batch-int:job-launching-gateway request-channel="outboundJobRequestChannel"
          reply-channel="jobLaunchReplyChannel" job-launcher="jobLauncher"&gt;
          &lt;int:poller fixed-rate="1000"/&gt;
      &lt;/batch-int:job-launching-gateway&gt;
  
      &lt;int:logging-channel-adapter channel="jobLaunchReplyChannel"/&gt;
  
      &lt;batch:job id="responseFileReaderJob"&gt;
          &lt;batch:step id="dailyReaderJob"&gt;
              &lt;batch:tasklet&gt;
                  &lt;batch:chunk reader="dailyRRReader" writer="dailyRRDBWriter" processor="itemProcessor" commit-interval="10"/&gt;
              &lt;/batch:tasklet&gt;
          &lt;/batch:step&gt;
      &lt;/batch:job&gt;
  </code></pre>
  
  <p>I am running this program using the test case below:</p>
  
  <pre><code>@RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(locations = {"classpath:META-INF/spring/applicationContext.xml","classpath:META-INF/spring/inbound-ResponseReaderJobIntegration.xml"})
  public class AAASftpInboundMsgJobTriggerTest {
  
      @Resource(name="inboundFileChannel")
      PollableChannel localFileChannel;
  
      @Test
      public void runDemo(){
          System.out.println("Received first file message: " + localFileChannel.receive());
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>I get this error:</p>
  
  <blockquote>
    <p>2014-07-01 10:51:48,987 [main] INFO 
    org.hibernate.impl.SessionFactoryImpl - closing 2014-07-01
    10:51:48,988 [main] DEBUG
    org.springframework.beans.factory.support.DisposableBeanAdapter -
    Invoking destroy method 'close' on bean with name 'dataSource'
    2014-07-01 10:51:48,988 [main] ERROR
    org.springframework.test.context.TestContextManager - Caught exception
    while allowing TestExecutionListener
    [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@2faadcc6]
    to prepare test instance
    [com.chofac.mint.integration.AAASftpInboundMsgJobTriggerTest@5d3ad33d]
    java.lang.IllegalStateException: Failed to load ApplicationContext    at
    org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
      at
    org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)
      at
    org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
      at
    org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
      at
    org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:326)
      at
    org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:212)  at
    org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
      at
    org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
      at
    org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
      at
    org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
      at
    org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)  at
    org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)   at
    org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)     at
    org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)   at
    org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)  at
    org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
      at
    org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:300)    at
    org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
      at
    org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
      at
    org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
      at
    org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
      at
    org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
      at
    org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
      at
    org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: org.springframework.beans.factory.BeanCreationException:
    Error creating bean with name
    'org.springframework.integration.config.ConsumerEndpointFactoryBean#0':
    Invocation of init method failed; nested exception is
    java.lang.IllegalArgumentException: No poller has been defined for
    endpoint
    'org.springframework.integration.config.ConsumerEndpointFactoryBean#0',
    and no default poller is available within the context.    at
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
      at
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
      at
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      at
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
      at
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
      at
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
      at
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
      at
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:681)
      at
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
      at
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
      at
    org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:121)
      at
    org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
      at
    org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
      at
    org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:250)
      at
    org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
      at
    org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
      ... 25 more Caused by: java.lang.IllegalArgumentException: No poller
    has been defined for endpoint
    'org.springframework.integration.config.ConsumerEndpointFactoryBean#0',
    and no default poller is available within the context.    at
    org.springframework.util.Assert.notNull(Assert.java:112)  at
    org.springframework.integration.config.ConsumerEndpointFactoryBean.initializeEndpoint(ConsumerEndpointFactoryBean.java:238)
      at
    org.springframework.integration.config.ConsumerEndpointFactoryBean.afterPropertiesSet(ConsumerEndpointFactoryBean.java:187)
      at
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
      at
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
      ... 40 more 2014-07-01 10:51:48,992 [main] DEBUG
    org.springframework.test.context.support.DirtiesContextTestExecutionListener
    - After test class: context [DefaultTestContext@ac44b88 testClass = SftpInboundMsgJobTriggerTest, testInstance = [null], testMethod =
    [null], testException = [null], mergedContextConfiguration =
    [MergedContextConfiguration@4102799c testClass =
    SftpInboundMsgJobTriggerTest, locations =
    '{classpath:META-INF/spring/applicationContext.xml,
    classpath:META-INF/spring/inbound-ResponseReaderJobIntegration.xml.xml}',
    classes = '{}', contextInitializerClasses = '[]', activeProfiles =
    '{}', contextLoader =
    'org.springframework.test.context.support.DelegatingSmartContextLoader',
    parent = [null]]], dirtiesContext [false].</p>
  </blockquote>
  
  <p>I experimented with most of the <a href="http://goo.gl/rYfymI" rel="nofollow">top answers on this issue</a> from Google and the suggestions from StachOverflow as I typed this question, all of them resulted in different other errors and I seem to be getting diverted from the main issue. </p>
  
  <p>Most common suggestion was to add a global poller, but this resulted in the error below:</p>
  
  <pre><code>&lt;int:poller default="true" fixed-delay="50"/&gt;
  </code></pre>
  
  <blockquote>
    <p>Caused by: java.lang.IllegalArgumentException: A poller should not be
    specified for endpoint
    'org.springframework.integration.config.ConsumerEndpointFactoryBean#1',
    since 'outboundJobRequestChannel' is a SubscribableChannel (not
    pollable).</p>
  </blockquote>
  
  <p>(I am a newbie in all of these, Spring, Spring Batch and Spring Integration) Any help would be greatly appreciated. Thanks in advance.</p>
  
  <p><strong>Update 1</strong></p>
  
  <p>I removed the poller in the #2 like the below </p>
  
  <pre><code>&lt;batch-int:job-launching-gateway request-channel="outboundJobRequestChannel"
      reply-channel="jobLaunchReplyChannel" job-launcher="jobLauncher"&gt;
  &lt;/batch-int:job-launching-gateway&gt;
  </code></pre>
  
  <p>and removed the global poller</p>
  
  <pre><code>&lt;int:poller default="true" fixed-delay="50"/&gt; 
  </code></pre>
  
  <p><strong>I get the below exception:</strong></p>
  
  <p>Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.config.ConsumerEndpointFactoryBean#0': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No poller has been defined for endpoint 'org.springframework.integration.config.ConsumerEndpointFactoryBean#0', and no default poller is available within the context.
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:681)
      at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
      at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
      at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
      at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:93)
      at com.chofac.mint.integration.DownloadFileRunBatch.main(DownloadFileRunBatch.java:15)
  Caused by: java.lang.IllegalArgumentException: No poller has been defined for endpoint 'org.springframework.integration.config.ConsumerEndpointFactoryBean#0', and no default poller is available within the context.
      at org.springframework.util.Assert.notNull(Assert.java:112)
      at org.springframework.integration.config.ConsumerEndpointFactoryBean.initializeEndpoint(ConsumerEndpointFactoryBean.java:238)
      at org.springframework.integration.config.ConsumerEndpointFactoryBean.afterPropertiesSet(ConsumerEndpointFactoryBean.java:187)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
      ... 12 more</p>
  
  <p><strong><em>However...</em></strong> if I leave the global poller the SFTP transfer happens and the job gets triggered</p>
  
  <pre><code>&lt;int:poller default="true" fixed-delay="50"/&gt;
  </code></pre>
  
  <p><strong>Update 2</strong></p>
  
  <p>I get the below exception if I remove <em></em> </p>
  
  <pre><code>Exception in thread "main" org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'inboundFileChannel' must be of type [org.springframework.messaging.PollableChannel], but was actually of type [org.springframework.integration.channel.DirectChannel]  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:376)    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)  at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:979)  at com.chofac.mint.batchintegration.SftpInboundMsgJobTriggerMain.main(SftpInboundMsgJobTriggerMain.java:16)
  </code></pre>
  
  <p>Here's my configuration again:</p>
  
  <pre><code>&lt;int-sftp:inbound-channel-adapter id="sftpInbondAdapter"
          channel="inboundFileChannel"
          session-factory="sftpSessionFactory"
          local-directory="file:${inbound.local.directory}"
          remote-directory="${inbound.remote.directory}"
          auto-create-local-directory="true"
          delete-remote-files="false"
          filename-pattern="*.*"&gt;
      &lt;int:poller max-messages-per-poll="-1" fixed-rate="45000" /&gt;
      &lt;!-- &lt;int:poller max-messages-per-poll="-1" cron="${MEX.CRON.PATTERN}"/&gt; --&gt;
      &lt;!-- 0 15 10 ? * MON-FRI --&gt;
  &lt;/int-sftp:inbound-channel-adapter&gt;
  
  &lt;int:channel id="inboundFileChannel"&gt;&lt;/int:channel&gt;
  &lt;int:channel id="outboundJobRequestChannel"/&gt;
  &lt;int:channel id="jobLaunchReplyChannel"/&gt;
  
  &lt;!-- &lt;int:poller default="true" cron="${MEX.CRON.PATTERN}"/&gt; --&gt;
  
  &lt;int:transformer input-channel="inboundFileChannel"
      output-channel="outboundJobRequestChannel"&gt;
      &lt;bean class="com.chofac.mint.integration.FileMessageToJobRequest"&gt;
          &lt;property name="job" ref="responseFileReaderJob"/&gt;
      &lt;/bean&gt;
  &lt;/int:transformer&gt;
  
  &lt;batch-int:job-launching-gateway request-channel="outboundJobRequestChannel"
      reply-channel="jobLaunchReplyChannel" job-launcher="jobLauncher"&gt;
  &lt;/batch-int:job-launching-gateway&gt;
  
  &lt;int:logging-channel-adapter channel="jobLaunchReplyChannel"/&gt;
  </code></pre>
  
  <p>I am triggering this from a Main program as below:</p>
  
  <pre><code>ApplicationContext context = new ClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml","classpath:META-INF/spring/batchintegration/inboundSFTPJob.xml");
  PollableChannel pollableFileChannel = context.getBean("inboundFileChannel", PollableChannel.class);
  System.out.println("Received first file message: " + pollableFileChannel.receive());
  </code></pre>
  
  <p><strong>Update 3</strong></p>
  
  <p>Sample <a href="https://github.com/spring-projects/spring-integration-samples/blob/master/basic/sftp/src/test/resources/META-INF/spring/integration/SftpInboundReceiveSample-context.xml" rel="nofollow">Configuration</a>, <a href="https://github.com/spring-projects/spring-integration-samples/blob/master/basic/sftp/src/test/java/org/springframework/integration/samples/sftp/SftpInboundReceiveSample.java" rel="nofollow">JUnit</a>, and <a href="http://docs.spring.io/spring-batch/trunk/reference/html/springBatchIntegration.html" rel="nofollow">Spring example</a> on the web.</p>
  
  <p><strong>Update 4</strong></p>
  
  <pre><code>&lt;int-sftp:inbound-channel-adapter id="sftpInbondAdapter"
          channel="inboundFileChannel"
          session-factory="sftpSessionFactory"
          local-directory="file:${inbound.local.directory}"
          remote-directory="${inbound.remote.directory}"
          auto-create-local-directory="true"
          delete-remote-files="false" 
          filename-pattern ="*.*"
          local-filter="acceptAllFileListFilter"&gt;
      &lt;int:poller max-messages-per-poll="-1" fixed-rate="45000" /&gt;
  
  &lt;bean id="acceptAllFileListFilter" class="org.springframework.integration.file.filters.AcceptAllFileListFilter"/&gt;
  </code></pre>
  
  <p>program runs into a continuous loop with exceptions. I feel the polling happens very frequently (every second) though I have specified 45 seconds for the poller <a href="https://docs.google.com/document/d/1Nyo0nc6S46iNNCiLH5vgIj6H4wncYVtz0uU_MZX6qDs/edit?usp=sharing" rel="nofollow">Full configuration and logs here</a>.</p>