@Test
 public void testContainerBeanNameWhenNoGatewayBeanName() {
   JmsOutboundGateway gateway = new JmsOutboundGateway();
   gateway.setConnectionFactory(mock(ConnectionFactory.class));
   gateway.setRequestDestinationName("foo");
   gateway.setUseReplyContainer(true);
   gateway.setReplyContainerProperties(new ReplyContainerProperties());
   gateway.afterPropertiesSet();
   assertEquals(
       "JMS_OutboundGateway@" + ObjectUtils.getIdentityHexString(gateway) + ".replyListener",
       TestUtils.getPropertyValue(gateway, "replyContainer.beanName"));
 }
  @Test
  public void testReplyContainerRecovery() throws Exception {
    JmsOutboundGateway gateway = new JmsOutboundGateway();
    ConnectionFactory connectionFactory = mock(ConnectionFactory.class);
    gateway.setConnectionFactory(connectionFactory);
    gateway.setRequestDestinationName("foo");
    gateway.setUseReplyContainer(true);
    ReplyContainerProperties replyContainerProperties = new ReplyContainerProperties();
    final List<Throwable> errors = new ArrayList<Throwable>();
    ErrorHandlingTaskExecutor errorHandlingTaskExecutor =
        new ErrorHandlingTaskExecutor(
            Executors.newFixedThreadPool(10),
            new ErrorHandler() {

              @Override
              public void handleError(Throwable t) {
                logger.info("Error:", t);
                errors.add(t);
                throw new RuntimeException(t);
              }
            });
    replyContainerProperties.setTaskExecutor(errorHandlingTaskExecutor);
    replyContainerProperties.setRecoveryInterval(100L);
    gateway.setReplyContainerProperties(replyContainerProperties);
    final Connection connection = mock(Connection.class);
    final AtomicInteger connectionAttempts = new AtomicInteger();
    doAnswer(
            new Answer<Connection>() {

              @SuppressWarnings("serial")
              @Override
              public Connection answer(InvocationOnMock invocation) throws Throwable {
                int theCount = connectionAttempts.incrementAndGet();
                if (theCount > 1 && theCount < 4) {
                  throw new JmsException("bar") {};
                }
                return connection;
              }
            })
        .when(connectionFactory)
        .createConnection();
    Session session = mock(Session.class);
    when(connection.createSession(false, 1)).thenReturn(session);
    MessageConsumer consumer = mock(MessageConsumer.class);
    when(session.createConsumer(any(Destination.class), anyString())).thenReturn(consumer);
    when(session.createTemporaryQueue()).thenReturn(mock(TemporaryQueue.class));
    final Message message = mock(Message.class);
    final AtomicInteger count = new AtomicInteger();
    doAnswer(
            new Answer<Message>() {

              @SuppressWarnings("serial")
              @Override
              public Message answer(InvocationOnMock invocation) throws Throwable {
                int theCount = count.incrementAndGet();
                if (theCount > 1 && theCount < 4) {
                  throw new JmsException("foo") {};
                }
                if (theCount > 4) {
                  Thread.sleep(100);
                  return null;
                }
                return message;
              }
            })
        .when(consumer)
        .receive(anyLong());
    when(message.getJMSCorrelationID()).thenReturn("foo");
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
    taskScheduler.initialize();
    beanFactory.registerSingleton("taskScheduler", taskScheduler);
    gateway.setBeanFactory(beanFactory);
    gateway.afterPropertiesSet();
    gateway.start();
    try {
      int n = 0;
      while (n++ < 100 && count.get() < 5) {
        Thread.sleep(100);
      }
      assertTrue(count.get() > 4);
      assertEquals(0, errors.size());
    } finally {
      gateway.stop();
    }
  }