1

Trying to read messages in consumer I get the following exception:

org.springframework.kafka.listener.ListenerExecutionFailedException: 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
...
Caused by: org.springframework.messaging.converter.MessageConversionException: failed to resolve class name. Class not found

I've been looking at the deserialiser but I cannot seem to find the right way to resolve it.

I am working on an application split across different microservices.

Right now I am working on the logic to send emails to newly registered users. So for this scenario, I have two microservices; the user service and the email service.

User Management - Producer - application.yml

kafka:
  properties:
    security.protocol: 'PLAINTEXT'
  template:
    default-topic: user-creation
  producer:
    bootstrap-servers: ${kafka_bootstrap_servers:localhost:9092}
    value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
    key-serializer: org.apache.kafka.common.serialization.StringSerializer

Email service - Consumer - application.yml

kafka:
  properties:
    security.protocol: 'PLAINTEXT'
  consumer:
    bootstrap-servers: ${kafka_bootstrap_servers:localhost:9092}
    group-id: user-creation-consumer
    auto-offset-reset: earliest
    # Configures the Spring Kafka ErrorHandlingDeserializer that delegates to the 'real' deserializers
    key-deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer
    value-deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer
    properties:
      # Delegate deserializers
      spring.json.trusted.packages: '*'
      spring.deserializer.key.delegate.class: org.apache.kafka.common.serialization.StringDeserializer
      spring.deserializer.value.delegate.class: org.springframework.kafka.support.serializer.JsonDeserializer

The user management service uses a Kafka topic user-creation to alert different microservices of user generation.

private final KafkaTemplate<String, RegisteredUser> kafkaTemplate;

public void sendMessage(RegisteredUser registeredUser){
    log.info("########## Sending message: {}", registeredUser.toString());
    this.kafkaTemplate.send(new ProducerRecord<>("user-creation", registeredUser));
}

The email service listens to the for updates on the user-creation topic:

@KafkaListener(topics = "user-creation")
@Service
@Slf4j
public class Consumer {

    @KafkaHandler
    public void listen(String string){
        log.info("Received String message {}", string);
    }

    @KafkaHandler
    public void listen(ConsumerRecord<String, NewUser> record) {
        log.info("Receive NewUser object {}", record.value());
    }

    @KafkaHandler(isDefault = true)
    public void consume(@Payload Object data) {
        log.info("received data='{}'", data);
    }
}

The two services are split to avoid tight coupling; hence the object RegisteredUser DTO used in User creation is not accessible to the Email service or the other services. I am using a very similar class with the same signature and fields but that is still failing.

What is the best way to handle such a scenario? I am quite new to Kafka so I am not sure how to progress - most tutorials online have the producer and consumer in the same code base so the DTO can be easily shared.

The idea is that the RegisteredUser DTO has fields/elements useful for other services so it will include more data - I only need to read a part of it.

TIA

Ox Jacome
  • 11
  • 2
  • I had the same issue, here is the answer: https://stackoverflow.com/questions/54690518/spring-kafka-jsondesirialization-messageconversionexception-failed-to-resolve-cl – Franco Jan 04 '22 at 19:03

0 Answers0