title: Spring boot Failover retryer using rabbitmq: Failed to invoke target method
body: <p>I'm actually trying to implement a failover retryer functionality using rabbit mq.</p>
  
  <p>So the requirement is that I get a message from a queue and process it. If by any issue happens then the message needs to be retried 3 more times.</p>
  
  <p>Can anyone help me the resolve this issue ???</p>
  
  <p>Here is my code</p>
  
  <p><strong>POJO</strong></p>
  
  <pre><code>package com.poc.failoverretryer.model;
  
  import java.io.Serializable;
  
  public class User implements Serializable {
  
      private String firstname;
      private String lastname;
      private String dob;
  
      public User(String firstname, String lastname, String dob) {
          this.firstname = firstname;
          this.lastname = lastname;
          this.dob = dob;
      }
  
      public String getFirstname() {
          return firstname;
      }
  
      public void setFirstname(String firstname) {
          this.firstname = firstname;
      }
  
      public String getLastname() {
          return lastname;
      }
  
      public void setLastname(String lastname) {
          this.lastname = lastname;
      }
  
      public String getDob() {
          return dob;
      }
  
      public void setDob(String dob) {
          this.dob = dob;
      }
  
      @Override
      public String toString() {
          return "User{" +
                  "firstname='" + firstname + '\'' +
                  ", lastname='" + lastname + '\'' +
                  ", dob='" + dob + '\'' +
                  '}';
      }
  }
  
  </code></pre>
  
  <p><strong>The configuration file</strong></p>
  
  <pre><code>package com.poc.failoverretryer.config;
  
  import com.poc.failoverretryer.model.User;
  import com.poc.failoverretryer.receiver.Receiver;
  import com.poc.failoverretryer.receiver.ReceiverTwo;
  import org.springframework.amqp.core.*;
  import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
  import org.springframework.amqp.rabbit.connection.ConnectionFactory;
  import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
  import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
  import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
  import org.springframework.beans.factory.annotation.Qualifier;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.context.annotation.Primary;
  
  import java.io.Serializable;
  
  @Configuration
  public class RMQConfiguration implements Serializable {
  
      @Value("${data.incoming.x}")
      String EXCHANGE_NAME;
      @Value("${data.dl.x}")
      String DEAD_LETTER_EXCHANGE_NAME;
      @Value("${incoming.queue}")
      String INCOMING_QUEUE_NAME;
      @Value("${data.incoming.two}")
      String INCOMING_QUEUE_TWO_NAME;
      @Value("${data.dl}")
      String DEAD_LETTER_QUEUE_NAME;
      @Value("${data.dl.two}")
      String DEAD_LETTER_QUEUE_TWO_NAME;
      @Value("${data.parking}")
      String PARKING_LOT_QUEUE_NAME;
      @Value("${retry.delay:3000}")
      public long DELAYED_RETRY_TIME;
      @Value("${max.retry:3}")
      public int MAX_RETRY_ATTEMPTS;
  
      @Primary
      @Bean
      Queue queue() {
          return QueueBuilder.durable(INCOMING_QUEUE_NAME)
                  .deadLetterExchange(DEAD_LETTER_EXCHANGE_NAME)
                  .build();
      }
  
      @Bean
      Queue queueTwo() {
          return QueueBuilder.durable(INCOMING_QUEUE_TWO_NAME)
                  .deadLetterExchange(DEAD_LETTER_EXCHANGE_NAME)
                  .build();
      }
  
      @Bean
      Queue deadLetterQueue() {
          return QueueBuilder.durable(DEAD_LETTER_QUEUE_NAME)
                  .deadLetterExchange(EXCHANGE_NAME)
                  .withArgument("x-message-ttl", DELAYED_RETRY_TIME)
                  .build();
      }
  
      @Bean
      Queue deadLetterTwoQueue() {
          return QueueBuilder.durable(DEAD_LETTER_QUEUE_TWO_NAME)
                  .deadLetterExchange(EXCHANGE_NAME)
                  .withArgument("x-message-ttl", DELAYED_RETRY_TIME)
                  .build();
      }
  
      @Bean
      Queue parkingLotQueue() {
          return new Queue(PARKING_LOT_QUEUE_NAME, true);
      }
  
      @Bean
      DirectExchange exchange() {
          return new DirectExchange(EXCHANGE_NAME);
      }
  
      @Bean
      DirectExchange deadLetterExchange() {
          return new DirectExchange(DEAD_LETTER_EXCHANGE_NAME);
      }
  
      @Bean
      Binding binding(@Qualifier("queue") Queue queue, @Qualifier("exchange") DirectExchange exchange) {
          return BindingBuilder.bind(queue).to(exchange).with(INCOMING_QUEUE_NAME);
      }
  
      @Bean
      Binding bindingTwo(@Qualifier("queueTwo") Queue queue, @Qualifier("exchange") DirectExchange exchange) {
          return BindingBuilder.bind(queue).to(exchange).with(INCOMING_QUEUE_TWO_NAME);
      }
  
      @Bean
      Binding deadLetterBinding(@Qualifier("deadLetterQueue") Queue queue, @Qualifier("deadLetterExchange") DirectExchange exchange) {
          return BindingBuilder
                  .bind(queue)
                  .to(exchange).with(INCOMING_QUEUE_NAME);
      }
  
      @Bean
      Binding deadLetterTwoBinding(@Qualifier("deadLetterTwoQueue") Queue queue, @Qualifier("deadLetterExchange") DirectExchange exchange) {
          return BindingBuilder
                  .bind(queue)
                  .to(exchange).with(INCOMING_QUEUE_TWO_NAME);
      }
  
      @Bean
      @Qualifier("myRabbitListenerContainer")
      SimpleMessageListenerContainer myRabbitListenerContainer(ConnectionFactory connectionFactory, @Qualifier("messageListenerAdapter") MessageListenerAdapter listenerAdapter) {
          SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
          container.setConnectionFactory(connectionFactory);
          container.setQueueNames(INCOMING_QUEUE_NAME);
          container.setMessageListener(listenerAdapter);
          return container;
      }
  
      @Bean
      @Qualifier("myRabbitListenerTwoContainer")
      SimpleMessageListenerContainer myRabbitListenerTwoContainer(ConnectionFactory connectionFactory, @Qualifier("messageListenerTwoAdapter") MessageListenerAdapter listenerAdapter) {
          SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
          container.setConnectionFactory(connectionFactory);
          container.setQueueNames(INCOMING_QUEUE_TWO_NAME);
  
          container.setMessageListener(listenerAdapter);
          return container;
      }
  
      @Primary
      @Bean
      MessageListenerAdapter messageListenerAdapter(Receiver receiver) {
          return new MessageListenerAdapter(receiver, "receiveMessage");
      }
  
      @Bean
      MessageListenerAdapter messageListenerTwoAdapter(ReceiverTwo receiverTwo) {
          return new MessageListenerAdapter(receiverTwo, "receiveMessageTwo");
      }
  }
  
  </code></pre>
  
  <p>**And the listener **</p>
  
  <pre><code>package com.poc.failoverretryer.receiver;
  
  import com.poc.failoverretryer.config.RMQConfiguration;
  import com.poc.failoverretryer.model.User;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.amqp.AmqpRejectAndDontRequeueException;
  import org.springframework.amqp.core.Message;
  import org.springframework.amqp.core.MessageListener;
  import org.springframework.amqp.rabbit.annotation.RabbitHandler;
  import org.springframework.amqp.rabbit.annotation.RabbitListener;
  import org.springframework.amqp.rabbit.core.RabbitTemplate;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.messaging.handler.annotation.Header;
  import org.springframework.stereotype.Component;
  
  import java.util.List;
  import java.util.Map;
  import java.util.Optional;
  
  @Component
  public class Receiver {
      Logger logger = LoggerFactory.getLogger(Receiver.class);
      @Autowired
      private RabbitTemplate rabbitTemplate;
      @Value("${max.retry:3}")
      public int MAX_RETRY_ATTEMPTS;
  
      @Value("${data.parking}")
      String PARKING_LOT_QUEUE_NAME;
  
      public void receiveMessage(Message message, @Header(required = false, name = "x-death") List&lt;Map&lt;String, Object&gt;&gt; xDeath) throws InterruptedException {
          System.out.println("Received &lt;" + message + "&gt;");
  
          logger.info(String.valueOf(xDeath));
  
          if (message == null) {
              System.out.println("The message is null");
              return;
          }
          try {
              process(message.getBody());
          } catch (Exception e) {
              if (checkIfNeedToRetry(xDeath))
                  throw new AmqpRejectAndDontRequeueException("Failed to process message");
              else
                  rabbitTemplate.convertAndSend(PARKING_LOT_QUEUE_NAME, message);
          }
      }
  
      private void process(byte[] message) throws Exception {
          throw new Exception("Test");
      }
  
      private boolean checkIfNeedToRetry(List&lt;Map&lt;String, Object&gt;&gt; xDeath) {
          long retryCount = 0L;
          if (xDeath != null) {
              Optional&lt;Long&gt; count = xDeath.stream()
                      .flatMap(m -&gt; m.entrySet().stream())
                      .filter(e -&gt; e.getKey().equals("count"))
                      .findFirst().map(e -&gt; (Long) e.getValue());
  
              retryCount = count.map(Long::longValue).orElse(retryCount);
  //            if (count.isPresent()) {
  //                retryCount = count.get().longValue();
  //                System.out.println("Retry: " + retryCount);
  //            } else {
  //
  //            }
          }
  
          System.out.println(retryCount);
  
          if (retryCount &lt;= MAX_RETRY_ATTEMPTS) {
              System.out.println("Retrying");
  
              return true;
          } else {
              System.out.println("exceed max retry " + retryCount + " -&gt; sending to parking lot");
              return false;
          }
      }
  }
  </code></pre>
  
  <p>When I run this code I get the following <strong>error</strong></p>
  
  <pre><code>org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Failed to invoke target method 'receiveMessage' with argument type = [class com.poc.failoverretryer.model.User], value = [{User{firstname='Jean Elisee', lastname='YAO', dob='13/10/1993'}}]
      at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:405) ~[spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:293) ~[spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1579) ~[spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1498) ~[spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1486) ~[spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1477) ~[spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1421) ~[spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:963) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:913) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:81) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1284) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1190) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at java.lang.Thread.run(Thread.java:748) [na:1.8.0_211]
  Caused by: java.lang.NoSuchMethodException: com.poc.failoverretryer.receiver.Receiver.receiveMessage(com.poc.failoverretryer.model.User)
      at java.lang.Class.getMethod(Class.java:1786) ~[na:1.8.0_211]
      at org.springframework.util.MethodInvoker.prepare(MethodInvoker.java:184) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
      at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:383) ~[spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      ... 12 common frames omitted
  
  2020-05-08 02:58:29.900  WARN 17643 --- [enerContainer-1] ingErrorHandler$DefaultExceptionStrategy : Fatal message conversion error; message rejected; it will be dropped or routed to a dead letter exchange, if so configured: (Body:'[B@1a07a33(byte[148])' MessageProperties [headers={}, contentType=application/x-java-serialized-object, contentLength=0, receivedDeliveryMode=PERSISTENT, priority=0, redelivered=false, receivedExchange=, receivedRoutingKey=data.incoming.q, deliveryTag=1, consumerTag=amq.ctag-m3Q0U6oWC1ejy4TrK16WaA, consumerQueue=data.incoming.q])
  2020-05-08 02:58:29.901 ERROR 17643 --- [enerContainer-1] o.s.a.r.l.SimpleMessageListenerContainer : Execution of Rabbit message listener failed, and the error handler threw an exception
  
  org.springframework.amqp.AmqpRejectAndDontRequeueException: Error Handler converted exception to fatal
      at org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler.handleError(ConditionalRejectingErrorHandler.java:116) ~[spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeErrorHandler(AbstractMessageListenerContainer.java:1383) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.handleListenerException(AbstractMessageListenerContainer.java:1667) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1442) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:963) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:913) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:81) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1284) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1190) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at java.lang.Thread.run(Thread.java:748) [na:1.8.0_211]
  Caused by: org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Failed to invoke target method 'receiveMessage' with argument type = [class com.poc.failoverretryer.model.User], value = [{User{firstname='Jean Elisee', lastname='YAO', dob='13/10/1993'}}]
      at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:405) ~[spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:293) ~[spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1579) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1498) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1486) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1477) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1421) [spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      ... 6 common frames omitted
  Caused by: java.lang.NoSuchMethodException: com.poc.failoverretryer.receiver.Receiver.receiveMessage(com.poc.failoverretryer.model.User)
      at java.lang.Class.getMethod(Class.java:1786) ~[na:1.8.0_211]
      at org.springframework.util.MethodInvoker.prepare(MethodInvoker.java:184) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
      at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:383) ~[spring-rabbit-2.2.5.RELEASE.jar:2.2.5.RELEASE]
      ... 12 common frames omitted
  
  </code></pre>