Ошибка при сериализации объекта списка с помощью JMS Jackson и Spring

#java #jackson #spring-jms #jackson2

Вопрос:

Я пытаюсь отправить List объект в конечную точку с помощью Spring JMS и ожидаю, что другой List объект вернется в качестве ответа. Когда я пытаюсь отправить List сообщение , оно выдает следующую ошибку:

 org.springframework.messaging.converter.MessageConversionException: Could not convert 'GenericMessage [payload=ActiveMQTextMessage {commandId = 0, responseRequired = false, messageId = null, originalDestination = null, originalTransactionId = null, producerId = null, destination = null, transactionId = null, expiration = 1000, timestamp = 0, arrival = 0, brokerInTime = 0, brokerOutTime = 0, correlationId = f407b3b6-75e2-4751-b551-84dee9237d5f, replyTo = queue://endpoint3_response, persistent = true, type = null, priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = false, readOnlyBody = false, droppable = false, jmsXGroupFirstForConsumer = false, text = [Test1, Test2, Test3]}, headers={id=d058221c-ac9f-9dcc-bf91-b3fbd5c80b3f, timestamp=1637443395895}]'; nested exception is org.springframework.jms.support.converter.MessageConversionException: Could not map JSON object [ActiveMQTextMessage {commandId = 0, responseRequired = false, messageId = null, originalDestination = null, originalTransactionId = null, producerId = null, destination = null, transactionId = null, expiration = 1000, timestamp = 0, arrival = 0, brokerInTime = 0, brokerOutTime = 0, correlationId = f407b3b6-75e2-4751-b551-84dee9237d5f, replyTo = queue://endpoint3_response, persistent = true, type = null, priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = false, readOnlyBody = false, droppable = false, jmsXGroupFirstForConsumer = false, text = [Test1, Test2, Test3]}]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.util.Vector$1 and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.apache.activemq.command.ActiveMQTextMessage["replyTo"]->org.apache.activemq.command.ActiveMQQueue["reference"]->javax.naming.Reference["all"])

    at org.springframework.jms.core.JmsMessagingTemplate$MessagingMessageCreator.createMessage(JmsMessagingTemplate.java:476)
    at org.springframework.jms.core.JmsTemplate.doSendAndReceive(JmsTemplate.java:915)
    at org.springframework.jms.core.JmsTemplate.lambda$sendAndReceive$11(JmsTemplate.java:896)
    at org.springframework.jms.core.JmsTemplate.executeLocal(JmsTemplate.java:954)
    at org.springframework.jms.core.JmsTemplate.sendAndReceive(JmsTemplate.java:894)
    at org.springframework.jms.core.JmsMessagingTemplate.doSendAndReceive(JmsMessagingTemplate.java:411)
    at org.springframework.jms.core.JmsMessagingTemplate.sendAndReceive(JmsMessagingTemplate.java:297)
    at org.springframework.jms.core.JmsMessagingTemplate.convertSendAndReceive(JmsMessagingTemplate.java:349)
    at org.springframework.jms.core.JmsMessagingTemplate.convertSendAndReceive(JmsMessagingTemplate.java:319)
    at org.springframework.jms.core.JmsMessagingTemplate.convertSendAndReceive(JmsMessagingTemplate.java:305)
    at me.aneeshreddy.activemqdemo.producer.Producer.sendMessageWithReply(Producer.java:49)
    at me.aneeshreddy.activemqdemo.JMSTest.testJMSWithReplyObject(JMSTest.java:46)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.springframework.jms.support.converter.MessageConversionException: Could not map JSON object [ActiveMQTextMessage {commandId = 0, responseRequired = false, messageId = null, originalDestination = null, originalTransactionId = null, producerId = null, destination = null, transactionId = null, expiration = 1000, timestamp = 0, arrival = 0, brokerInTime = 0, brokerOutTime = 0, correlationId = f407b3b6-75e2-4751-b551-84dee9237d5f, replyTo = queue://endpoint3_response, persistent = true, type = null, priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = false, readOnlyBody = false, droppable = false, jmsXGroupFirstForConsumer = false, text = [Test1, Test2, Test3]}]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.util.Vector$1 and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.apache.activemq.command.ActiveMQTextMessage["replyTo"]->org.apache.activemq.command.ActiveMQQueue["reference"]->javax.naming.Reference["all"])
    at org.springframework.jms.support.converter.MappingJackson2MessageConverter.toMessage(MappingJackson2MessageConverter.java:195)
    at org.springframework.jms.support.converter.MessagingMessageConverter.createMessageForPayload(MessagingMessageConverter.java:144)
    at org.springframework.jms.support.converter.MessagingMessageConverter.toMessage(MessagingMessageConverter.java:111)
    at org.springframework.jms.core.JmsMessagingTemplate$MessagingMessageCreator.createMessage(JmsMessagingTemplate.java:473)
    ... 78 more
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.util.Vector$1 and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.apache.activemq.command.ActiveMQTextMessage["replyTo"]->org.apache.activemq.command.ActiveMQQueue["reference"]->javax.naming.Reference["all"])
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
    at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1300)
    at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:46)
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:29)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
    at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1518)
    at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1219)
    at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1060)
    at org.springframework.jms.support.converter.MappingJackson2MessageConverter.mapToTextMessage(MappingJackson2MessageConverter.java:280)
    at org.springframework.jms.support.converter.MappingJackson2MessageConverter.toMessage(MappingJackson2MessageConverter.java:185)
 

Вот мой код:

Производитель (часть, которая отправляет сообщение):

 @Component
@Slf4j
public class Producer {

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Autowired
    private JmsTemplate jmsTemplate;

    @SneakyThrows
    public boolean sendMessageWithoutReply(String destination, Object message) {
        log.info("Sending message '"   message   "' to destination '"   destination   "' NO REPLY");
        jmsTemplate.convertAndSend(destination, message);
        log.info("Sent message '"   message   "' to destination '"   destination   "' Successfully");
        return true;
    }

    @SneakyThrows
    public <T> T sendMessageWithReply(String destination, Object message, Class<T> replyObject) {
        jmsMessagingTemplate.setJmsTemplate(jmsTemplate);

        Session session = jmsMessagingTemplate.getConnectionFactory().createConnection()
                .createSession(false, Session.AUTO_ACKNOWLEDGE);

        Message messageObject = session.createTextMessage(message.toString());

        messageObject.setJMSCorrelationID(UUID.randomUUID().toString());
        messageObject.setJMSReplyTo(new ActiveMQQueue(destination   "_response"));
        messageObject.setJMSExpiration(1000L);
        messageObject.setJMSDeliveryMode(DeliveryMode.PERSISTENT);
        log.info(jmsMessagingTemplate.getJmsMessageConverter().toString());
        log.info("Sending message '"   message   "' to destination '"   destination   "' EXPECTING REPLY");
        T reply = jmsMessagingTemplate.convertSendAndReceive(destination,
                messageObject, replyObject);
        log.info("Sent message '"   message   "' to destination '"   destination   "' Successfully");
        log.info("Reply received from '"   destination   "': "   reply);
        return reply;
    }

}
 

Config:

 @Configuration
@Slf4j
@EnableJms
public class Config {

    @Value("${spring.activemq.broker-url}")
    private String brokerUrl;

    @Bean
    public ConnectionFactory connectionFactory() {
        return new ActiveMQConnectionFactory(brokerUrl);
    }

    @Bean
    public MessageConverter jacksonJmsMessageConverter() {
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.setTargetType(MessageType.TEXT);
        converter.setTypeIdPropertyName("_type");
        return converter;
    }

    @Bean
    public JmsTemplate jmsTemplate() {
        JmsTemplate jmsTemplate = new JmsTemplate();
        jmsTemplate.setConnectionFactory(connectionFactory());
        jmsTemplate.setMessageConverter(jacksonJmsMessageConverter());
        return jmsTemplate;
    }

}
 

Test class:

 @SpringBootTest
public class JMSTest {

    @Autowired
    private Producer producer;

    @Test
    @SneakyThrows
    public void testJMSNoReplyString() {
        assertTrue(producer.sendMessageWithoutReply("endpoint3", "Hello World"));
        Thread.sleep(2000);
    }

    @Test
    @SneakyThrows
    public void testJMSWithReplyString() {
        assertEquals(producer.sendMessageWithReply("endpoint3", "Hello World", String.class), "Message processed: Hello World");
        Thread.sleep(2000);
    }

    @Test
    @SneakyThrows
    public void testJMSNoReplyObject() {
        assertTrue(producer.sendMessageWithoutReply("endpoint3", Arrays.asList("Test1", "Test2", "Test3")));
        Thread.sleep(2000);
    }

    @Test
    @SneakyThrows
    public void testJMSWithReplyObject() {
        assertEquals(producer.sendMessageWithReply("endpoint3", new ArrayList<>(Arrays.asList("Test1", "Test2", "Test3")), List.class), Arrays.asList("a", "b", "c"));
        Thread.sleep(2000);
    }

}
 

Any help would be appreciated!

Thank you.