title: How to avoid shutdown of SimpleMessageListenerContainer in case of unexpected errors?
body: <p>I am using Java boot 1.4.0 and 'spring-boot-starter-amqp' for connecting to rabbitMq. The message producer, consumer and the rabbitMq server are under my control.Things were working fine for a few months in production. But suddenly my consumer stopped with exceptions given below. As I only produce messages which are always valid, I had no clue what went wrong.</p>
  
  <p>But this caused my listener-container to shutdown. And hence my message processing stopped.I had to manually restart my message-consumer program.</p>
  
  <p><strong>So my questions are:</strong> </p>
  
  <ol>
  <li>Can we avoid complete shutdown of listener-container in any unexpected case?</li>
  <li>Is it possible to gracefully discard such message and keep listener-container alive?</li>
  <li>If not, then are there ways by which I can check if all my listener-containers are running and start them if I found them dead? ( NOTE: I looked at RabbitListenerEndpointRegistry.getListenerContainers(). But looks like it does not cover SimpleMessageListenerContainer containers. )</li>
  </ol>
  
  <p><strong>Exception log:</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>2017-02-20 12:42:18.441 ERROR 18014 --- [writeToDBQQueueListenerContainer-17] o.s.a.r.l.SimpleMessageListenerContainer : Consumer thread error, thread abort.
  java.lang.NoClassDefFoundError: org/springframework/messaging/handler/annotation/support/MethodArgumentNotValidException
      at org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler$DefaultExceptionStrategy.causeIsFatal(ConditionalRejectingErrorHandler.java:110) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
      at org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler$DefaultExceptionStrategy.isFatal(ConditionalRejectingErrorHandler.java:97) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
      at org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler.handleError(ConditionalRejectingErrorHandler.java:72) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeErrorHandler(AbstractMessageListenerContainer.java:625) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.handleListenerException(AbstractMessageListenerContainer.java:852) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:685) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1165) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1149) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1100(SimpleMessageListenerContainer.java:95) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1312) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
      at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91]
  Caused by: java.lang.ClassNotFoundException: org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException
      at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_91]
      at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_91]
      at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:89) ~[KattaQueueManager-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
      at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_91]
      ... 11 common frames omitted</code></pre>
  </div>
  </div>
  </p>
  
  <p><strong>One more exception:</strong>
  <div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>2017-02-20 12:42:18.674 ERROR 18014 --- [imageQueueListenerContainer-53] o.s.a.r.l.SimpleMessageListenerContainer : Consumer thread error, thread abort.
  
  java.lang.NoClassDefFoundError: com/rabbitmq/utility/Utility
          at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.checkShutdown(BlockingQueueConsumer.java:348) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
          at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.nextMessage(BlockingQueueConsumer.java:402) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
          at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1160) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
          at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1149) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
          at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1100(SimpleMessageListenerContainer.java:95) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
          at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1312) ~[spring-rabbit-1.6.1.RELEASE.jar!/:na]
          at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91]
  Caused by: java.lang.ClassNotFoundException: com.rabbitmq.utility.Utility
          at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_91]
          at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_91]
          at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:89) ~[KattaQueueManager-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
          at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_91]
          ... 7 common frames omitted
  
  2017-02-20 12:42:18.675 ERROR 18014 --- [imageQueueListenerContainer-53] o.s.a.r.l.SimpleMessageListenerContainer : Stopping container from aborted consumer</code></pre>
  </div>
  </div>
  </p>
  
  <p><strong>My consumer sample code:</strong></p>
  
  <pre><code>@Bean
  public MessageConverter jsonMessageConverter(){
      //return new JsonMessageConverter();
      Jackson2JsonMessageConverter converter =  new   Jackson2JsonMessageConverter();
  
      converter.setClassMapper(new ClassMapper() {
          @Override
          public Class&lt;?&gt; toClass(MessageProperties properties) {
              return String.class;
          }
  
          @Override
          public void fromClass(Class&lt;?&gt; clazz, MessageProperties properties) {
          }
      });
  
      return converter;
  }
  
  @Bean
  public ConnectionFactory connectionFactory() 
  {
      CachingConnectionFactory connectionFactory =
              new CachingConnectionFactory(_rabbitmqHost, _rabbitmqPort);
      return connectionFactory;
  }
  
  @Bean
  public RabbitTemplate rabbitTemplate() 
  {
      RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
      rabbitTemplate.setMessageConverter(jsonMessageConverter());
      return rabbitTemplate;
  }
  
  @Bean
  TopicExchange exchange() 
  {
      return new TopicExchange("MyExchange");
  }
  
  @Bean
  public Queue mainQueue() 
  {
      return new Queue("MyMainQ");
  }
  
  @Bean
  public Binding mainRouteBinding() 
  {
      return BindingBuilder.bind(mainQueue()).to(exchange()).with("MyMainQ");
  }
  
  @Bean
  SimpleMessageListenerContainer mainQueueListenerContainer(
          ConnectionFactory connectionFactory, 
          @Qualifier("mainQueueListenerAdapter") MessageListenerAdapter listenerAdapter) 
  {
      SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
      container.setConnectionFactory(connectionFactory);
      container.setQueues(mainQueue());
  
      container.setMessageConverter(jsonMessageConverter());
  
      container.setMessageListener(listenerAdapter);
      container.setConcurrentConsumers(1);
      return container;
  }
  
  @Bean
  MessageListenerAdapter mainQueueListenerAdapter(MainConsumer receiver) 
  {
      MessageListenerAdapter msgAdapter = new MessageListenerAdapter(receiver, "receiveMessage");
  
      msgAdapter.setMessageConverter(jsonMessageConverter());
  
      return msgAdapter;
  }
  
  @Bean
  MainConsumer getMainConsumer()
  {
      return new MainConsumer();
  }
  
  //
  //The receiving method in MainConsumer class looks as given below
  public void receiveMessage(String message) 
  {
       // My business logic goes here ...
  }
  </code></pre>