title: How to send message to stop polling and exit from application
body: <p>I have spring integration application and I need to close it after all data were processed. If I explicitly call <code>appContext.close()</code> then not all data could be processed in time(unless I set <code>Thread.sleep()</code>). If I do not call close on application context then application doesn't stop since I have background poller that does not allow application to close automatically. So how to signal to stop whole application in one of my service activator(last in the chain of processing)?</p>
  
  <ol>
  <li>first bean reads data from storage line by line and send it via <code>gateway.send(data)</code> in while loop</li>
  <li>processing chain that is happening in parallel</li>
  <li>than all threads sends messages into single thread via Pollable Queue</li>
  <li>And here I should stop application if I realise that all messages read in the first bean were processed</li>
  </ol>
  
  <p>I tried to stop last service activator using controlbus but it didn't help</p>
  
  <p>Thanks</p>
  
  <p>UPDATE</p>
  
  <p>here are some code examples:</p>
  
  <p>Runner:</p>
  
  <pre><code>public class Runner {
  static Logger log = LoggerFactory.getLogger(Service2.class);
  
  public static void main(String[] args) throws InterruptedException {
      log.info("START APP");
      AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
      RootService service = context.getBean(RootService.class);
      service.start();
      service.stop();
      context.close();
      log.info("END APP");
  }
  </code></pre>
  
  <p>}</p>
  
  <p>RootService:</p>
  
  <pre><code>    @Component
  public class RootService {
  
      Logger log = LoggerFactory.getLogger(RootService.class);
  
      @Autowired
      MyGateway gateway;
  
      int totalSize = 0;
  
      public void start() {
          List&lt;String&gt; source = generateSource();
          totalSize = source.size();
          //imitate very long but finite process
          for (String s : source) {
              gateway.send(s, totalSize);
          }
          log.info("end sending data");
      }
  
      public void stop() throws InterruptedException {
          log.info("sending stop signal...");
          while (gateway.sendStop(totalSize)&lt;0) {
              Thread.sleep(100);
              log.info("sending stop signal...");
          }
          log.info("THE END");
      }
  
  
      private List&lt;String&gt; generateSource() {
          List&lt;String&gt; result = new ArrayList&lt;String&gt;();
          for (int i = 0; i &lt; 15; i++) {
              result.add("data" + i);
          }
          return result;
      }
  }
  </code></pre>
  
  <p>Service1</p>
  
  <pre><code>@Component
  public class Service1 {
  
      public String dodo(String data) throws InterruptedException {
          //doing a job in parallel
          Thread.sleep(100);
          return data + "-" + Thread.currentThread().getName();
      }
  }
  </code></pre>
  
  <p>Service2:</p>
  
  <pre><code>    @Component
  public class Service2 {
      Logger log = LoggerFactory.getLogger(Service2.class);
      int counter = 0;
  
      public void dodo(String data) {
          log.info("data: {}-{}", data, Thread.currentThread().getName());
          counter++;
          log.info("counter: {}", counter);
      }
  
      public Integer dodo(Integer data) {
          if (counter &lt; data) {
              return -1;
          } else {
              return 0;
          }
      }
  }
  
  
  @Component
  public class ErrorHandler {
  
      Logger log = LoggerFactory.getLogger(Service2.class);
  
      public void handleError(Message&lt;?&gt; message) {
          log.info("ERROR: {}", message);
      }
  }
  </code></pre>
  
  <p>and xml config</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans:beans xmlns="http://www.springframework.org/schema/integration"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
          http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd"
               xmlns:beans="http://www.springframework.org/schema/beans"
               xmlns:task="http://www.springframework.org/schema/task"&gt;
  
  
      &lt;gateway id="myGateway"
               service-interface="com.dimas.MyGateway"
               default-request-channel="channel1"
               error-channel="errorChannel"
               default-reply-timeout="3000"&gt;
          &lt;method name="send" request-channel="channel1"/&gt;
          &lt;method name="sendStop" request-channel="channel2" reply-channel="channel3"/&gt;
      &lt;/gateway&gt;
  
      &lt;channel id="channel1"&gt;
          &lt;dispatcher task-executor="executor"/&gt;
      &lt;/channel&gt;
      &lt;channel id="channel2"&gt;
          &lt;queue/&gt;
      &lt;/channel&gt;
      &lt;channel id="channel3"&gt;
          &lt;queue/&gt;
      &lt;/channel&gt;
      &lt;channel id="errorChannel"/&gt;
  
      &lt;service-activator input-channel="errorChannel" ref="errorHandler" method="handleError"/&gt;
  
      &lt;service-activator input-channel="channel1" output-channel="channel2" ref="service1"/&gt;
      &lt;service-activator input-channel="channel2" output-channel="channel3" ref="service2"&gt;
          &lt;poller fixed-delay="0"/&gt;
      &lt;/service-activator&gt;
  
      &lt;task:executor id="executor" pool-size="2"/&gt;
  &lt;/beans:beans&gt;
  </code></pre>
  
  <p>Now it works - app is stopped when all data is processed and it returns stop code 0 but i see in log a lot of errors like:</p>
  
  <blockquote>
    <p>ErrorMessage
    [payload=org.springframework.messaging.core.DestinationResolutionException:
    no output-channel or replyChannel header available,
    headers={id=639ca939-8110-4486-6a2b-5d36c7bfdbcd,
    timestamp=1475872251269}]</p>
  </blockquote>
  
  <p>Error handler successfully catch it but something is wrong</p>
  
  <p>I realized where was the issue. Last Service2 returns soemthing for any income message. Redid it so it responds code only for stopRequest request.</p>
  
  <p>Just wondering if there is simpler solution</p>