Can Apache Avro framework handle parameterized typ

2019-05-28 01:33发布

Can Apache Avro handle parameterized types during serialization?

I see this exception thrown from Avro framework when I try to serialize an instance that uses generics -

org.apache.avro.AvroTypeException: Unknown type: T
    at org.apache.avro.specific.SpecificData.createSchema(SpecificData.java:255)
    at org.apache.avro.reflect.ReflectData.createSchema(ReflectData.java:514)
    at org.apache.avro.reflect.ReflectData.createFieldSchema(ReflectData.java:593)
    at org.apache.avro.reflect.ReflectData$AllowNull.createFieldSchema(ReflectData.java:75)
    at org.apache.avro.reflect.ReflectData.createSchema(ReflectData.java:472)
    at org.apache.avro.specific.SpecificData.getSchema(SpecificData.java:189)

The class I am trying to serialize looks like this

public class Property<T> {

   private T propertyValue;

}

I am trying to generate the schema on the fly based on the incoming POJO instance. My serialization code looks like this -

ByteArrayOutputStream os = new ByteArrayOutputStream();
ReflectData reflectData = ReflectData.AllowNull.get();
Schema schema = reflectData.getSchema(propertyValue.getClass());
DatumWriter<T> writer = new ReflectDatumWriter<T>(schema);
Encoder encoder = EncoderFactory.get().jsonEncoder(schema, os);
writer.write(propertyValue, encoder);

The line in my code that triggers the exception:

Schema schema = reflectData.getSchema(propertyValue.getClass());

The same code works fine for classes that don't have parameterized types.

1条回答
迷人小祖宗
2楼-- · 2019-05-28 02:32

Avro as of version 1.7.7 cannot generate a schema for a parameterized type due to issue AVRO-1571. A work around is to explicitly specify the schema for a parameterized type so Avro does not try to generate it:

private static final String PROPERTY_STRING_SCHEMA =
    "{ " +
      "\"type\": \"record\", " +
      "\"name\": \"PropertyString\", " +
      "\"fields\": [" +
        "{ \"name\": \"propertyValue\", \"type\": \"string\" }" +
      "] " +
    "}";

@AvroSchema(PROPERTY_STRING_SCHEMA)
private Property<String> password; 
查看更多
登录 后发表回答