You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@avro.apache.org by Iván de Prado <iv...@datasalt.com> on 2011/06/27 19:30:17 UTC

Reflection not allowing new fields present in writer schema but not on reader schema

Hi,
If I serialize a bean using the Reflection API, and then I add a new
field to the bean and I try to deserialize, I got an exception. That
seems to break the spec rule:

"if the reader's record schema has a field that contains a default
value, and writer's schema does not have a field with the same name,
then the reader should use the default value from its field."

A code where that happens is the following:

package example;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.apache.avro.Schema;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.Encoder;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.reflect.ReflectData;
import org.apache.avro.reflect.ReflectDatumReader;
import org.apache.avro.reflect.ReflectDatumWriter;

public class AvroTest {

	public static class TwoFields {
		String one;
		String two;

		public String getOne() {
	  	return one;
	  }
		public void setOne(String one) {
	  	this.one = one;
	  }
		public String getTwo() {
	  	return two;
	  }
		public void setTwo(String two) {
	  	this.two = two;
	  }	
		
		public String toString() {
			return "1:" + one + " 2:" + two;
		}
	}	
	
	public static class ThreeFields {
		String one;
		String two;
		String three = "default3";

		public String getOne() {
	  	return one;
	  }
		public void setOne(String one) {
	  	this.one = one;
	  }
		public String getTwo() {
	  	return two;
	  }
		public void setTwo(String two) {
	  	this.two = two;
	  }
		public String getThree() {
    	return three;
    }
		public void setThree(String three) {
    	this.three = three;
    }
		
		public String toString() {
			return "1:" + one + " 2:" + two + " 3:" + three;
		}
	}
	
	public static ByteArrayOutputStream write(Object datum, Schema
schema) throws IOException {
		ReflectDatumWriter dWriter = new ReflectDatumWriter(schema);
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		Encoder e = EncoderFactory.get().binaryEncoder(os, null);
    dWriter.write(datum, e);
    e.flush();
		return os;
	}
	
	public static Object read(ByteArrayInputStream is, Schema writer,
Schema reader) throws IOException {
    Object o = new ReflectDatumReader(writer, reader).read(null,
        DecoderFactory.get().binaryDecoder(is, null));
		return o;
	}
	
	public static void main(String args[]) throws IOException {
		
		Schema twoSchema = ReflectData.get().getSchema(TwoFields.class);
		Schema threeSchema = ReflectData.get().getSchema(ThreeFields.class);
		threeSchema.addAlias("TwoFields");
		
		TwoFields two = new TwoFields();
		two.one = "one";
		two.two = "two";
			
		ByteArrayOutputStream bo = write(two, twoSchema);
		Object o = read(new ByteArrayInputStream(bo.toByteArray()),
twoSchema, threeSchema);
		System.out.println(o);
	}
}

Thanks,
--
Iván de Prado
CEO & Co-founder
www.datasalt.com