【问题标题】:Kafka consumer ClassNotFoundException卡夫卡消费者 ClassNotFoundException
【发布时间】:2021-08-31 21:25:26
【问题描述】:

(在开始提问之前,我的英文可能不足以描述清楚。如果你不明白,请告诉我。)

我正在尝试通过 Kafka 将数据对象从 A spring 项目(生产者)发送到 B spring 项目(消费者)。

问题是 A 和 B 中的数据对象具有不同的类路径。所以B项目数据类无法映射A项目的字段。

但是两个对象具有相同的字段。所以我想从 A 项目中获取对象作为 B 项目的参数。

错误信息

Listener failed; nested exception is 

org.springframework.kafka.support.serializer.DeserializationException: failed to deserialize; nested exception is 

org.springframework.messaging.converter.MessageConversionException: failed to resolve class name. Class not found [com.example.springboot.DTO.kafka.PostViewCountDTO]; nested exception is 

java.lang.ClassNotFoundException: com.example.springboot.DTO.kafka.PostViewCountDTO

build.gradle

    implementation 'org.apache.kafka:kafka-clients:2.8.0'
    implementation 'org.apache.kafka:kafka_2.13:2.8.0'
    implementation 'org.springframework.boot:spring-boot-starter-web:2.5.3'

数据类(使用 A 和 B 项目)

public class PostViewCountDTO implements Serializable {
    private static final long serialVersionUID = 1L;

    @NotNull
    private long postNo;
}

生产者配置

@Configuration
public class PostViewProducerConfig {

    @Value("${spring.kafka.producer.bootstrap-servers}")
    private String bootstrapServer;

    @Bean
    public Map<String,Object> postViewProducerConfigs() {
        return JsonSerializer.getStringObjectMap(bootstrapServer);
    }

    @Bean
    public ProducerFactory<String, PostViewCountDTO> postViewCountDTOProducerFactory() {
        return new DefaultKafkaProducerFactory<>(postViewProducerConfigs());
    }

    @Bean
    public KafkaTemplate<String, PostViewCountDTO> postViewDTOKafkaTemplate() {
        return new KafkaTemplate<>(postViewCountDTOProducerFactory());
    }
}

通用 JsonSerializer 类

public class JsonSerializer {

    static Map<String, Object> getStringObjectMap(String bootstrapServer) {
        Map<String, Object> props = new HashMap<>();

        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServer);
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, org.springframework.kafka.support.serializer.JsonSerializer.class);

        return props;
    }
}

消费者配置

@Configuration
@RequiredArgsConstructor
public class PostViewConsumerConfig {

    @Value("${spring.kafka.consumer.bootstrap-servers}")
    private String bootstrapServer;

    @Bean
    public Map<String,Object> postViewConsumerConfigs() {
        return JsonDeserializer.getStringObjectMap(bootstrapServer);
    }

    @Bean
    public ConsumerFactory<String, PostViewCountDTO> postViewCountDTO_ConsumerFactory() {
        return new DefaultKafkaConsumerFactory<>(postViewConsumerConfigs());
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, PostViewCountDTO> postViewCountListener() {
        ConcurrentKafkaListenerContainerFactory<String, PostViewCountDTO> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(postViewCountDTO_ConsumerFactory());
        return factory;
    }

    @Bean
    public StringJsonMessageConverter jsonConverter() {
        return new StringJsonMessageConverter();
    }
}

生产

    @Async
    public void sendPostNo(PostViewCountDTO postViewCountDTO) {
        postViewKafkaTemplate.send(topic_viewCount, null, postViewCountDTO);
    }

消费

    @KafkaListener(topics = topic_viewCount, groupId = groupId, containerFactory = "postViewCountListener")
    public void consume(@Payload PostViewCountDTO postViewCountDTO) {
        ...
    }

【问题讨论】:

  • 你是什么意思对象有不同的“路径”?
  • 需要给序列化器和反序列化器添加类型映射docs.spring.io/spring-kafka/docs/current/reference/html/…
  • OneCricketeer /// 抱歉,我的英语不够好,无法清楚地描述这一点。我的意思是“路径”是“包名”。

标签: java apache-kafka spring-kafka


【解决方案1】:

你需要给序列化器和反序列化器添加类型映射

https://docs.spring.io/spring-kafka/docs/current/reference/html/#serdes-mapping-types

在生产者方面,将com.a.PostViewCountDTO 映射到PostViewCountDTO。 在消费者方面,将com.b.PostViewCountDTO 映射到PostViewCountDTO。

【讨论】:

  • 非常感谢加里!我已经为这个问题苦苦挣扎了两个星期。你刚刚救了我。
  • @YeonCheolJang 你能展示一下你是如何进行映射的吗?我也有同样的问题
  • @Gloria - 请参阅答案中的链接;他们只是进入生产者/消费者配置属性;如果您仍有不明白的地方,请提出一个显示您的代码和配置的新问题。
  • @GaryRussell 我发布了一个问题:stackoverflow.com/questions/70206790/…。请,如果你能帮忙..我真的不知道如何解决这个问题。
猜你喜欢
  • 2019-07-03
  • 2018-05-05
  • 2021-08-22
  • 1970-01-01
  • 2020-10-28
  • 2015-12-18
  • 2019-03-27
  • 2017-01-07
  • 2018-12-04
相关资源
最近更新 更多