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.
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();