Affects: 5.2.0
I configured MappingJackson2MessageConverter
, however the app still fails with MessageConversionException
.
When I replace @SendTo
with template.convertAndSend()
, everything works as expected.
Code to reproduce:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.annotation.JmsListenerConfigurer;
import org.springframework.jms.config.JmsListenerEndpointRegistrar;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
@SpringBootApplication
@EnableJms
@RequiredArgsConstructor
@Slf4j
public class TestApp implements CommandLineRunner, JmsListenerConfigurer {
private final JmsMessagingTemplate template;
@JmsListener(destination = "queue1")
@SendTo("queue2")
public Payload handle(Payload payload) {
log.info("Handling message {}", payload);
return payload;
}
@Bean
public MessageConverter messageConverter() {
return new MappingJackson2MessageConverter();
}
@Bean
public DefaultMessageHandlerMethodFactory handlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setMessageConverter(messageConverter());
return factory;
}
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
registrar.setMessageHandlerMethodFactory(handlerMethodFactory());
}
@Override
public void run(String... args) {
template.setMessageConverter(messageConverter());
template.convertAndSend("queue1", new Payload("test"));
}
public static void main(String[] args) {
SpringApplication.run(TestApp.class, args);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
private static class Payload {
private String value;
}
}
Comment From: sbrannen
@b-dzoba, did this work for you on a previous version of the Spring Framework, and if so which version?
Comment From: b-dzoba
@sbrannen I haven't tried with different versions. Is there something wrong with my configuration?
5.1.2. doesn't work too.
Comment From: sbrannen
@sbrannen I haven't tried with different versions.
I was asking about that, because I wanted to know if you were experiencing a regression possibly introduced in 5.2.
5.1.2. doesn't work too.
OK. Thanks for letting us know.
Is there something wrong with my configuration?
I'm not sure off the top of my head. One of us will have to look into it in greater detail to determine that.
Comment From: b-dzoba
Seems like the problem is with MessagingMessageListenerAdapter
which doesn't call messageConverter before sending reply. Workaround is to override handleResult()
in MessagingMessageListenerAdapter
like this
public static class CustomMessagingMessageListenerAdapter extends MessagingMessageListenerAdapter {
private final MessageConverter messageConverter = new MappingJackson2MessageConverter();
private final JmsHeaderMapper jmsHeaderMapper = new SimpleJmsHeaderMapper();
@Override
protected void handleResult(Object result, javax.jms.Message request, Session session) {
Message<?> resultMessage;
if (result instanceof org.springframework.messaging.Message) {
resultMessage = messageConverter.toMessage(((org.springframework.messaging.Message) result).getPayload(), ((org.springframework.messaging.Message) result).getHeaders());
} else {
resultMessage = messageConverter.toMessage(result, jmsHeaderMapper.toHeaders(request));
}
super.handleResult(resultMessage, request, session);
}
}
Comment From: rstoyanchev
@b-dzoba, I think this is where it should be applying message conversion on the return value. Can you try a breakpoint to see if it has the right converter and if so what actually happens there? The converter should be getting set over here.
Comment From: b-dzoba
@rstoyanchev
Can you try a breakpoint to see if it has the right converter
The converter is null, but this is a org.springframework.jms.support.converter.MessageConverter. And I configured a org.springframework.messaging.converter.MessageConverter, because it's required for @JmsListener
(DefaultMessageHandlerMethodFactory). Shouldn't @SendTo
be able to use the same converter as @JmsListener
?
Comment From: snicoll
@b-dzoba the converter is shared for incoming messages and replies but it's null
so that's a sign of an inconsistent setup. Why don't you configure the messageConverter
on the JmsListenerContainerFactory
as indicated in the documentation?
A Spring Boot application does most of the heavy lifting for you anyway, see the documentation. In short, if you expose a org.springframework.jms.support.converter.MessageConverter
bean, it's going to be detected and used automatically.
I don't understand why that DefaultMessageHandlerMethodFactory
bean is defined. If the above doesn't help, please share a sample we can actually run (rather than code in text).
Comment From: b-dzoba
Why don't you configure the messageConverter on the JmsListenerContainerFactory as indicated in the documentation?
@snicoll Because I use org.springframework.messaging.converter.MappingJackson2MessageConverter
for conversion and it doesn't implement org.springframework.jms.support.converter.MessageConverter
. This configuration
works with @JmsListener
but stops working when I add @SendTo
org.springframework.jms.support.converter.MessageConverter bean, it's going to be detected and used automatically
yes, but it doesn't detect org.springframework.messaging.converter.MessageConverter
bean, so I have to set it manually on the factory
please share a sample we can actually run
https://github.com/b-dzoba/spring-jms-demo/blob/master/src/main/java/com/example/demo/Issue23886.java
Comment From: mbolis
I bumped into the same issue, is this being taken care of?
Comment From: snicoll
Unfortunately, https://github.com/b-dzoba/spring-jms-demo is no longer accessible.
@b-dzoba or @mbolis would you be able to share a sample we can run ourselves. That would be very helpful.
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.