@Test
 public void testFailureAndRecovery() throws Exception {
   final RetryTemplate retryTemplate = new RetryTemplate();
   retryTemplate.setRetryPolicy(new NeverRetryPolicy());
   container.setMessageListener(
       new MessageListener() {
         @Override
         public void onMessage(final Message msg) {
           try {
             RetryCallback<Message> callback =
                 new RetryCallback<Message>() {
                   @Override
                   public Message doWithRetry(RetryContext context) throws Exception {
                     try {
                       processed.add(((TextMessage) msg).getText());
                     } catch (JMSException e) {
                       throw new IllegalStateException(e);
                     }
                     throw new RuntimeException("planned failure: " + msg);
                   }
                 };
             RecoveryCallback<Message> recoveryCallback =
                 new RecoveryCallback<Message>() {
                   @Override
                   public Message recover(RetryContext context) {
                     try {
                       recovered.add(((TextMessage) msg).getText());
                     } catch (JMSException e) {
                       throw new IllegalStateException(e);
                     }
                     return msg;
                   }
                 };
             retryTemplate.execute(
                 callback, recoveryCallback, new DefaultRetryState(msg.getJMSMessageID()));
           } catch (Exception e) {
             throw (RuntimeException) e;
           }
         }
       });
   container.initializeProxy();
   container.start();
   jmsTemplate.convertAndSend("queue", "foo");
   assertEquals("foo", processed.poll(5, TimeUnit.SECONDS));
   assertEquals("foo", recovered.poll(5, TimeUnit.SECONDS));
 }
 @After
 @Before
 public void drainQueue() throws Exception {
   container.stop();
   while (jmsTemplate.receiveAndConvert("queue") != null) {
     // do nothing
   }
   processed.clear();
 }
 @Test
 public void testFailureAndRepresent() throws Exception {
   container.setMessageListener(
       new MessageListener() {
         @Override
         public void onMessage(Message msg) {
           try {
             processed.add(((TextMessage) msg).getText());
           } catch (JMSException e) {
             throw new IllegalStateException(e);
           }
           throw new RuntimeException("planned failure for represent: " + msg);
         }
       });
   container.initializeProxy();
   container.start();
   jmsTemplate.convertAndSend("queue", "foo");
   for (int i = 0; i < 2; i++) {
     assertEquals("foo", processed.poll(5, TimeUnit.SECONDS));
   }
 }
 @Test
 public void testSendAndReceive() throws Exception {
   container.setMessageListener(
       new MessageListener() {
         @Override
         public void onMessage(Message msg) {
           try {
             processed.add(((TextMessage) msg).getText());
           } catch (JMSException e) {
             throw new IllegalStateException(e);
           }
         }
       });
   container.initializeProxy();
   container.start();
   jmsTemplate.convertAndSend("queue", "foo");
   jmsTemplate.convertAndSend("queue", "bar");
   SortedSet<String> result = new TreeSet<String>();
   for (int i = 0; i < 2; i++) {
     result.add(processed.poll(5, TimeUnit.SECONDS));
   }
   assertEquals("[bar, foo]", result.toString());
 }