org.springframework.messaging.converter.MessageConversionException: невозможно преобразовать

У нас есть приложение, использующее реализации Spring Boot и Tibco EMS JMS. Когда я создаю войну и разворачиваюсь на своем локальном Tomcat, я могу отправлять и получать сообщения без проблем. Однако, если я запускаю приложение из метода main():

@SpringBootApplication
public class Main {
 public static void main(String[] args) {       
    SpringApplication.run(Main.class, args);
 }
}

При запуске от имени> Spring Boot App я вижу эту ошибку, как только сообщение отправляется для использования.

Здесь сообщения создаются и отправляются:

@Transactional
private void sendAndLog (Long id1, Long id2, String s, List<Mapping> mappings) {
    queue.send(new Request (
            id1,
            id2,
            s,
            mappings));
    log.info("Message sent.");
}

Это где он потребляется - я вижу, что ошибка сразу после вызова send() и никогда не получить метод receive():

Processor.java:

@Transactional
public void receive (Request mappings) {
    // Process the message
}

Это класс запроса:

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

    private Long id1;
    private Long id2;   
    private String s;   
    private List<Mapping> mappings;

    public Request() {}
    public Request (Long id1, Long id2, String s, List<Mapping> mappings) {
        this.id1 = id1;
        this.id2 = id2;
        this.s = s;
        this.mappings = mappings;
    }

    //getter() and setter() methods.
}

Это ошибка.

Что идет не так и почему я вижу эту ошибку "только" при запуске с Spring Runner, а не при развертывании в Tomcat?

2018-07-25 17:19:19.924  WARN 4796 --- [enerContainer-7] o.s.j.l.DefaultMessageListenerContainer  : Execution of JMS message listener failed, and no ErrorHandler has been set.

org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method could not be invoked with incoming message
Endpoint handler details:
Method [public void com.package.tasks.Processor.receive(com.package.dto.Request)]
Bean [com.package.tasks.Processor@475d2a6d]
; nested exception is org.springframework.messaging.converter.MessageConversionException: Cannot convert from [com.package.dto.Request] to [com.package.dto.Request] for org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@6d5d2920, failedMessage=org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@6d5d2920
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:118)
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:77)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:736)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:696)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:674)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:318)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:257)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1189)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1179)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1076)
    at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [com.package.dto.Request] to [com.package.dto.Request] for org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@6d5d2920
    at org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver.resolveArgument(PayloadArgumentResolver.java:144)
    at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:114)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:137)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:109)
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:114)
    ... 10 common frames omitted

17:19:19.924 [DefaultMessageListenerContainer-7] WARN  o.s.j.l.DefaultMessageListenerContainer - Execution of JMS message listener failed, and no ErrorHandler has been set.

1 ответ

Прежде всего, вы должны отладить, чтобы увидеть, что происходит. Замените тип параметра на "Объект", начните с отладки и посмотрите, какой тип объекта вы получаете. Попробуйте преобразовать объект вручную в режиме отладки, чтобы увидеть, что происходит.

Сообщение сбивает с толку, посмотрите на упаковку вашего приложения и посмотрите, возможно ли иметь несколько dto с одним и тем же пакетом в разных банках. Если у вас есть проблема только с SpringRunner, возможно, у вас есть зависимости, которых нет в вашем локальном Tomcat, и именно поэтому у вас есть ошибка.

Также, вероятно, не источник проблемы, но @Transactionnal для частного метода обычно не работает, зависит от того, где вы выполняете код (Eclipse run config, gradle, tomcat и т. Д.). Подобная аннотация должна идти по общедоступному методу. Мне пришлось бы исследовать, но я предполагаю, что Spring внедряет транзакцию, когда вы вызываете метод из компонента в контексте, когда он видит @Transactional. Поскольку вы вызывали приватный метод из другого публичного метода, Spring, вероятно, не внедряет его.

Другие вопросы по тегам