Search code examples
jmsactivemq-classicbroker

JMS Broker receives the message as null


I have a C++ component which passes message to JMS broker via tcp using ActiveMQ. My broker is written in JAVA. I want these two to communicate; to C++ component send messages to the JAVA broker.

On C++ side what I am doing is creating a message (using protocol buffer), converting that to vector of bytes and passing it to the broker. On JAVA side (broker), I am constantly listening and acting upon a received message.

Now, I can tell that the system somehow works, since when I execute my C++ component (and when it passes the messages), I see my JAVA broker printing an error message: unexpected error:null per each message that I am sending from my C++ component. This means that at least my messages do reach to the broker, but somehow they cannot be decrypted, hence the null issue.

I am using the following for composing the message from C++ side:

            // convert pointmsg to byte
            int size = pointmsg.ByteSize();
            char* byteArray = new char[size];
            pointmsg.SerializeToArray(byteArray, size);

            // convert bytearray to vector
            vector<unsigned char> v(byteArray, byteArray + sizeof byteArray / sizeof byteArray[0]);

            // pass as a vector
            BytesMessage *message = session->createBytesMessage();
            message->writeBytes(v);
            producer->send(message);
            printf("Sent message #%d from thread %s\n", ix + 1, threadIdStr.c_str());

pointmsg is just an object that I create and fill in, and it is not null, I tested it already and it has data in it. I am converting pointmsg to byte array since this is the way to pass an object as far as I read in the documantation. And since the writeBytes() function expects a vector, I am converting the byte array into a vector. I suspect there might be some problem in this part.

On JMS side I am simply listening the upcoming messages with:

public void onMessage(final javax.jms.Message message) {
    final Timer traceTimer = new Timer();
    final long messageReceived = System.currentTimeMillis();
    try {
        if (message instanceof ActiveMQBytesMessage) {

            final ActiveMQBytesMessage amqBytesMsg = (ActiveMQBytesMessage) message;
            final byte[] buffer = amqBytesMsg.getContent().data;

            final String msgType = amqBytesMsg.getStringProperty(LLCom.MSG_PROP_CLASS_NAME);
            final String topic = amqBytesMsg.getStringProperty(LLCom.MSG_PROP_TOPIC_NAME);
            String msgLookUpType;
            if (topic == null || topic.isEmpty()) {
                // get message class name: foo.bar$MessageMsg
                msgLookUpType = msgType.split("\\$")[1];
            } else {
                // it's a topic we assume, that all subscribers have the
                // correct type
                msgLookUpType = topic;
            }
            if (logger.isDebugEnabled())
                logger.debug("Router(" + name + ") received message ( " + buffer.length + "bytes)of type or topic " + msgLookUpType);

            final Message req = parsers.createMessage(buffer, msgType);

            // process explicit topic/queue subscriber
            processServiceMessage(msgLookUpType, messageReceived, amqBytesMsg, req, traceTimer);

        } else {
            logger.error("Not supported JMS MessageType: " + message);
        }
    } catch (final Exception e) {
        logger.error("Unexpected error: " + e.getMessage());
        // e.printStackTrace();
    }
}

When I debug it I can see that msgType and topic variables (on JMS side) are coming as null, which means that activemq message is somehow not decrypted. What could be the reason for that? I can see the message is being sent, received but not understood.

Any thoughts?

Update: I noticed that I am expecting to get stringProperties on JMS side, which I am not setting on C++ side, but I am not sure whether it causes the problem or not.


Solution

  • Ok, It seems the error was related to set properties, msgType and topic, I gave them the expected strings with using setStringProperty() on C++ side with the required methods, and now that initial error is gone.

    message->setStringProperty();