Results 1 to 6 of 6

Thread: Sending Message on Control Bus Problem

  1. #1
    Join Date
    Jul 2010
    Posts
    139

    Default 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 at 12:04 PM.

  2. #2
    Join Date
    Jul 2010
    Posts
    139

    Default

    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 at 07:13 PM.

  3. #3
    Join Date
    Jul 2010
    Posts
    139

    Default

    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.

  4. #4
    Join Date
    Jul 2010
    Posts
    139

    Default

    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?

  5. #5
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,854

    Default

    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

  6. #6
    Join Date
    Jul 2010
    Posts
    139

    Default

    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)" />

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •