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