The answer may be a bit belated, but maybe it still helps someone.
In the current version of protocol buffers, 3 pack and unpack are available in Java .
In your example, packaging can be done as follows:
Any anyMessage = Any.pack(protoMess.build()));
And unpack as:
ProtoMess protoMess = anyMessage.unpack(ProtoMess.class);
Here is also a complete example of processing protocol buffer messages with nested Any messages:
Buffers Files
A simple protocol buffer file with an Any message attached may look like this:
syntax = "proto3"; import "google/protobuf/any.proto"; message ParentMessage { string text = 1; google.protobuf.Any childMessage = 2; }
A possible attached message may be as follows:
syntax = "proto3"; message ChildMessage { string text = 1; }
Packaging
To create a complete message, you can use the following function:
public ParentMessage createMessage() {
Unpacking
To read the child message from the parent message, you can use the following function:
public ChildMessage readChildMessage(ParentMessage parentMessage) { try { return parentMessage.getChildMessage().unpack(ChildMessage.class); } catch (InvalidProtocolBufferException e) { e.printStackTrace(); return null; } }
EDIT:
If your packed messages can have different types, you can read typeUrl and use reflection to unpack the message. Assuming you have child messages ChildMessage1 and ChildMessage2 , you can do the following:
@SuppressWarnings("unchecked") public Message readChildMessage(ParentMessage parentMessage) { try { Any childMessage = parentMessage.getChildMessage(); String clazzName = childMessage.getTypeUrl().split("/")[1]; String clazzPackage = String.format("package.%s", clazzName); Class<Message> clazz = (Class<Message>) Class.forName(clazzPackage); return childMessage.unpack(clazz); } catch (ClassNotFoundException | InvalidProtocolBufferException e) { e.printStackTrace(); return null; } }
For further processing, you can determine the type of message with instanceof , which is not very efficient. If you want to receive a message of a certain type, you must directly compare typeUrl :
public ChildMessage1 readChildMessage(ParentMessage parentMessage) { try { Any childMessage = parentMessage.getChildMessage(); String clazzName = childMessage.getTypeUrl().split("/")[1]; if (clazzName.equals("ChildMessage1")) { return childMessage.unpack("ChildMessage1.class"); } return null } catch (InvalidProtocolBufferException e) { e.printStackTrace(); return null; } }