Announcement Announcement Module
Collapse
No announcement yet.
More notes on JDBC-AMQP Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • More notes on JDBC-AMQP

    I have an message flow that reads rows from a db via jdbc outbound gateway, splits the rows and sends each row, as a message, to an amqp outbound adapter. I have descibed this flow in other recent posts to this forum. Another application (also running SI) reads the message from the queue, and get this error:

    Caused by: java.lang.ClassCastException: org.springframework.util.LinkedCaseInsensitiveMap cannot be cast to [B
    at org.springframework.integration.transformer.Payloa dDeserializingTransformer.transformPayload(Payload DeserializingTransformer.java:33)
    at org.springframework.integration.transformer.Abstra ctPayloadTransformer.doTransform(AbstractPayloadTr ansformer.java:33)
    at org.springframework.integration.transformer.Abstra ctTransformer.transform(AbstractTransformer.java:3 3)

    Normally, messages on this queue are type LinkedHashMap (which is how they are created byt the original sender) and this flow works fine. Seems like JDBC gateway produces a LinkedCaseInsensitiveMap on the republish. Is this is a bug/feature?

    What is the workaround? I was thinking a transformer in the republish flow on the sending end.

  • #2
    Whenever you ask these questions, please show the relevant configuration - in this case from the inbound adapter to the transformer; it will save us, and you, time because then we don't have to speculate about what you have.

    <speculation>

    My best guess is that you are using the default message converter (SimpleMessageConverter) in the outbound and inbound adapters. This means that, for Serializable payloads, the adapter will use Java serialization and set the contentType header to "application/x-java-serialized-object".

    This header is understood by the inbound converter (in the adapter) and the Map is deserialized for you - you don't need a PayloadDeserializingTransformer.

    I am guessing your "other" application is not setting the content type, so the adapter doesn't know what to do with it so gives you a byte[] - hence you need the transformer.

    Solutions:

    1. Set the contentType header in all producing applications and remove the transformer.
    2. Add a payload type router and only route through the transformer if the payload is a byte[] (skip the transformer if the payload is already a Map).

    </speculation>

    Comment


    • #3
      Originally posted by Gary Russell View Post
      Whenever you ask these questions, please show the relevant configuration - in this case from the inbound adapter to the transformer; it will save us, and you, time because then we don't have to speculate about what you have.

      <speculation>

      My best guess is that you are using the default message converter (SimpleMessageConverter) in the outbound and inbound adapters. This means that, for Serializable payloads, the adapter will use Java serialization and set the contentType header to "application/x-java-serialized-object".

      This header is understood by the inbound converter (in the adapter) and the Map is deserialized for you - you don't need a PayloadDeserializingTransformer.

      I am guessing your "other" application is not setting the content type, so the adapter doesn't know what to do with it so gives you a byte[] - hence you need the transformer.

      Solutions:

      1. Set the contentType header in all producing applications and remove the transformer.
      2. Add a payload type router and only route through the transformer if the payload is a byte[] (skip the transformer if the payload is already a Map).

      </speculation>

      Gary, thank you for parsing my post and making the correct speculation. We fixed it with option 1. I was not aware that this content type existed. That's really cool. Passing serialized Java Objects around in messaging. The more I learn about SI and Rabbit the more I realize this is likely the best system I have ever seen for middleware programming. Good job guys!

      Comment


      • #4
        Great!

        Just one caveat - passing around java serialized objects is generally not the "AMQP way" of doing things because of its polyglot nature. You are stuck with using Java in the producer(s) and consumer(s). It works, but you might (perhaps in future) want to consider using a language-neutral serialization technique (such as JSON). Spring-AMQP provides a JsonMessageConverter for this purpose. It sets some additiona headers that contain type information, to help the deserialization but that should not be necessary for simple Maps.

        Comment

        Working...
        X