当前位置: 首页 > 知识库问答 >
问题:

Spring kafka 2.2类型映射类加载器不匹配

何越
2023-03-14

我正在尝试使用Spring Kafka2.2中引入的新类型映射特性:

向下滚动到“映射类型”:
https://docs.spring.io/spring-kafka/reference/htmlsingle/#serdes

在生产者方面,我注册了一个映射,如下所示:

senderProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
senderProps.put(JsonSerializer.TYPE_MAPPINGS, "foo:com.myfoo.Foo");
consumerProps.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
consumerProps.put(JsonDeSerializer.TYPE_MAPPINGS, "foo:com.yourfoo.Foo");

我在《Spring-Kafka》中把问题缩小到这个方法:

https://github.com/spring-projects/spring-kafka/blob/master/spring-kafka/src/main/java/org/springframework/kafka/support/converter/abstractJavaTypeMapper.java#L142

protected void addHeader(Headers headers, String headerName, Class<?> clazz) {
    if (this.classIdMapping.containsKey(clazz)) {
        headers.add(new RecordHeader(headerName, this.classIdMapping.get(clazz)));
    }
    else {
        headers.add(new RecordHeader(headerName, clazz.getName().getBytes(StandardCharsets.UTF_8)));
    }
}

当通过执行kafka记录的序列化进行调试时,执行实际上会转到else分支,而根据我的理解,它实际上应该转到if分支并添加foo作为头。相反,它将com.myfoo.foo添加到头部。

罪魁祸首似乎与类加载器不匹配有关,但我不确定这实际上是一个bug还是我在我的端做了什么蠢事。

基本上,classidmapping映射以com.myfoo.foo作为键和foo的UTF-8 byte[]表示形式作为相应的值正确填充。

但是,在if检查期间,clazz参数是一个由不同的类加载器加载的类,与存储在classidmapping映射中的类一样,因此哈希代码是不同的,它会转到else分支。

实际上是String-Kafka端的bug还是我配置错误了?

谢谢

共有1个答案

秦时铭
2023-03-14

这看起来确实像是我们在实现中的一个疏漏。请为Apache Kafka项目的Spring提出一个问题:https://github.com/spring-projects/spring-kafka。我们的想法是不使用Class<?>进行映射,而是使用它的完全限定类名。

看起来你的应用程序是多类加载器,例如它是Web One。Apache Kafka客户机将senderprops.put(Producerconfig.value_serializer_class_config,jsonserializer.class);加载到其类加载器中,同时所有其他操作都由应用程序上下文类加载器完成。

作为一种解决方法,我们在解决该问题的同时,建议使用DefaultKafkaProducerFactory配置及其SetValueSerializer()来填充JSONSerializerbean引用。这样,您需要通过其setTypeMapper()填充类映射,因此需要在DefaultJackson2JavaTypeMapper上填充一个SetIDClassMapping()

 类似资料:
  • 我试图通过使用多个测试数据在Cucumber DataTable中使用映射来自动化一个场景。在本测试中,我们将向测试步骤传递两次Username和Password。所以我们的测试应该输入用户名和密码一次,点击登录按钮,并重复相同的步骤再次。 我已经尝试使用for循环来使用Maps集合重复测试。1.我收到一个错误,表示类型不匹配:无法从元素类型2。当我将其转换为时,我得到另一个错误,说明方法send

  • 我在解决泛型问题时遇到了一些麻烦。我有一个“猫”对象列表和一个“狗”对象列表,我需要将它们传递到同一个方法中。该方法的返回类型是一个“字符串”和“动物列表”的映射,我试图找出一种方法来将带有动物列表的映射转换为带有猫或狗列表的映射。 这工作很好,如果我有一个单独的方法猫和狗,但我正在寻找一个更灵活的解决方案。 标题中出现错误的行: 注意:这是一个简化的例子,我必须能够使用地图中的列表作为“猫”或“

  • 我得到这个错误: 14/12/10 18:11:01 INFO Mapred.JobClient:任务Id:Attest_201412100143_0008_M_000000_0,状态:失败java.io.ioException:溢出在org.apache.hadoop.mapred.maptask$MapOutputBuffer.Collect(maptask.java:425)在wordcou

  • 类型映射 web3j中使用的原生Java到ABI类型映射如下: boolean -> bool BigInteger -> uint/int byte[] -> bytes String -> string and address types List<> -> dynamic/static array BigInteger类型必须用于数字类型,因为Ethereum以太坊中的数字类型是256位整数

  • 我对Flutter编程非常陌生,我正在尝试导入一个本地JSON文件,其中包含书籍数据,如标题、作者、发布年份等。 最初我使用JSON-to-DART转换器来组装一个图书数据模型,现在我正在尝试创建一个函数,在该函数中,程序获取本地JSON文件,并使用类中的方法将数据解析为地图。 我遇到的问题是返回类型

  • TypeScript 会将一些好用的工具类型纳入基准库中,方便开发者直接使用,本节介绍的映射类型就是这样的工具类型。 对这种工具类型,我们不只要知道使用方法,还要了解其实现功能的本质。本节我们会从源码进行分析,逐步掌握。 1. 慕课解释 映射类型可以将已知类型的每个属性都变为可选的或者只读的。 2. Readonly 与 Partial 关键字 先来看这样一个任务:将 Person 接口的每个属性