Search code examples
javajmxactivemq-artemis

How to translate CompositeData[] class objects into Message class objects in ActiveMQ Artemis JMX?


I'm using JMX to connect to an ActiveMQ Artemis queue via the QueueControl class and its browse method, which returns a CompositeData array, but I can't get the individual headers with the get methods as there aren't any. Please tell me how to get not the whole body of the headers, but certain fields via JMX on Artemis

I also tried the listMessage method, but it gives an incomplete list of headers and does not display the body of the message


Solution

  • The key to getting the message details out of the CompositeData is the CompositeDataConstants class.

    If I sent a message like this:

          ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
          Connection connection = connectionFactory.createConnection();
          Session session = connection.createSession();
          MessageProducer messageProducer = session.createProducer(session.createQueue("myQueue"));
          TextMessage message = session.createTextMessage();
          message.setJMSReplyTo(session.createQueue("myReplyTo"));
          message.setText("myText");
          message.setStringProperty("myKey1", "myValue1");
          message.setStringProperty("myKey2", "myValue2");
          messageProducer.send(message);
          connection.close();
    

    You could browse the queue and deserialize the message data, e.g.:

          QueueControl queueControl = ...
          CompositeData[] messages = queueControl.browse();
          for (CompositeData message : messages) {
             System.out.println("JMSMessageID: " + message.get(CompositeDataConstants.USER_ID));
             System.out.println("Destination: " + message.get(CompositeDataConstants.ADDRESS));
             System.out.println("Text: " + message.get(CompositeDataConstants.TEXT_BODY));
             System.out.println("DeliveryMode: " + ((Boolean) message.get(CompositeDataConstants.DURABLE) ? "persistent" : "non-persistent"));
             TabularData stringProps = (TabularData) message.get(CompositeDataConstants.STRING_PROPERTIES);
             for (CompositeData o : (Collection<CompositeData>) stringProps.values()) {
                System.out.println(o.get("key") + ": " + o.get("value"));
             }
          }
    

    Which would print something like this:

    JMSMessageID: ID:41171b0e-dfae-11ed-9217-3ce1a1d12939
    Destination: myQueue
    Text: myText
    DeliveryMode: persistent
    JMSReplyTo: queue://myReplyTo
    myKey1: myValue1
    myKey2: myValue2
    __AMQ_CID: 41123909-dfae-11ed-9217-3ce1a1d12939
    

    If you don't want to use the constants directly you can find their respective values here.

    Keep in mind that the returned data may be truncated due to the management-message-attribute-size-limit. The documentation explains this setting:

    management-message-attribute-size-limit is the number of bytes collected from the message for browse. This is relevant for the browse and list management methods exposed on the queue control. Message attributes longer than this value appear truncated. Default is 256. Use -1 to switch this limit off. Note that memory needs to be allocated for all messages that are visible at a given moment. Setting this value too high may impact the browser stability due to the large amount of memory that may be required to browse through many messages.