title: JmsTemplate with CachingConnectionFactory Connection Recovery for IBM MQ Queue
body: <p>I am connecting to two IBM MQ servers from a same client using JmsTemplate. </p>
  
  <p>I have configured JmsTemplate's reconnectOnException as well as IBM MQ connection factory's setClientReconnectOptions. </p>
  
  <p>Spring bean definition: </p>
  
  <pre><code>&lt;bean id="firstMQCachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"&gt;
          &lt;property name="targetConnectionFactory" ref="firstMQConnectionFactory" /&gt;
          &lt;property name="sessionCacheSize" value="20" /&gt; 
          &lt;property name="reconnectOnException" value="true"/&gt;
  &lt;/bean&gt;
  
  &lt;bean id="secondMQCachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"&gt;
          &lt;property name="targetConnectionFactory" ref="secondMQConnectionFactory" /&gt;
          &lt;property name="sessionCacheSize" value="20" /&gt; 
          &lt;property name="reconnectOnException" value="true"/&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>Set IBM MQ reconnect options:</p>
  
  <pre><code>firstMQConnectionFactory.setClientReconnectOptions(WMQConstancs.WMQ_CLIENT_RECONNECT;
  firstMQConnectionFactory.setClientReconnectTimeout(5);
  secondMQConnectionFactory.setClientReconnectOptions(WMQConstancs.WMQ_CLIENT_RECONNECT;
  secondMQConnectionFactory.setClientReconnectTimeout(5);
  </code></pre>
  
  <p>This is how I am sending message: </p>
  
  <pre><code>public boolean sendMsg(final String content) throws JmsException{
      boolean success = false;
      LOGGER.info("sendMsg: Start ") ;
      try { 
          jmsTemplate.send(new MessageCreator() {
              @Override
              public Message createMessage(Session session) throws JMSException {
                  TextMessage textMessage = session.createTextMessage(content);
                  textMessage.setStringProperty(WMQConstants.JMS_IBM_CHARACTER_SET,  "UTF8");
                  textMessage.setIntProperty(WMQConstants.JMS_IBM_ENCODING,
                          WMQConstants.WMQ_ENCODING_NATIVE);
                  textMessage.setJMSDeliveryMode(DeliveryMode.PERSISTENT);
                  return textMessage;
              }
          });
          LOGGER.info("sendMsg: Message sent to MQ successfully");
          success = true;
      } catch (JmsException je) {
          LOGGER.error("sendMsg: JmsException " + je.getMessage());
          throw je;
      } catch (Exception exc) {
          LOGGER.error("sendMsg: Exception message: " + exc.getMessage());
          throw exc;
      }
      return success; 
  }
  </code></pre>
  
  <p>When none of the connections is being used during low system load, a broken connection to first system is detected by Spring.</p>
  
  <pre><code>18 Nov 2017 20:41:03,924 WARN CachingConnectionFactory:322 - Encountered a JMSException - resetting the underlying JMS Connection
  com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ1107: A problem with this connection has occurred.
  Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2009' ('MQRC_CONNECTION_BROKEN').
  18 Nov 2017 20:41:03,940 DEBUG CachingConnectionFactory:486 - Closing cached Session: com.ibm.mq.jms.MQQueueSession@4cbb56ac
  18 Nov 2017 20:41:04,006 DEBUG CachingConnectionFactory:447 - Closing shared JMS Connection: com.ibm.mq.jms.MQQueueConnection@48d23557
  18 Nov 2017 20:41:04,008 DEBUG CachingConnectionFactory:463 - Could not close shared JMS Connection
  com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ0019: Failed to disconnect from queue manager 'QM1' using connection mode '1' and host name 'system1.company.com(62305)'.
  Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2009' ('MQRC_CONNECTION_BROKEN').
  Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2009;AMQ9208: Error on receive from host 'system1.company.com/10.0.0.1:62305 (system1.company.com)'. [1=-1,2=ffffffff,3=system1.company.com/10.0.0.1:62305 (system1.company.com),4=TCP]
  </code></pre>
  
  <p>This somehow affects JmsTemplate connection to second system and when used I get an exception with no message.</p>
  
  <pre><code>18 Nov 2017 23:43:40,247 DEBUG JmsTemplate:482 - Executing callback on JMS Session: Cached JMS Session: com.ibm.mq.jms.MQQueueSession@5a4a62d0
  18 Nov 2017 23:43:40,248 DEBUG JmsTemplate:595 - Sending created message: 
  18 Nov 2017 23:43:40,251 ERROR MessageSender:86 - sendMsg: Exception message: null
  </code></pre>
  
  <p>Stack trace</p>
  
  <pre><code>java.lang.NullPointerException
      at com.ibm.mq.jmqi.remote.impl.RemoteSession.checkIfDisconnected(RemoteSession.java:249)
      at com.ibm.mq.jmqi.remote.api.RemoteFAP.jmqiPutMessageWithProps(RemoteFAP.java:9045)
      at com.ibm.mq.jmqi.remote.api.RemoteFAP.jmqiPut(RemoteFAP.java:8115)
      at com.ibm.mq.ese.jmqi.InterceptedJmqiImpl.jmqiPut(InterceptedJmqiImpl.java:624)
      at com.ibm.mq.ese.jmqi.ESEJMQI.jmqiPut(ESEJMQI.java:635)
      at com.ibm.msg.client.wmq.internal.WMQMessageProducer$SpiIdentifiedProducerShadow.sendInternal(WMQMessageProducer.java:864)
      at com.ibm.msg.client.wmq.internal.WMQMessageProducer$ProducerShadow.send(WMQMessageProducer.java:548)
      at com.ibm.msg.client.wmq.internal.WMQMessageProducer.send(WMQMessageProducer.java:1393)
      at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.sendMessage(JmsMessageProducerImpl.java:851)
      at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.synchronousSendInternal(JmsMessageProducerImpl.java:2051)
      at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.sendInternal(JmsMessageProducerImpl.java:1989)
      at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.send(JmsMessageProducerImpl.java:1569)
      at com.ibm.mq.jms.MQMessageProducer.send(MQMessageProducer.java:321)
      at org.springframework.jms.connection.CachedMessageProducer.send(CachedMessageProducer.java:181)
      at sun.reflect.GeneratedMethodAccessor120.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at org.springframework.jms.connection.CachedMessageProducer$Jms2MessageProducerInvocationHandler.invoke(CachedMessageProducer.java:293)
      at com.sun.proxy.$Proxy59.send(Unknown Source)
      at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:626)
      at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:597)
      at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:562)
      at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:484)
      at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:559)
      at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:550)
  </code></pre>
  
  <ul>
  <li>Why does broken connection for one CachingConnectionFactory affect
  another? </li>
  <li>Why does second connection not recover from 'Exception' once
  it detects it? </li>
  <li>Do I need to wrap Exception in JmsException for spring jms to detect it?</li>
  </ul>