Compatibility between Protobuf and Protostuff

Laures picture Laures · Jul 3, 2012 · Viewed 8k times · Source

are Classes generated by the Protostuff code generator compatible with those created by Protobuf?

I tried to (de)serialize some simple messages and got several exceptions:

Proto-File (WrapperClass.proto)

package tutorial;
option java_package = "com.example.tutorial";
message ProjectId {
    required int32 id = 1;
}
message UserId {
    required ProjectId project = 1;
    required int32 projectUserId = 2;
}
message ChannelId {
    required ProjectId project = 1;
    required string name = 2;
}

Protostuff to Protobuf Test (example)

ProjectId projectId = new ProjectId(1);
byte[] projectarray = ProtostuffIOUtil.toByteArray(projectId, ProjectId.getSchema(), buffer);
com.example.tutorial.WrapperClass.ProjectId returnBufProject = com.example.tutorial.WrapperClass.ProjectId.parseFrom(projectarray);

Problem:

Everything works for ProjectId, but for UserId and ChannelId (everything a little bit more complex), i get:

com.google.protobuf.InvalidProtocolBufferException: Message missing required fields: project
    at com.google.protobuf.UninitializedMessageException.asInvalidProtocolBufferException(UninitializedMessageException.java:81)
    at com.example.tutorial.WrapperClass$ChannelId$Builder.buildParsed(Test.java:1278)
    at com.example.tutorial.WrapperClass$ChannelId$Builder.access$17(Test.java:1273)
    at com.example.tutorial.WrapperClass$ChannelId.parseFrom(Test.java:1142)
    ...

And the other way around:

Protobuf to Protostuff Test (example)

com.example.tutorial.WrapperClass.ProjectId projectId2 = com.example.tutorial.WrapperClass.ProjectId.newBuilder().setId(1).build();
byte[] project2array = projectId2.toByteArray();
ProjectId returnStufProject = new ProjectId();
ProtostuffIOUtil.mergeFrom(project2array, returnStufProject, ProjectId.getSchema());

Problem

again, for everything other than the ProjectId, there is an exception:

java.lang.RuntimeException: Reading from a byte array threw an IOException (should never happen).
    at com.dyuproject.protostuff.IOUtil.mergeFrom(IOUtil.java:53)
    at com.dyuproject.protostuff.ProtostuffIOUtil.mergeFrom(ProtostuffIOUtil.java:96)
    at JacksonTest.main(JacksonTest.java:92)
Caused by: com.dyuproject.protostuff.ProtobufException: Protocol message contained an invalid tag (zero).
    at com.dyuproject.protostuff.ProtobufException.invalidTag(ProtobufException.java:98)
    at com.dyuproject.protostuff.ByteArrayInput.readFieldNumber(ByteArrayInput.java:220)
    at com.example.tutorial.ProjectId$1.mergeFrom(ProjectId.java:115)
    at com.example.tutorial.ProjectId$1.mergeFrom(ProjectId.java:1)
    at com.dyuproject.protostuff.ByteArrayInput.mergeObjectEncodedAsGroup(ByteArrayInput.java:390)
    at com.dyuproject.protostuff.ByteArrayInput.mergeObject(ByteArrayInput.java:362)
    at com.example.tutorial.UserId$1.mergeFrom(UserId.java:138)
    at com.example.tutorial.UserId$1.mergeFrom(UserId.java:1)
    at com.dyuproject.protostuff.IOUtil.mergeFrom(IOUtil.java:43)
    ... 2 more

Am i trying something impossible or do i only do something wrong?

Answer

Laures picture Laures · Jul 4, 2012

The problem was simple: Instead of using ProtostuffIOUtil to (de)serialize my messages i need to use ProtobufIOUtil