title: JMS synchronous Request/Reply using temporary queue timed out reading
body: <p>I'm currently having a problem with jms synchronous request/reply approach, this is what happens:</p>
  
  <p>1.) ProgramA create a jms message, a temporary queue and set it as a replyTo.</p>
  
  <p>2.) ProgramB has a listener to the message created from ProgramA, process the message and reply to it. But ProgramB needs to communicate to a 3rd party web service that sometimes takes more than 10seconds to reply, and that is the problem I set the consumer to listen for 5000 (5s) and of course it will timeout afterwards. So the message is not received.</p>
  
  <p>My observation:
  1.) Even though ProgramA is done reading (no reply yet, at that instant I try to delete the temporary queue). It's not able to and ProgramB was still able to write to the reply queue, but nobody's going to read that message (too late).</p>
  
  <p>When I try to change 5s to 20s listen time the problem was solved, but is it the right approach? </p>
  
  <p>Also is it possible for the ProgramB to not try to write to the queue when ProgramA has stop reading?</p>
  
  <p>Partial codes:</p>
  
  <pre><code>Destination replyQueue = send(jmsUtil, actionDTO);
  SalesOrderResponseDTO responseDTO = readReply(jmsUtil, replyQueue, actionDTO);
  
  public Destination send(JmsSessionUtil jmsUtil, SalesOrderActionDTO soDTO) {
      try {
          utx.begin();        
          jmsUtil.send(soDTO, null, 0L, 1, Long.parseLong(configBean.getProperty("jms.payrequest.timetolive")), true);
          utx.commit();
          return jmsUtil.getReplyQueue();
      } catch (Exception e) {
          try {
              utx.rollback();
          } catch (Exception e1) {
  
          }       
      }
      return null;
  }
  
  public SalesOrderResponseDTO readReply(JmsSessionUtil jmsUtil, Destination replyQueue, SalesOrderActionDTO actionDTO) {
      SalesOrderResponseDTO responseDTO = null;
      try {       
          utx.begin();
  
          responseDTO = (SalesOrderResponseDTO) jmsUtil.read(replyQueue);
  
          if (responseDTO != null) {
              // fires the response event
              SalesOrderResponsePayload eventPayload = new SalesOrderResponsePayload();
              eventPayload.setResponseDTO(responseDTO);
              responseEvent.fire(eventPayload);
          } else { // timeout
              ((TemporaryQueue) replyQueue).delete();
              jmsUtil.dispose();
          }
          utx.commit();
          return responseDTO;
      } catch (Exception e) {
          try {
              utx.rollback();
          } catch (Exception e1) {
          }
      }
      return responseDTO;
  }
  
  public String send(MessageDTO messageDTO,
              JMSQueueEnum resultNotificationQueue, Long parentProcessId,
              int JMSPriority, long timeToLive, boolean hasReply)
              throws JMSException, InvalidDTOException, NamingException {
  
      try {
          // Process optional parameters
          messageDTO.setResultNotificationQueue(resultNotificationQueue);
          messageDTO.setParentProcessId(parentProcessId);
  
          // Wrap MessageDTO in a JMS ObjectMessage
          ObjectMessage msg = MessageDTOHelper.serialize(session, messageDTO);
          msg.setJMSType(messageDTO.getClass().getSimpleName());
          msg.setStringProperty("DTOType", messageDTO.getClass()
                  .getSimpleName());
  
          requestProducer = session.createProducer(queue);
  
          if (hasReply) {
              replyQueue = session.createTemporaryQueue();
              replyConsumer = session.createConsumer(replyQueue);     
              msg.setJMSReplyTo(replyQueue);
          }
  
          if (JMSPriority &gt; -1) {
              requestProducer.send(msg, DeliveryMode.PERSISTENT, JMSPriority,
                      timeToLive);
          } else {
              // Send the JMS message
              requestProducer.send(msg);
          }
          return msg.getJMSMessageID();
      } catch (Exception e) {
  
      }
  
      return null;
  }
  
  public MessageDTO read(Destination replyQueue) throws JMSException,
              NamingException {
      if (replyQueue instanceof Queue) {
          Message msg = replyConsumer.receive(20000);
  
          if (msg == null) {
              return null;
          }
  
          MessageDTO messageDTO = MessageDTOHelper
                  .deserialize((ObjectMessage) msg);
  
          return messageDTO;
      } else {
  
      }
      return null;
  }
  </code></pre>