You need to specify both the reader and writer schema in the SpecificDatumReader. The writer schema is used in serialize and the reader schema is the schema you want to use after deserialize. See http://avro.apache.org/docs/1.7.0/api/java/org/apache/avro/specific/SpecificDatumReader.html Hope this helps.Sam
On Wednesday, July 29, 2015 7:26 AM, Yosi Botzer <yosi.bot...@gmail.com> wrote: Hi, I have 2 schemas: {"namespace": "com.slg.model.generated.event", "type": "record", "name": "A1", "fields": [ {"name": "event_id", "type": "string", "doc" : "unique event id"}, {"name": "ts", "type": "long", "doc" : "time stamp in miliseconds"} ]} and {"namespace": "com.slg.model.generated.event", "type": "record", "name": "A2", "fields": [ {"name": "event_id", "type": "string", "doc" : "unique event id"}, {"name": "ts", "type": "long", "doc" : "time stamp in miliseconds"}, {"name": "msg", "type": ["null", "string"], "default" : null, "doc" : "error message"} ]} As you can see there are identical except the A2 has one extra field with default value. When running the following code: package common.events; import java.io.ByteArrayOutputStream;import java.io.IOException; import org.apache.avro.Schema;import org.apache.avro.io.BinaryEncoder;import org.apache.avro.io.DatumWriter;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 org.apache.avro.specific.SpecificRecordBase; import com.slg.model.generated.event.A1;import com.slg.model.generated.event.A2; public class AddFieldTest { public static void main(String[] args) throws IOException{ A1 a1 = new A1("aaa1", 1000L); byte[] bytes = serialize(a1); A2 a2 = deserialize(A2.SCHEMA$, bytes); System.out.println(a2); } public static <T> T deserialize(Schema schema, byte[] value) throws IOException { SpecificDatumReader<T> reader = new SpecificDatumReader<T>(schema); T record = reader.read(null, DecoderFactory.get().binaryDecoder(value, null)); return record; } public static <T extends SpecificRecordBase> byte[] serialize(T record) throws IOException { try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(out, null); DatumWriter<T> writer = new SpecificDatumWriter<T>(record.getSchema()); writer.write(record, encoder); encoder.flush(); return out.toByteArray(); } }} I was surprised to get the following exception: Exception in thread "main" java.io.EOFException at org.apache.avro.io.BinaryDecoder.ensureBounds(BinaryDecoder.java:473) at org.apache.avro.io.BinaryDecoder.readInt(BinaryDecoder.java:128) at org.apache.avro.io.BinaryDecoder.readIndex(BinaryDecoder.java:423) at org.apache.avro.io.ResolvingDecoder.doAction(ResolvingDecoder.java:290) at org.apache.avro.io.parsing.Parser.advance(Parser.java:88) at org.apache.avro.io.ResolvingDecoder.readIndex(ResolvingDecoder.java:267) at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:155) at org.apache.avro.generic.GenericDatumReader.readField(GenericDatumReader.java:193) at org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:183) at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:151) at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:142) at common.events.AddFieldTest.deserialize(AddFieldTest.java:32) at common.events.AddFieldTest.main(AddFieldTest.java:25) Why can't the decoder populate the value of A2 with the default value? Am I doing something wrong here? Yosi