Uploaded image for project: 'Apache Avro'
  1. Apache Avro
  2. AVRO-3186

Java: Avro can't decode union<null, logicalType> field of a record

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Critical
    • Resolution: Fixed
    • 1.10.2
    • 1.11.0
    • java
    • JDK 11, macOS.

    Description

      https://github.com/apache/avro/blob/release-1.10.2/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java#L163

        protected Object read(Object old, Schema expected, ResolvingDecoder in) throws IOException {
          Object datum = readWithoutConversion(old, expected, in);
          LogicalType logicalType = expected.getLogicalType();
          if (logicalType != null) {
            Conversion<?> conversion = getData().getConversionFor(logicalType);  // <---- bad
            if (conversion != null) {
              return convert(datum, expected, logicalType, conversion);
            }
          }
          return datum;
        }
       

       
      For a logic type field in a union, getData().getConversionFor(logicalType) returns null, the cause is SpecificData.getForSchema() isn't compatible with JDK >= 9, it can't depend on Class.forName() to load user class.

      https://github.com/apache/avro/blob/release-1.10.2/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java#L147

      diff --git a/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java b/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
      index 58bc660b..33fc3418 100644
      --- a/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
      +++ b/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
      @@ -140,15 +140,9 @@ public class SpecificData extends GenericData {
          */
         public static SpecificData getForSchema(Schema reader) {
           if (reader != null && reader.getType() == Type.RECORD) {
      -      final String className = getClassName(reader);
      -      if (className != null) {
      -        final Class<?> clazz;
      -        try {
      -          clazz = Class.forName(className);
      -          return getForClass(clazz);
      -        } catch (ClassNotFoundException e) {
      -          return SpecificData.get();
      -        }
      +      final Class<?> clazz = SpecificData.get().getClass(reader);
      +      if (clazz != null) {
      +        return getForClass(clazz);
             }
           }
           return SpecificData.get();
      

      Attachments

        Issue Links

          Activity

            People

              liuyb@yahoo-inc.com Yubao Liu
              liuyb@yahoo-inc.com Yubao Liu
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 40m
                  40m