尝试序列化包含数组的avro genericord时发生nullpointerexception

93ze6v8z  于 2021-06-07  发布在  Kafka
关注(0)|答案(2)|浏览(430)

我正试图出版《阿夫罗》(到Kafka),并获得一个 NullPointerException 尝试用 BinaryEncoder .
以下是stacktrace的缩写:

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

以下是代码中发生异常的send方法:

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." }
    ]
  }
]
waxmsbnn

waxmsbnn1#

我对您拥有的对象了解不够,但我在您的示例中看到的是您拥有不正确的avro模式。
avro中的deeplynestedobject是一个记录,因此您的模式必须如下所示:

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

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

ac1kyiln

ac1kyiln2#

从avro出来的stacktrace有误导性。这个问题可能比这个班的学生更深一层 Exception 消息指示。
当它说 null of array of com.mycode.DeeplyNestedObject of array of com.mycode.NestedObject of union of com.mycode.ParentObject ,这意味着 DeeplyNestedObject 预计将成为 array 但被发现 null . (把它误解为 DeeplyNestedObjectnull 内部 NestedObject .)
你得检查一下 DeeplyNestedObject 找出是哪个 array 未正确序列化。问题可能出在 DeeplyNestedObject 已创建。它将有一个类型为的字段 array 并不是所有情况下都由序列化程序在调用send方法之前填充。

相关问题