我已经使用avro-maven-plugin从Avro模式生成了Avro Java类。我将avro类序列化为字节数组,然后将其写入kafka主题。
然后我有一个kafka流,它试图操纵avro数据来执行某些操作。在反序列化过程中,我从同一类中获得ClassCastExcetion。我读到这个问题是由于Avro在回退时使用了另一个ClassLoader(ClassLoader的新实例)而产生的。
有一种方法可以强制Avro使用调用者的ClassLoader或类似的东西?
KafkaStream属性
this.props = new Properties();
this.props.put(StreamsConfig.APPLICATION_ID_CONFIG, "test");
this.props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
this.props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
this.props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.ByteArray().getClass());
我正在使用String键和序列化的avro的字节数组,那么我需要手动反序列化avro的有效负载。 我使用avro的解码器像这样反序列化:
AvroPayload stp = AvroPayload.fromByteBuffer(ByteBuffer.wrap(bytes));
甚至是这样:
AvroPayload stp = AvroPayload.getDecoder().decode(ByteBuffer.wrap(bytes));
在第一个版本的调试中,我可以看到,如果我仍留在avro的生成的类上下文中,则将字节数组正确反序列化为AvroPayload类。返回该新实例可能会引发ClassCastException
答案 0 :(得分:2)
我发现的唯一解决方案是按照建议将avro类放入外部jar,然后将其导入。
这不是一个好的解决方案,因为它需要大量配置才能保持您的avro模式和您生成的类的耦合,但这是我发现的唯一一个。
我配置了一个maven项目,该项目将avro的类jar生成到目录中,而名称中没有工件版本,因此我始终可以导入最新版本而不必更改pom。
如果有人会发现其他解决方案,请发布