Search code examples
javajmsoracle-aq

How to tell if a JMS queue is started or stopped?


I have a Java service which is getting messages from an Oracle Advanced Queue. I can create the connection and listen and get messages OK. I can see that you can stop and start listening for messages, so I have implemented controls for that. However, I would like to be able to report on the current status of the listener. I can see if it's there, but how can I tell if it's stopped or started?

I have a container class along the lines of (Listener is my own class (implementing both MessageListener and ExceptionListener) which actually does something with the message)

public class QueueContainer {
  private static final String QUEUE_NAME = "foo";

  private final Connection dbConnection;
  private final QueueConnection queueConnection;
  private final QueueSession queueSession;
  private final Queue queue;
  private final MessageConsumer consumer;
  private final Listener listener;

public QueueContainer(final Connection dbConnection ) {
    try {
      this.dbConnection = dbConnection;
      queueConnection = AQjmsQueueConnectionFactory.createQueueConnection(dbConnection);
      queueSession = queueConnection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
      queue = ((AQjmsSession) queueSession).getQueue(context.getEnvironment(), QUEUE_NAME);
      consumer = queueSession.createConsumer(queue);
      listener = new Listener(QUEUE_NAME);
      consumer.setMessageListener(listener);
      queueConnection.setExceptionListener(listener);
    } catch (JMSException | SQLException e) {
      throw new RunTimeException("Queue Exception", e);
    }
  }
  public void startListening() {
    try {
      queueConnection.start();

    } catch (JMSException e) {
      throw new RunTimeException("Failed to start listening to queue", e);
    }
  }

  public void stopListening() {
    try {
      queueConnection.stop();
    } catch (JMSException e) {
      throw new RunTimeException("Failed to stop listening to queue", e);
    }
  }

  public void close() {
    if (queueConnection != null) {
      try {
        queueConnection.close();
      } catch (JMSException e) {
        throw new RunTimeException("Failed to stop listening to queue", e);
      }
    }
  }

  public boolean isRunning() {
    try {
      // This doesn't work - I can't distinguish between started and stopped
      return queueConnection.getClientID() != null;
    } catch (JMSException e) {
      LOGGER.warn("Failed to get queue client ID", e);
      return false;
    }
  }

I can't see what to put in isRunning that could distinguish between a stopped and started listener


Solution

  • The JMS API assumes you know yourself what you did. So why not add a boolean flag and keep track of this ?

        private volatile boolean isListening = false;
        ...
    
        public void startListening() {
        try {
          queueConnection.start();
          isListening = true;
        } catch (JMSException e) {
          throw new RunTimeException("Failed to start listening to queue", e);
        }
      }
    
      public void stopListening() {
        try {
          queueConnection.stop();
          isListening = false;
        } catch (JMSException e) {
          throw new RunTimeException("Failed to stop listening to queue", e);
        }
      }
    
      public void close() {
        if (queueConnection != null) {
          try {
            queueConnection.close();
            isListening = false;
          } catch (JMSException e) {
            throw new RunTimeException("Failed to stop listening to queue", e);
          }
        }
      }
    
      public boolean isRunning() {
          return isListening;
      }