[ 
https://issues.apache.org/jira/browse/AVRO-2108?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16278778#comment-16278778
 ] 

Nandor Kollar commented on AVRO-2108:
-------------------------------------

[~FaisalFeroz] are you referring to a case like this:
{code}
  public static class Super<T> {
    @Stringable
    T f;
  }

  public static class B extends Super<String> {
  }

  @Test public void testStringable() throws Exception {
    B datum = new B();
    datum.f = "42";

    Schema schema = ReflectData.get().getSchema(B.class);
    ReflectDatumWriter<Object> writer = new ReflectDatumWriter<>(schema);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    writer.write(datum, EncoderFactory.get().directBinaryEncoder(out, null));
    byte[] data = out.toByteArray();

    ReflectDatumReader<Object> reader = new ReflectDatumReader<Object>(schema);
    Object decoded = reader.read(null,
      DecoderFactory.get().binaryDecoder(data, null));
  }
{code}

If so, your proposed patch would only fix the writing case, but will fail when 
reading data using ReflectDatumReader. Stringable classes require a constructor 
with a single String parameter, and since in runtime generic type information 
is not present, Avro will try to call 
java.lang.Object.<init>(java.lang.String), and fail. 
{{GenericDatumReader#newInstanceFromString}} should find the subclass's single 
parameter constructor in this case. In addition, I don't see any solution to 
solve the problem of reading of Super instances, since the generic type 
information is lost in runtime, thus Avro can't find the single parameter 
constructor of an unknown type.

> @Stringable annotation should be processed before creating the schema
> ---------------------------------------------------------------------
>
>                 Key: AVRO-2108
>                 URL: https://issues.apache.org/jira/browse/AVRO-2108
>             Project: Avro
>          Issue Type: Bug
>          Components: java
>    Affects Versions: 1.8.2
>            Reporter: Faisal Feroz
>
> In {{org.apache.avro.reflect.ReflectData::createFieldSchema}} the following 
> code is processing Stringable after explicitly creating a schema
> {code:java}
> Schema schema = createSchema(field.getGenericType(), names);
> if (field.isAnnotationPresent(Stringable.class)) {      // Stringable
>   schema = Schema.create(Schema.Type.STRING);
> }
> {code}
> https://github.com/apache/avro/blob/3af404efb31a1dc2fd720384ef9a3f7326c2d303/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java#L748
> The above code has a side effect when @Stringable annotation is placed over a 
> Generic Type like {{ID}} which results in Unknown Type {{ID}} since the 
> schema is created first which causes the error. 
> Changing the code to following would fix this. Also it would also act as a 
> micro optimization of the code as the generated schema is overwritten if 
> stringable annotation is preset
> {code:java}
> Schema schema = null;
> if (field.isAnnotationPresent(Stringable.class)) {      // Stringable
>   schema = Schema.create(Schema.Type.STRING);
> } else {
>   schema = createSchema(field.getGenericType(), names);
> }
> {code}



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to