Announcement Announcement Module
Collapse
No announcement yet.
best practices for interpreting exceptions/input-channel validation Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • best practices for interpreting exceptions/input-channel validation

    hi,

    newbie question: i'm spiking some work with spring integration, and i've noticed that the stacktraces can get pretty horrendous if an error occurs somewhere in the message flow. i personally find it quite hard to work out which endpoint it is that has failed. is there something that i'm missing, am i doing things wrong?

    one other thing that has caught me out a few times is getting my input-channel names wrong, it then seems to create a directChannel that nothing sends to. is there some way to tell it to bomb out on startup if i define endpoints that listen to channels that i haven't explicitly created?

  • #2
    Well for the first problem it would be easier to answer if you can provide a bit of a stack trace in question and corresponding configuration. It might be just a matter of explaining how to read this stack trace.

    As far as the second question I say its a common problem with any XML - "typo" so unless you have a DSL-aware editor (e.g., STS) it would be hard to track. Having said that you are right, we will auto-create an input-channel as a DirectChannel if one not found in the context. This was mainly done to eliminate the need for explicitly configuring DirectChannel (the simplest and default) just to connect two endpoints together. In other words unless you need a specialized channel (e.g., async, pollable, pub-sub) you don't have to configure it explicitly. Now, in most cases if you mistyped the channel and the channel you are sending too is a DirectChannel you'll get an exception during the send; something along the lines of "Dispatcher has no subscribers. . .". So that should tell you that you have a problem. And although in the current state the above message will not include the channel name it will shortly (once Gary finishes up with https://jira.springsource.org/browse/INT-2431). That one will also have a setting allowing you to ensure that pub-sub channel would have at least one subscriber. That will leave you only with PollableChannel that will be accumulating messages without them being retrieved, but I am sure it will become apparent very soon. Also as you get more experienced with the framework these type of mistakes will become more rare.

    One other thing. I am currently working on this issue https://jira.springsource.org/browse/INT-2434 and i will put an extra log message every time an input channel is "not found and therefore auto-created" so at least you;ll be able to see something in the log.
    Hope that helps

    Comment


    • #3
      not sure if i'm clear, i haven't got a problem that i can't diagnose at the moment, it was more a general approach question. in a layered implementation if i got an error in eg my dao layer then simplistically speaking i would see a stacktrace showing the incoming request processing, a service layer, and then the dao. obviously i'm not planning to use spring integration to handle a relatively trivial example like that, but instead I get something like the below. I guess I was thinking something that would say at least identify the channel that the error occured in.

      Code:
      org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 141): Field or property 'blah' cannot be found on object of type 'com.google.common.collect.SingletonImmutableList'
      	at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:207) ~[org.springframework.expression-3.0.5.RELEASE.jar:3.0.5.RELEASE]
      	at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:71) ~[org.springframework.expression-3.0.5.RELEASE.jar:3.0.5.RELEASE]
      	at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:57) ~[org.springframework.expression-3.0.5.RELEASE.jar:3.0.5.RELEASE]
      	at org.springframework.expression.spel.ast.ConstructorReference.createNewInstance(ConstructorReference.java:106) ~[org.springframework.expression-3.0.5.RELEASE.jar:3.0.5.RELEASE]
      	at org.springframework.expression.spel.ast.ConstructorReference.getValueInternal(ConstructorReference.java:92) ~[org.springframework.expression-3.0.5.RELEASE.jar:3.0.5.RELEASE]
      	at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:102) ~[org.springframework.expression-3.0.5.RELEASE.jar:3.0.5.RELEASE]
      	at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:102) ~[org.springframework.expression-3.0.5.RELEASE.jar:3.0.5.RELEASE]
      	at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:126) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:86) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor.processMessage(ExpressionEvaluatingMessageProcessor.java:67) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.transformer.AbstractMessageProcessingTransformer.transform(AbstractMessageProcessingTransformer.java:56) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:67) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:97) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.MessageHandlerChain$1.send(MessageHandlerChain.java:154) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(AbstractReplyProducingMessageHandler.java:175) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(AbstractReplyProducingMessageHandler.java:159) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(AbstractReplyProducingMessageHandler.java:124) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:118) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:100) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.MessageHandlerChain$1.send(MessageHandlerChain.java:154) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(AbstractReplyProducingMessageHandler.java:175) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(AbstractReplyProducingMessageHandler.java:159) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(AbstractReplyProducingMessageHandler.java:124) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:118) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:100) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.MessageHandlerChain$1.send(MessageHandlerChain.java:154) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(AbstractReplyProducingMessageHandler.java:175) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(AbstractReplyProducingMessageHandler.java:159) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(AbstractReplyProducingMessageHandler.java:124) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:118) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:100) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.MessageHandlerChain.handleMessageInternal(MessageHandlerChain.java:137) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:105) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:96) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:61) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      	at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149) ~[spring-integration-core-2.1.0.RELEASE.jar:na]
      

      Comment


      • #4
        Well in the above stack trace i can say that the error occurred not in MessageChannel but in the Transformer which is SpEL-based transformer. Its expression attribute contains SpEL expression which contains reference to 'blah' as non-literal value so it treats it as property of the root object which is of type com.google.common.collect.SingletonImmutableList. Now I am assuming that this list contains a String object with value 'blah' and you are attempting to invoke one of the following methods: contains(Object), lastIndexOf(Object), indexOf(Object), equals(Object) etc., In other words one of the methods that takes the value you are inquiring about and you probably not wrapping this value in quotes. For example; if this list is a payload of the Message your expression probably looks something like this: payload.contains(blah) where it should be payload.contains('blah')

        I other words as you can see the stack trace is actually pretty informative, but it does require some getting used to giving the fact that most of the code (including your POJO code or expression) is handled by the framework. In fact if you had a POJO based transformer and exception would happen in it, than it would be part of the stack trace, but since everything you have is configured via framework and little code that you had to provide is also not in the regular Java file i say what you got is a compilation error. The only difference is that since SpEL is interpreted in real time you are getting this compile error at runtime

        Comment


        • #5
          Hi.

          As I see in your stackTrace, you've got something like this:
          HTML Code:
          <chain>
            <transformer expression="payload.blah">
          <chain>
          But your payload instanseof com.google.common.collect.SingletonImmutableList.
          So, it is problem of your config.

          Show it, please

          Artem Bilan

          Comment


          • #6
            oops, the important point missing from my post was that i introduced the error deliberately to get a stacktrace . it sounds like the stacktrace is as good as it gets for now.

            Without knowing the technical details it would be nice if it could identify the channel that the error occurred in. though i suppose a lot of them are implicitly defined channels in chains.

            Comment


            • #7
              That's correct and in fact if your transformer was not in chain you would see the error deriving from the channel dispatch and once https://jira.springsource.org/browse/INT-2431 is addressed you'll also see the channel name. But please understand my earlier point that in your case the error is not in channel (rarely is). The channel initiates a message hand-off and the error happened somewhere else and in your case it was obvious where.

              Also you are correct, the channels in the chain are implicit and anonymous. The chain is a black-box. You should look at the chain as a way to assemble a hybrid endpoint which itself is exposed via input/output channel. Everything inside is inside the black box.

              Comment

              Working...
              X