Ошибка при конвертации сообщения RabbitMQ
Делаю небольшое тестовое приложение с использование RabbitMQ по этому видео, при получении сообщения и попытки вывести его в консоль выскакивает следующая ошибка:
org.springframework.amqp.AmqpRejectAndDontRequeueException: Error Handler converted exception to fatal
at org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler.handleError(ConditionalRejectingErrorHandler.java:146) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeErrorHandler(AbstractMessageListenerContainer.java:1509) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.handleListenerException(AbstractMessageListenerContainer.java:1806) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListenerAndHandleException(AbstractMessageListenerContainer.java:1582) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.lambda$executeListener$8(AbstractMessageListenerContainer.java:1540) ~[spring-rabbit-3.0.3.jar:3.0.3]
at io.micrometer.observation.Observation.observe(Observation.java:492) ~[micrometer-observation-1.10.5.jar:1.10.5]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1540) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1001) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:948) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1326) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1232) ~[spring-rabbit-3.0.3.jar:3.0.3]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Listener method could not be invoked with the incoming message
Endpoint handler details:
Method [public void com.example.maycodereddisrabbitmq.rabbit.CrazyTaskListener.handleCrazeTask(com.example.maycodereddisrabbitmq.domain.CrazyTask)]
Bean [com.example.maycodereddisrabbitmq.rabbit.CrazyTaskListener@624ade1c]
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:267) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandlerAndProcessResult(MessagingMessageListenerAdapter.java:210) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:149) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1718) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1637) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1625) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1616) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListenerAndHandleException(AbstractMessageListenerContainer.java:1561) ~[spring-rabbit-3.0.3.jar:3.0.3]
... 8 common frames omitted
Caused by: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [com.example.maycodereddisrabbitmq.domain.CrazyTask] to [com.example.maycodereddisrabbitmq.domain.CrazyTask] for GenericMessage [payload=CrazyTask(id=350306e5-66c5-4826-8727-dc399d8fb92e, fromServer=b0c9b00c-598e-4271-9664-47893b4062a7), headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedExchange=myExchange, amqp_deliveryTag=400, amqp_consumerQueue=myQueue, amqp_redelivered=false, id=458a1441-df18-1fd0-8fc8-994dbe204504, amqp_consumerTag=amq.ctag-jE7Z-AlOyrS-vpNqn2E5mg, amqp_lastInBatch=false, contentType=application/x-java-serialized-object, timestamp=1681239122758}]
at org.springframework.messaging.handler.annotation.support.PayloadMethodArgumentResolver.resolveArgument(PayloadMethodArgumentResolver.java:152) ~[spring-messaging-6.0.7.jar:6.0.7]
at org.springframework.amqp.rabbit.annotation.RabbitListenerAnnotationBeanPostProcessor$OptionalEmptyAwarePayloadArgumentResolver.resolveArgument(RabbitListenerAnnotationBeanPostProcessor.java:1055) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:118) ~[spring-messaging-6.0.7.jar:6.0.7]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:147) ~[spring-messaging-6.0.7.jar:6.0.7]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:115) ~[spring-messaging-6.0.7.jar:6.0.7]
at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:75) ~[spring-rabbit-3.0.3.jar:3.0.3]
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:263) ~[spring-rabbit-3.0.3.jar:3.0.3]
... 15 common frames omitted
Код CrazyTaskListener:
package com.example.maycodereddisrabbitmq.rabbit;
import com.example.maycodereddisrabbitmq.domain.CrazyTask;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.experimental.FieldDefaults;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Log4j2
@RequiredArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@Component
public class CrazyTaskListener {
ObjectMapper objectMapper = new ObjectMapper();
public static final String CRAZY_TASK_QUEUE = "myQueue";
public static final String CRAZY_TASK_EXCHANGE = "myExchange";
@SneakyThrows
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = CRAZY_TASK_QUEUE),
exchange = @Exchange(value = CRAZY_TASK_EXCHANGE)
)
)
public void handleCrazeTask(CrazyTask crazyTask) {
log.info(objectMapper.writeValueAsString(crazyTask));
}
}
Код CrazyTaskSender:
package com.example.maycodereddisrabbitmq.rabbit;
import com.example.maycodereddisrabbitmq.domain.CrazyTask;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
import org.springframework.stereotype.Component;
@Log4j2
@RequiredArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@Component
public class CrazyTaskSender {
RabbitMessagingTemplate rabbitMessagingTemplate;
public void sendCrazyTask(CrazyTask crazyTask) {
rabbitMessagingTemplate.convertAndSend(CrazyTaskListener.CRAZY_TASK_EXCHANGE, null, crazyTask);
}
}
Код CrazyTaskInitializerService:
package com.example.maycodereddisrabbitmq.services;
import com.example.maycodereddisrabbitmq.configs.RedisLock;
import com.example.maycodereddisrabbitmq.domain.CrazyTask;
import com.example.maycodereddisrabbitmq.rabbit.CrazyTaskSender;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.extern.log4j.Log4j2;
import org.apache.logging.log4j.util.Strings;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.UUID;
@Log4j2
@RequiredArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@Service
public class CrazyTaskInitializerService {
private static final String SERVER_ID = UUID.randomUUID().toString();
RedisLock redisLock;
CrazyTaskSender crazyTaskSender;
private static final long ONE_MINUTE_IN_MILLIS = 1000 * 60;
private static final String GENERATE_CRAZY_TASK_KEY = "generate:crazy:task";
@Scheduled(fixedDelay = 1000L)
public void generateCrazyTasks() {
if (redisLock.acquireLock(ONE_MINUTE_IN_MILLIS, GENERATE_CRAZY_TASK_KEY)) {
log.info("I am here");
log.info(Strings.repeat("-", 100));
log.info("Server {} start generate tasks", SERVER_ID);
for (int i = 0; i < 100; ++i) {
crazyTaskSender.sendCrazyTask(CrazyTask.builder()
.id(UUID.randomUUID().toString())
.fromServer(SERVER_ID)
.build());
}
log.info(Strings.repeat("-", 100));
log.info("Server {} stopped generate tasks", SERVER_ID);
redisLock.releaseLock(GENERATE_CRAZY_TASK_KEY);
}
}
}
Код CrazyTask:
package com.example.maycodereddisrabbitmq.domain;
import lombok.*;
import lombok.experimental.FieldDefaults;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class CrazyTask implements Serializable {
String id;
String fromServer;
}
Я так понял это связано с тем, что при получении сообщения класс-слушатель не может перевести полученный объект из JSON в Java класс? Или проблема всё же в чём-то другом?