Actually, it happens even if I don't add isFeatured. Is there something incompatible due to the different namespace?
From: Francois Forster [mailto:[email protected]] Sent: Wednesday, December 07, 2011 2:53 PM To: [email protected] Subject: AvroTypeException thrown with version change on optional record Hi, I'm trying to test versioning in Avro data serialization and I'm seeing an AvroTypeException thrown when I add a new field to an optional record. Here's the V1 schema: @namespace("v1") protocol Service { record Result { string id; string text; boolean isRecommended; } record Response { int version; boolean success; union {null, Result} results; } } V2 (added isFeatured to Result): @namespace("v2") protocol Service { record Result { string id; string text; boolean isRecommended; boolean isFeatured; } record Response { int version; boolean success; union {null, Result} results; } } Here's the code: import org.apache.avro.Protocol; import org.apache.avro.io.BinaryDecoder; import org.apache.avro.io.BinaryEncoder; import org.apache.avro.io.DecoderFactory; import org.apache.avro.io.EncoderFactory; import org.apache.avro.specific.SpecificDatumReader; import org.apache.avro.specific.SpecificDatumWriter; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; public class AvroServiceMain { public static void main(String[] args) throws Exception { Protocol protocol_v2 = Protocol.parse(new File("TestCase_v2.avdr")); Protocol protocol_v1 = Protocol.parse(new File("TestCase_v1.avdr")); SpecificDatumWriter< v2.Response> responseSerializer = new SpecificDatumWriter< v2.Response>(protocol_v2.getType("Response")); SpecificDatumReader< v1.Response> responseDeserializer = new SpecificDatumReader< v1.Response>(protocol_v2.getType("Response"),protocol_v1.getType("Response")); v2.Response responseV2 = new v2.Response(); responseV2.setVersion(2); responseV2.setSuccess(true); v2.Result result = new v2.Result(); result.setId("1234"); result.setIsRecommended(false); result.setIsFeatured(true); result.setText("Some text..."); responseV2.setResults(result); ByteArrayOutputStream baos = new ByteArrayOutputStream(); BinaryEncoder encoder = EncoderFactory.get().directBinaryEncoder(baos, null); responseSerializer.write(responseV2, encoder); byte[] bytes = baos.toByteArray(); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); BinaryDecoder decoder = DecoderFactory.get().directBinaryDecoder(bais, null); v1.Response responseV1 = new v1.Response(); responseDeserializer.read(responseV1, decoder); System.out.println(responseV1); } } Here's the exception thrown: Exception in thread "main" org.apache.avro.AvroTypeException: Found { "type" : "record", "name" : "Result", "namespace" : "v2", "fields" : [ { "name" : "id", "type" : "string" }, { "name" : "text", "type" : "string" }, { "name" : "isRecommended", "type" : "boolean" }, { "name" : "isFeatured", "type" : "boolean" } ] }, expecting [ "null", { "type" : "record", "name" : "Result", "namespace" : "v1", "fields" : [ { "name" : "id", "type" : "string" }, { "name" : "text", "type" : "string" }, { "name" : "isRecommended", "type" : "boolean" } ] } ] at org.apache.avro.io.ResolvingDecoder.doAction(ResolvingDecoder.java:231) at org.apache.avro.io.parsing.Parser.advance(Parser.java:88) at org.apache.avro.io.ResolvingDecoder.readIndex(ResolvingDecoder.java:206) at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:148) at org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:173) at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:144) at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:135) at TestCaseMain.main(TestCaseMain.java:44) The exception doesn't occur when the field is not Optional. Am I missing something or does this look like a bug? Thanks, Francois.
