jackson-dataformats-binary icon indicating copy to clipboard operation
jackson-dataformats-binary copied to clipboard

[protobuf] ObjectWriter fails to serialize depends on the order of messages

Open knoguchi opened this issue 7 years ago • 1 comments

ObjectWriter fails to serialize depends on the order of messages defined in a proto file.

proto1 below works fine.

// proto1
message Main {
  required Other o = 1;
}
message Other {
  required int32 f = 1;
}

proto2 below fails. The only difference is the order of message types.

// proto2
message Other {
  required int32 f = 1;
}
message Main {
  required Other o = 1;
}

Stack trace

com.fasterxml.jackson.core.JsonGenerationException: Unrecognized field 'o' (in Message of type Other); known fields are: [Field 'f', tag=8, wireType=0, fieldType=VINT32_STD]

	at com.fasterxml.jackson.core.JsonGenerator._reportError(JsonGenerator.java:1914)
	at com.fasterxml.jackson.dataformat.protobuf.ProtobufGenerator.writeFieldName(ProtobufGenerator.java:299)
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:725)
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:716)
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:481)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:401)
	at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1392)
	at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1120)
	at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsBytes(ObjectWriter.java:1017)
	at com.fasterxml.jackson.dataformat.protobuf.schema.MessageResolutionTest.serializeTest(MessageResolutionTest.java:85)

Here is the test case.

knoguchi avatar May 14 '17 19:05 knoguchi

This may be because in absence of specification of the root type (and since protobuf format has no concept of root type id, as far as I know), the first message type is assumed to be the root.

Now... it is possible to specify one of the other message types to be the root to use, with:

ProtobufSchema schema = schema.withRootType("Main")

This may not be the most obvious API design, but since I don't know of other ways to specify which of multiple message types user wants, there has to be something to design it.

One alternative would also to throw an exception if schema has multiple possible message types, and user does not explicitly specify one to use.

cowtowncoder avatar May 22 '17 19:05 cowtowncoder