【问题标题】:NullPointerException when attempting to serialize Avro GenericRecord containing array尝试序列化包含数组的 Avro GenericRecord 时出现 NullPointerException
【发布时间】:2017-08-08 06:32:59
【问题描述】:

我正在尝试发布 Avro(到 Kafka)并在尝试使用 BinaryEncoder 编写 Avro 对象时获得 NullPointerException

这是缩写的堆栈跟踪:

java.lang.NullPointerException: null of array of com.mycode.DeeplyNestedObject of array of com.mycode.NestedObject of union of com.mycode.ParentObject
    at org.apache.avro.generic.GenericDatumWriter.npe(GenericDatumWriter.java:132) ~[avro-1.8.1.jar:1.8.1]
    at org.apache.avro.generic.GenericDatumWriter.writeWithoutConversion(GenericDatumWriter.java:126) ~[avro-1.8.1.jar:1.8.1]
    at org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:73) ~[avro-1.8.1.jar:1.8.1]
    at org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:60) ~[avro-1.8.1.jar:1.8.1]
    at com.mycode.KafkaAvroPublisher.send(KafkaAvroPublisher.java:61) ~[classes/:na]
    ....
    at org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:73) ~[avro-1.8.1.jar:1.8.1]
    at org.apache.avro.generic.GenericDatumWriter.writeWithoutConversion(GenericDatumWriter.java:112) ~[avro-1.8.1.jar:1.8.1]
    at org.apache.avro.specific.SpecificDatumWriter.writeField(SpecificDatumWriter.java:87) ~[avro-1.8.1.jar:1.8.1]
    at org.apache.avro.generic.GenericDatumWriter.writeRecord(GenericDatumWriter.java:143) ~[avro-1.8.1.jar:1.8.1]
    at org.apache.avro.generic.GenericDatumWriter.writeWithoutConversion(GenericDatumWriter.java:105) ~[avro-1.8.1.jar:1.8.1]
    ... 55 common frames omitted

这是我的代码中发生异常的发送方法:

private static final EncoderFactory ENCODER_FACTORY = EncoderFactory.get();
private static final SpecificDatumWriter<ParentObject> PARENT_OBJECT_WRITER = new SpecificDatumWriter<>(ParentObject.SCHEMA$);
public void send(ParentObject parentObject) {
    try {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        binaryEncoder = ENCODER_FACTORY.binaryEncoder(stream, binaryEncoder);
        PARENT_OBJECT_WRITER.write(parentObject, binaryEncoder);  // Exception HERE
        binaryEncoder.flush();
        producer.send(new ProducerRecord<>(topic, stream.toByteArray()));
    } catch (IOException ioe) {
        logger.debug("Problem publishing message to Kafka.", ioe);
    }
}

在架构中,NestedObject 包含一个 DeeplyNestedObject 数组。我已经进行了足够多的调试,发现NestedObject 实际上包含一个DeeplyNestedObject 的数组,或者如果不存在则为一个空数组。这是架构的相关部分:

[ { "namespace": "com.mycode.avro"
  , "type": "record"
  , "name": "NestedObject"
  , "fields":
    [ { "name": "timestamp", "type": "long", "doc": "Instant in time (milliseconds since epoch)." }
    , { "name": "objs", "type": { "type": "array", "items": "DeeplyNestedObject" }, "doc": "Elided." }
    ]
  }
]

【问题讨论】:

    标签: java apache-kafka avro


    【解决方案1】:

    来自 Avro 的堆栈跟踪具有误导性。问题可能比Exception 消息所指示的类别更深一层。

    当它显示“null of array of com.mycode.DeeplyNestedObject of array of com.mycode.NestedObject of union of com.mycode.ParentObject”时,表示DeeplyNestedObject 内的字段之一应为array,但被发现为null。 (将DeeplyNestedObject 误解为nullNestedObject 内部是完全有道理的。)

    您需要检查DeeplyNestedObject 的字段并找出哪个array 未正确序列化。问题很可能出在DeeplyNestedObject 的创建位置。它将有一个类型为 array 的字段,在调用 send 方法之前,序列化程序不会在所有情况下填充该字段。

    【讨论】:

      【解决方案2】:

      我对您拥有的对象知之甚少,但我在您的示例中看到的是您的 avro-schema 不正确。

      avro 中的 DeeplyNestedObject 是一个 Record,所以你的 schema 必须是这样的:

      {
        "type": "record",
        "name": "NestedObject",
        "namespace": "com.mycode.avro",
        "fields": [
          {
            "name": "timestamp",
            "type": "long"
          },
          {
            "name": "objs",
            "type": {
              "type": "record",
              "name": "DeeplyNestedObject",
              "fields": []
            }
          }
        ]
      }
      

      当然DeeplyNestedObject的所有字段都需要在“fields”中声明:[]与DeeplyNestedObject记录相关。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-12
        • 2023-03-06
        • 1970-01-01
        • 2012-11-11
        • 1970-01-01
        • 1970-01-01
        • 2021-03-14
        • 2013-12-31
        相关资源
        最近更新 更多