A protobuf message does not have the class name in the data stream. This I think is done because the language of origin can be different than the receiver's language. The receive's end point would expect a given type and have proto generated code to convert it. If you restrict your world to Java on both ends, you could send the class name along with the data. You could even use another proto message to do that. Then assume that all messages are of that type. The real message and type are wrapped up in that message. Then you have the classname and the data. Here's a MessageConverter for Jms that you could grab parts of it that fits your situation.
The proto file
syntax = "proto3";
package jms;
option java_package = "some.package.here.jms";
option java_multiple_files = true;
message AnyMessage{
string classname = 1;
bytes bytesData = 2;
}
The code
@Slf4j
public class ProtobufJmsMessageConverter implements MessageConverter {
@Override
public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
GeneratedMessageV3 protoMsg = (GeneratedMessageV3) object;
AnyMessage wrap = AnyMessage.newBuilder().setClassname(object.getClass().getName()).setBytesData(protoMsg.toByteString()).build();
BytesMessage bytesMessage = session.createBytesMessage();
bytesMessage.writeBytes(wrap.toByteArray());
return bytesMessage;
}
@Override
public Object fromMessage(Message message) throws JMSException, MessageConversionException {
BytesMessage bytesMessage = (BytesMessage) message;
int messageLength = (int) bytesMessage.getBodyLength();
byte[] rawProtoMsg = new byte[messageLength];
bytesMessage.readBytes(rawProtoMsg);
try {
AnyMessage anyMessage = AnyMessage.parseFrom(rawProtoMsg);
Class protoClass = Class.forName(anyMessage.getClassname());
Method m = protoClass.getMethod("parseFrom", byte[].class);
Object result = m.invoke(null, anyMessage.getBytesData().toByteArray());
return result;
} catch (InvalidProtocolBufferException | ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
log.error("",e);
throw new MessageConversionException("Only AnyMessage should be sent.", e);
}
}
}