从 kafka 流和 Avro 反序列化相同 class 的 ClassCastException
ClassCastException on the same class deserializing from kafka stream and Avro
我已经使用 avro-maven-plugin 从 Avro 模式生成了我的 Avro Java classes。我将我的 avro class 序列化为字节数组,并将其写入 kafka 主题。
然后我有一个 kafka 流,它试图操纵 avro 数据来做某事。在反序列化过程中,我从同一个 class 得到了一个 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());
我正在使用字符串键和序列化的 avro 字节数组,然后我需要手动反序列化 avro 的有效负载。
我使用avro的解码器反序列化是这样的:
AvroPayload stp = AvroPayload.fromByteBuffer(ByteBuffer.wrap(bytes));
甚至像这样:
AvroPayload stp = AvroPayload.getDecoder().decode(ByteBuffer.wrap(bytes));
对于第一个版本,调试我可以看到,如果我留在 avro 生成的 class 上下文中,字节数组将正确反序列化为 AvroPayload class。返回那个新实例可能会抛出 ClassCastException
我找到的唯一解决方案是按照建议将 avro 类 放入外部 jar 中,然后导入它。
这不是一个好的解决方案,因为它需要大量的配置来保持你的 avro 模式和你生成的 类 的耦合,但这是我找到的唯一解决方案。
我配置了一个生成 avro 的 类 jar 到目录中的 maven 项目,其名称中没有工件版本,因此我始终可以导入最新版本而无需更改 pom。
如果有人会发现另一个解决方案,请post它
我已经使用 avro-maven-plugin 从 Avro 模式生成了我的 Avro Java classes。我将我的 avro class 序列化为字节数组,并将其写入 kafka 主题。
然后我有一个 kafka 流,它试图操纵 avro 数据来做某事。在反序列化过程中,我从同一个 class 得到了一个 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());
我正在使用字符串键和序列化的 avro 字节数组,然后我需要手动反序列化 avro 的有效负载。 我使用avro的解码器反序列化是这样的:
AvroPayload stp = AvroPayload.fromByteBuffer(ByteBuffer.wrap(bytes));
甚至像这样:
AvroPayload stp = AvroPayload.getDecoder().decode(ByteBuffer.wrap(bytes));
对于第一个版本,调试我可以看到,如果我留在 avro 生成的 class 上下文中,字节数组将正确反序列化为 AvroPayload class。返回那个新实例可能会抛出 ClassCastException
我找到的唯一解决方案是按照建议将 avro 类 放入外部 jar 中,然后导入它。
这不是一个好的解决方案,因为它需要大量的配置来保持你的 avro 模式和你生成的 类 的耦合,但这是我找到的唯一解决方案。
我配置了一个生成 avro 的 类 jar 到目录中的 maven 项目,其名称中没有工件版本,因此我始终可以导入最新版本而无需更改 pom。
如果有人会发现另一个解决方案,请post它