Search code examples
javaspring-bootjacksonjsm

Caused by: org.springframework.jms.support.converter.MessageConversionException: Could not find type id property [_type] on message


I am trying this spring JMS sample, and it gives error. https://spring.io/guides/gs/messaging-jms/ Caused by: org.springframework.jms.support.converter.MessageConversionException: Could not find type id property [_type] on message from destination [queue://mailbox] Interesting part is, if I clone it and run everything runs fine. If I copy and paste, it gives error.

 @Bean // Serialize message content to json using TextMessage
public MessageConverter jacksonJmsMessageConverter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setTargetType(MessageType.TEXT);
    converter.setTypeIdPropertyName("_type");
    return converter;
}

This piece of code actually causing the error. Searching the web and documentation, I still have no clue how and what to set setTypeIdPropertyName value and with "_type" what it refers in this project to? As the message does not have such property, then where is it coming from ?


Solution

  • I'm using Spring Boot JmsTemplate and the 2nd class of Danylo Zatorsky's answer didn't quite work for me as its deserialization only returns simple strings. Prepending the content with the class name during serialization and cracking that out later with a regex allows one to reverse more complex objects. HTH

    @Component
    public class JsonMessageConverter implements MessageConverter {
    
        private final ObjectMapper mapper;
    
        public JsonMessageConverter(ObjectMapper mapper) {
            this.mapper = mapper;
        }
    
        @Override
        public javax.jms.Message toMessage(Object object, Session session) throws MessageConversionException {
            try {
                // send class=<json content>
                return session.createTextMessage(object.getClass().getName() + "=" + mapper.writeValueAsString(object));
            } catch (Exception e) {
                throw new MessageConversionException("Message cannot be serialized", e);
            }
        }
    
        @Override
        public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException {
            try {
                Matcher matcher = Pattern.compile("^([^=]+)=(.+)$").matcher(((TextMessage) message).getText());
                if (!matcher.find())
                {
                    throw new MessageConversionException("Message is not of the expected format: class=<json content>");
                }
                return mapper.readValue(matcher.group(2), Class.forName(matcher.group(1)));
            } catch (Exception e) {
                throw new MessageConversionException("Message cannot be deserialized", e);
            }
        }
    }