JMX Management Example

This example shows how to manage ActiveMQ using JMX

Example configuration

ActiveMQ exposes its managed resources by default on the platform MBeanServer.

To access this MBeanServer remotely, the Java Virtual machine must be started with system properties:

             -Dcom.sun.management.jmxremote
             -Dcom.sun.management.jmxremote.port=3000
             -Dcom.sun.management.jmxremote.ssl=false
             -Dcom.sun.management.jmxremote.authenticate=false
        

These properties are explained in the Java 5 Management guide (please note that for this example, we will disable user authentication for simplicity sake).

With these properties, ActiveMQ server will be manageable remotely using standard JMX URL on port 3000.

Example step-by-step

To run the example, simply type mvn verify -Pexample from this directory

  1. First we need to get an initial context so we can look-up the JMS connection factory and destination objects from JNDI. This initial context will get its properties from client-jndi.properties
  2.             InitialContext initialContext = getContext(0);
            
  3. We look up the JMS queue object from JNDI
  4.             Queue queue = (Queue) initialContext.lookup("/queue/exampleQueue");
            
  5. We look up the JMS connection factory object from JNDI
  6.             ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory");
            
  7. We create a JMS connection
  8.             connection = cf.createConnection();
            
  9. We create a JMS session. The session is created as non transacted and will auto acknowledge messages.
  10.             Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            
  11. We create a JMS message producer on the session. This will be used to send the messages.
  12.             MessageProducer messageProducer = session.createProducer(topic);
           
  13. We create a JMS text message that we are going to send.
  14.             TextMessage message = session.createTextMessage("This is a text message");
            
  15. We send message to the queue
  16.             messageProducer.send(message);
            

    Now that we have a message in the queue, we will manage the queue by retrieving the number of messages in the queue (i.e. 1) and by removing the message which has been sent in step 8.

  17. We retrieve the ObjectName corresponding to the queue using a helper class ObjectNameBuilder
  18.               ObjectName on = ObjectNameBuilder.DEFAULT.getJMSQueueObjectName(queue.getQueueName());
            
  19. We create a JMX Connector to connect to the server's MBeanServer using the standard JMX service URL
  20.             JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(JMX_URL), new HashMap());
            
  21. We retrieve a MBeanServerConnection from the JMX connector
  22.            TextMessage messageReceived = (TextMessage) messageConsumer.receive(5000);
            
  23. We create a JMSQueueControl proxy to manage the queue on the server
  24.             JMSQueueControl queueControl = (JMSQueueControl)MBeanServerInvocationHandler.newProxyInstance(mbsc,
                                                                                                  on,
                                                                                                  JMSQueueControl.class,
                                                                                                  false);
                 
            
  25. We use this mbean proxy to retrieve the number of messages in the queue using the getMessageCount method
  26.             System.out.println(queueControl.getName() + " contains " + queueControl.getMessageCount() + " messages");
            
  27. We will now remove the message sent at step 8 using the removeMessage method with the JMS Message ID of the message
  28.             System.out.println("message has been removed: " + queueControl.removeMessage(message.getJMSMessageID()));
            
  29. We use again the mbean proxy to retrieve the number of messages. This time, it will display 0 messages
  30.             System.out.println(queueControl.getName() + " contains " + queueControl.getMessageCount() + " messages");
            
  31. Now we have finish the management operations, we close the JMX connector
  32.             connector.close()
            

    We will now try to consume the message sent to the queue but it won't be there: it has been removed by the management operation

  33. We create a JMS message consumer on the queue
  34.             MessageConsumer messageConsumer = session.createConsumer(queue);
            
  35. We start the connection. In order for delivery to occur on any consumers or subscribers on a connection, the connection must be started
  36.             connection.start();
            
  37. We try to receive a message from the queue. Since there is none, the call will timeout after 5000ms and messageReceived will be null
  38.             TextMessage messageReceived = (TextMessage) messageConsumer.receive(5000);
                System.out.println("Received message: " + messageReceived);
            
  39. And finally, always remember to close your JMS connections and resources after use, in a finally block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects
  40.            finally
               {
                  if (initialContext != null)
                  {
                    initialContext.close();
                  }
                  if (connection != null)
                  {
                     connection.close();
                  }
               }
            

More information