提问者:小点点

从kafka流和Avro反序列化同一类时出现ClassCastException


我已经用avro-maven-plugin从Avro模式中生成了我的Avro Java类。我将我的avro类序列化为一个字节数组,并将其写入kafka主题。

然后我有一个kafka流,它试图操纵avro数据来做一些事情。在反序列化过程中,我从同一个类中获得了一个ClassCastExcetion。我了解到这个问题是由于Avro在回退时使用了不同的类加载器(类加载器的新实例)而产生的。

有一种方法可以强制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());

我使用一个字符串键和序列化的avro的字节数组,然后我需要手动反序列化avro的有效载荷。我用avro的解码器反序列化成这样:

AvroPayload stp = AvroPayload.fromByteBuffer(ByteBuffer.wrap(bytes));

或者甚至像这样:

AvroPayload stp = AvroPayload.getDecoder().decode(ByteBuffer.wrap(bytes));

在第一个版本中,通过调试,我可以看到,如果我保持在avro生成的类上下文中,字节数组将正确地反序列化到AvroPayload类中。返回该新实例可能会引发一个<code>类异常</code>问题


共1个答案

匿名用户

我发现的唯一解决方案是按照建议将avro类放入外部jar中,然后导入它。

这不是一个好的解决方案,因为它需要大量配置来保持avro模式和生成的类的耦合,但这是我发现的唯一解决方案。

我配置了一个maven项目,将avro的类jar生成到一个目录中,名称中没有工件版本,因此我可以始终导入最新版本,而无需更改pom。

如果有人会发现另一种解决方案,请发布