I have a topic set up with using Camel and ActiveMQ which receives messages as a byte array of a protobuf.
The receive route looks like this:
<route>
<from uri="jmsComponent:topic:{{heartbeat}}" />
<unmarshal>
<protobuf instanceClass="protobuf.HeartbeatProto" />
</unmarshal>
<to uri="bean:heartbeatConsumer" />
</route>
The heartbeatConsumer only has one method that takes the POJO version of a Heartbeat. In order for this to work, I have a type converter that converts to/from POJO to protobuf.
This works very well and Camel is able to take the byte array and pass it to the heartbeatConsumer as a POJO.
My issue comes with the sender. I have my sending route setup as:
<route>
<from uri="quartz2://heartbeatJob?cron=0/30+*+*+*+*+?" />
<to uri="bean:heartbeat?method=sendHeartbeat" />
<marshal>
<protobuf instanceClass="protobuf.HeartbeatProto" />
</marshal>
<to uri="jmsComponent:topic:{{heartbeat}}" />
</route>
It gives me the exception: 'java.lang.ClassCastException: protobuf.HeartbeatProto cannot be cast to com.google.protobuf.Message'
Why would it be able to automatically type converter in the receive route, but not in the sending route?
Marshalling Java classes to a protobuf payload only works correctly with Java classes implementing the com.google.protobuf.Message
interface as can be seen digging into the source code of org.apache.camel.dataformat.protobuf.ProtobufDataFormat
( here ):
public void marshal(Exchange exchange, Object graph, OutputStream outputStream) throws Exception {
((Message)graph).writeTo(outputStream); // <- here the ClassCastException occurs!
}
As stated at the Camel doc , you should start with a .proto
definition file that is compiled with protoc --java_out=. ./protobuf.HeartbeatProto
protoc --java_out=. ./protobuf.HeartbeatProto
to a Java class implementing the desired interface.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.