1
votes

I'm using ActiveMQ 5.9.0 for sending and receiving JMS. First I send MapMessage in a queue:

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory();

Connection connection = connectionFactory.createConnection();
connection.start();

Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("my-queue");

MessageProducer producer = session.createProducer(destination);
MapMessage message = session.createMapMessage();
message.setDouble(key, value);
producer.send(message);
session.commit();
session.close();
connection.close();
System.out.println(message);

What it prints out is:

ActiveMQMapMessage {commandId = 0, responseRequired = false, messageId = ID:LT006632-52708-1382520875674-11:1:1:1:1, originalDestination = null, originalTransactionId = null, producerId = null, destination = queue://my-queue, transactionId = TX:ID:LT006632-52708-1382520875674-11:1:1, expiration = 0, timestamp = 1382520891291, arrival = 0, brokerInTime = 0, brokerOutTime = 0, correlationId = null, replyTo = null, persistent = true, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@33cf4, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = false, readOnlyBody = false, droppable = false, jmsXGroupFirstForConsumer = false} ActiveMQMapMessage{ theTable = {entry 6=922.0} }

with a correct theTable in the Message.

It receives message in another project in this way:

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory();

Connection connection = connectionFactory.createConnection();
connection.start();

final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("my-queue");

MessageConsumer consumer = session.createConsumer(destination);

consumer.setMessageListener(new MessageListener() {

    public void onMessage(Message msg) {
        MapMessage message = (MapMessage) msg;
        // TODO something....
        try {
            System.out.println(message.getJMSType());
            session.commit();
        } catch (JMSException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

});
Thread.sleep(30000);

session.close();
connection.close();

But on receiving the messages it prints out:

ActiveMQMapMessage {commandId = 6, responseRequired = false, messageId = ID:LT006632-52708-1382520875674-11:1:1:1:1, originalDestination = null, originalTransactionId = null, producerId = ID:LT006632-52708-1382520875674-11:1:1:1, destination = queue://my-queue, transactionId = TX:ID:LT006632-52708-1382520875674-11:1:1, expiration = 0, timestamp = 1382520891291, arrival = 0, brokerInTime = 1382520891291, brokerOutTime = 1382520891298, correlationId = null, replyTo = null, persistent = true, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@186db54, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false} ActiveMQMapMessage{ theTable = {} }

With an empty theTable item. I'd like to know what's the cause of it and how to solve this problem. Thanks!

2

2 Answers

3
votes

We use ActiveMQ 5.8.0, but have same "problem": logging message after receiving doesn't print out 'theTable' entries.

BUT after parsing the map message and logging it again, it DOES print 'theTable' entries!

It seems that you somehow have to 'touch' the message or access its content to print 'theTable' entries. That works at least for us.

3
votes

The above answer is correct. I will elaborate a bit on why it works this way.

The contents of the MapMessage map (theMap) are marshalled to a smaller binary form for transmission, which can even be compressed based on settings of the OpenWire protocol. The map values are only lazily unmarshalled when the map elements are accessed which is why the log statements don't show them on the receiver side. There are a number of reasons for doing this.

On the Broker side you don't really want to spend a lot of time logging all the map elements just to have some simple logs showing messages passing through the broker, plus you don't want to pack and unpack this map that often as it can add a bit of overhead.

The same thing also applies on the client side where some Messages could be ignored based on message properties etc so you'd prefer to not add the overhead of unmarshaling the map for no reason.