1
votes

I am using below config to send JMS message with an Object payload( lets say HelloWorld object) but when I receive message using Message driven adapater the payload is converted into byte[].

Is there a way to prevent this? I see outbound adapter eventually calls SimpleMessageConverter method `createMessageForSerializable --> session.createObjectMessage(object)

<si:chain input-channel="errorChannelIn"> 
  <si:router 
       expression="headers.jms_redelivered.equals(T(java.lang.Boolean).FALSE) ? 'errorQueueChannel' : 'channel2Name' " 
       apply-sequence="true"> 
     <si:mapping value="errorQueueChannel" channel="errorChannel"/> 
     <si:mapping value="channel2Name" channel="channel2"/> 
  </si:router> 
</si:chain> 

<si-jms:outbound-channel-adapter id="errorQueueMessageSender"
                                 channel="errorChannel"
                                 connection-factory="connectionFactory" session-transacted="true" destination="errorQueue"
        />

However, when I send message using JmsTemplate then it perfectly sends message as messageObject and message driven adapter picks up the Object as payload. Code snippet below.

Any idea where am I going wrong.

jmsTemplate.send(new MessageCreator() {
        @Override
        public Message createMessage(Session session) throws JMSException {
            return session.createObjectMessage(messageObject);
        }
    });
1

1 Answers

0
votes

I guess you mean the extract-payload="false" on the <si-jms:outbound-channel-adapter>.

In that case <si-jms:message-driven-channel-adapter> delegates work to the org.springframework.jms.support.converter.SimpleMessageConverter which ends up with:

else if (message instanceof ObjectMessage) {
    return extractSerializableFromMessage((ObjectMessage) message);
}

and you get deserialized Message<?>.

UPDATE

Sorry, it is really not clear what's going on. Just tested with our Samples. There you can find server/client configs: outboundChannelAdapter.xml and inboundChannelAdapter.xml. And I added a test-case to the GatewayDemoTest:

private final static String[] configFilesChannelAdapterDemo = {
        "/META-INF/spring/integration/common.xml",
        "/META-INF/spring/integration/inboundChannelAdapter.xml",
        "/META-INF/spring/integration/outboundChannelAdapter.xml"
};

@Test
public void testAdapterDemo() throws InterruptedException {

    System.setProperty("spring.profiles.active", "testCase");

    final GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext(configFilesChannelAdapterDemo);

    final MessageChannel stdinToJmsoutChannel = applicationContext.getBean("stdinToJmsoutChannel", MessageChannel.class);

    Foo foo = new Foo("bar");

    stdinToJmsoutChannel.send(MessageBuilder.withPayload(foo).build());

    final QueueChannel queueChannel = applicationContext.getBean("queueChannel", QueueChannel.class);

    Message<?> reply = queueChannel.receive(20000);
    Assert.assertNotNull(reply);
    Object out = reply.getPayload();

    Assert.assertThat(out, Matchers.instanceOf(Foo.class));

    Assert.assertEquals(foo, out);

    applicationContext.close();
}

public static class Foo implements Serializable {

    private final String bar;

    public Foo(String bar) {
        this.bar = bar;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Foo foo = (Foo) o;

        return !(bar != null ? !bar.equals(foo.bar) : foo.bar != null);

    }

    @Override
    public int hashCode() {
        return bar != null ? bar.hashCode() : 0;
    }

}

As you see I sand some Serializable object to the queue and the <jms:message-driven-channel-adapter> receives for me exactly the same deserialized object.

Maybe your issue is somewhere before the <jms:outbound-channel-adapter> where you may use a <payload-serializing-transformer>?

Would you mind rechecking the payload just before <jms:message-driven-channel-adapter> or even putting break point to the SimpleMessageConverter.toMessage ?