Announcement Announcement Module
Collapse
No announcement yet.
Transformer's strange behaviour Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Transformer's strange behaviour

    Hello!

    I'm new to the Spring Integration project, please excuse if my question is quite simple.

    What is the difference between the following cases?
    Code:
    public Message<List<String>> transform(AuthProtocolDocument payload, @Headers Map<String, Object> headers) {
      // some deal with payload and headers,
      // returning result
    }
    and
    Code:
    public Message<List<String>> transform(Message<AuthProtocolDocument> message) {
      AuthProtocolDocument payload = message.getPayload();
      Map<String, Object> headers = message.getHeaders();
      // some deal with payload and headers,
      // returning result
    }
    The first sample works quite good, but the second one fails with MessagingHandlingException
    (handler requires a reply, but no reply was received). My transformer's code is not executed in this case.
    And this fail is not stable, one of about five similar runs is successful.

    I'm using this transformation to convert XmlBean object, received from other service, to my domain pojo. I'm not sure I'm using headers
    properly. Received message may contain an error response code and I want to throw an domain exception from the gateway. I think that this transformer
    is the only component that knows something about response message structure and it have to check the response code and generate an exception.
    Also I don't want to add response codes to my domain pojo.
    I'll be thankful if someone suggest me how to throw the domain specific exception from the gateway without mixing of payload and headers
    transformation in the same transformer.

    Thanks!

    Best Regards,
    -- Alexei Pomelov

  • #2
    There is absolutely no difference between the two implementation of the transformer other then what is provided as an input argument (the whole Message or its parts). The execution and the end result should be the same.

    The exception and the message you are getting simply means that some request component (probably the one that generates XML ) returned null and AbstractReplyProducingMessageHandler throws this exception letting you know that it will not be generating a reply (delegating to transformer) with null result.

    Try to analyze your code. The bottom line is in Messaging architecture nulls are treated somewhat different then what you may used too. We don't have NullMessages. So in your case if something that was supposed to generate XML didn't do it, it should throw an exception or generate some type of result that could be interpreted downstream as a failure.

    Comment


    • #3
      Hello, thanks for your reply!

      There is a router before transformation. It logs the message and the channel where it's going to route the message. Then Spring integration logs "preSend on channel" with message payload (not null xml, containing correct data) and then exception occurs, transformer method hasn't been called.

      This exception never occurs when the transformer method signature contains payload and headers separately and occurs quite always (approx four of five runs, but there is no regularity) when signature contains the whole message.

      Comment


      • #4
        Could you possibly submit a bare minimum configuration that reproduces this problem,so we can test it locally?

        Comment


        • #5
          I'm already thinking about it. I'll do some stubs, cut off some functionality and if the problem does not float away I'll send my configuration. I'm not sure I'll have time to do it today, but I'll do it as soon as possible, thanks!

          Comment


          • #6
            Another idea is if you can reproduce it in your environment with reasonable consistency, try to step into the code and see if there are some exception that is thrown and swallowed internally resulting in the exception that you see.
            I'll assume you are using Spring Integration 2.0.RC1, set a breakpoint in AbstractReplyProducingMessageHandler.handleMessage Internal(Message<?> message) method.

            You can clearly see there that the exception that you see is thrown only if reply was NULL.

            Comment


            • #7
              Oh, great! Problem seems to be solved!
              My transformer class has one public method that is not annotated as @Transformer. But it has an abstract superclass that has a setter. Setter signature is also suitable as transformer method. So when MessagingMethodInvokerHelper find candidates for transformation method there are two matches: correct transform method and setter with void return type. As I understand the order of candidates is not specified so my problem was floating. MessagingMethodInvokerHelper invoked the setter and satisfied with null result (its field requiresReply was false). When the null result returned to AbstractReplyProducingMessageHandler it threw an exception, because its requiresReply was true. Using the @Transformer annotation completely solved the problem.
              And sorry, I forgot to say, I'm really using integration 2.0.0.RC1

              Comment


              • #8
                I assume you have a "ref" but not a "method" then? ... or are you using SpEL?

                Comment


                • #9
                  There is an inner bean and no "method" attribute. I've read, that if there is the only suitable method it will be used. I'll specify it in future
                  Is it correct that the 'requiresReply' property has different values for AbstractReplyProducingMessageHandler and MessagingMethodInvokerHelper?

                  Comment

                  Working...
                  X