Announcement Announcement Module
Collapse
No announcement yet.
Sending Message on Control Bus Problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Sending Message on Control Bus Problem

    I'm using a Control Bus to send a message for invoking an operation on one of my App's services, like such:

    Code:
    @Service
    public DocumentSelectorService()
    {
      public List<T extends Document> getNextSetOfDocuments(Class<T> documentType)
      {
         documentService.getDocumentByType(documentType);
          ...
      }
    }
    Code:
    <control-bus input-channel="documentsSelectorControlChannel" />
    <service-activator input-channel="documentsSelectorControlChannel" 
          output-channel="someDownstreamChannel"
          expression="@documentsSelectorService.getNextSetOfDocuments(payload)" />
    And then to send the message:

    Code:
    public static void main(String[] args)
    {
      String payloadClass = "org.mycompany.model.SomeClass";
      Message<?> operation;
      try
      {
        operation = MessageBuilder.withPayload(Class.forName(payloadClass)).build();
      }
      catch (ClassNotFoundException e)
      {
        throw new IllegalArgumentException(e);
      }
    
      ApplicationContext ctx = new ClassPathXmlApplicationContext("META-INF/spring/application-context.xml");
      DirectChannel documentsSelectorControlChannel = ctx.getBean("documentsSelectorControlChannel", DirectChannel.class);
      documentsSelectorControlChannel.send(operation);
    }
    This works fine for all of my Unit/Integration tests. It also works on my PC running command line. However, it is failing when I deploy to our Solaris server running Solaris 10 with JRE 1.5. I am able to get it to run locally on my PC using the same 1.5 runtime as on Solaris. All environments are using Spring Framework 3.0.5 along with Spring Integration 2.0.1. The exception I'm getting is as follows:

    Code:
    INFO [org.springframework.integration.handler.LoggingHandler] - [Payload=class org.mycompany.model.SomeClass][Headers={...}]
    Exception in thread "main" org.springframework.integration.dispatcher.ArrgesageMessageDeliveryException:  All attempts to deliver Message to MessageHandlers failed.  Multiple causes:
       error occurred in message handler [ServiceActivator for [org.springframework.integration.handler.ExpressionCommandMessageProcessor@bcc8f4]]
       Expression evaluation failed: @documentsSelectorService.getNextSetOfDocuments(payload)
    See below for the stacktrace of the first cause.
             at org.springframework.integration.dispatcher.UnicastDispatcher.handleExceptions(UnicasterDispatcher.java:160)
             at org.springframework.integration.dispatcher.UnicastDispatcher.doDispatch(UnicasterDispatcher.java:123)
             at org.springframework.integration.dispatcher.UnicastDispatcher.dispatch(UnicasterDispatcher.java:97)
             at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubstribableChannel.java:44)
             at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
             at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
             at org.mycompany.MainAppClass(MainAppClass.java:57)
    Caused by: org.springframework.integration.MessageHandlingException: error occurred in message handler [ServiceActivator for [org.springframework.integration.handler.ExpressionCommandMessageProcessor@bcc8f4]]
             at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:84)
             at org.springframework.integration.dispatcher.UnicastDispatcher.dispatch(UnicasterDispatcher.java:110)
             ... 5 more
    Caused by: java.lang.IllegalArgumentException: Message payload must be an Expression instance or an expression String.
             at org.springframework.integration.handler.ExpressionCommandMessageProcessor.processMessage(ExpressionCommandMessageProcessor.java:65)
             at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:64)
             at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:98)
             at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
            ... 6 more
    Last edited by jzcfk9; Mar 17th, 2011, 01:04 PM.

  • #2
    Some more updates. I tried running the code on Solaris 10 using JRE 1.6, but same error. This eliminates any potential JRE 1.5 vs JRE 1.6 issue.

    I also modified the Main class to evaluate the same expression that's being used by the Service Activator. This evaluation is done prior to sending the Spring Integration message to the Control Bus, and the expression evaluated successfully with results being returned from my DocumentsSelectorService. This eliminates any potential issue with the expression that I'm using the workflow.

    Code:
    StandardEvaluationContext evalContext = new StandardEvaluationContext();
    //use the same ApplicationContext as used by Spring Integration
    evalContext.setBeanResolver(new BeanFactoryResolver(ctx));
    
    //now evaluate expression, and see if results are returned from the DocumentSelectorService
    System.out.println(new SpelExpressionParser().parseExpression(
        "@documentsSelectorService.getNextSetOfDocuments(
        T(org.mycompany.model.SomeClass))").getValue(evalContext )));
    Last edited by jzcfk9; Mar 17th, 2011, 08:13 PM.

    Comment


    • #3
      I think I figured out the cause. The service activator's service calls a DAO, which was receiving a RuntimeException. This RuntimeException appears to have affected the processing of one of the downstream aggregators.

      I'll need to re-think our Exception handling within the Service that's being called from my Service Activator.

      Comment


      • #4
        Just to clarify the error handling on a synchronous(single thread) workflow in Spring Integration...

        If a call to a handler (in my case a Service Activator) results in a RuntimeException, and the caller doesn't declare the RuntimeException as throwable, then Spring Integration will put the resulting exception into the message payload and send the message on to the declared output-channel of the Service Activator.

        Can someone verify my understanding is correct?

        Comment


        • #5
          Actually, if an Exception occurs within a Service Activator's handling of the Message and its uncaught, it will propagate back to the sender if you have no asynchronous behavior in the message flow (queue-based buffering, or task-executor dispatching). By the way, in terms of RuntimeExceptions, the 'throws' clause is really nothing more than documentation (since they are unchecked and don't require catching-or-declaring). The important point is whether the RuntimeException is caught or not.

          Hope that helps.
          -Mark

          Comment


          • #6
            Thanks for the clarification on error handling. I submitted JIRA 1842 for investigation into what payloads can be sent to the Service Activator's expression. In my case, I was sending a Class as the message payload, which was getting rejected by ExpressionCommandMessageProcessor. Seems it wants either an expression or a String. The documentation wasn't clear that the payload must be a String or Expression, so perhaps the documentation just need further clarification if this is the intended behavior.

            <service-activator input-channel="channel1" output-channel="channel2" expression="@myService.process(payload)" />

            Comment

            Working...
            X