Announcement Announcement Module
No announcement yet.
Converting Remote calls to use Jms:channel Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Converting Remote calls to use Jms:channel

    I am converting existing code which used to use Jini for remote method calls.

    The basic idea is that the end Service has a number of methods on it, and i want to call them remotely. I wanted to use jms as the transport.

    I have created an intial outline but run into a problem when using <jms:channel

    </root>][Headers={history=[[name=getStockOfTheWeek;type=gateway;timestamp=1263 365328929], [name=ServiceActivator for [com.jdv.b2b.research.aspect.AspectResearchImpl$$En hancerByCGLIB$$8beb13fe.getStockOfTheWeek]];type=endpoint;timestamp=1263365329030]], $timestamp=1263365328926, $id=26153905-2c05-4c03-8f6b-18a904eb1ea9}]
    WARN : org.springframework.jms.listener.DefaultMessageLis tenerContainer - Execution of JMS message listener failed, and no ErrorHandler has been set.
    org.springframework.integration.core.MessagingExce ption: failed to handle incoming JMS Message
    at org.springframework.integration.jms.JmsDestination BackedMessageChannel.onMessage(JmsDestinationBacke
    at org.springframework.jms.listener.AbstractMessageLi stenerContainer.doInvokeListener(AbstractMessageLi
    at org.springframework.jms.listener.AbstractMessageLi stenerContainer.invokeListener(AbstractMessageList
    at org.springframework.jms.listener.AbstractMessageLi stenerContainer.doExecuteListener(AbstractMessageL
    at org.springframework.jms.listener.AbstractPollingMe ssageListenerContainer.doReceiveAndExecute(Abstrac
    at org.springframework.jms.listener.AbstractPollingMe ssageListenerContainer.receiveAndExecute(AbstractP
    at org.springframework.jms.listener.DefaultMessageLis tenerContainer$AsyncMessageListenerInvoker.invokeL istener(
    at org.springframework.jms.listener.DefaultMessageLis tenerContainer$AsyncMessageListenerInvoker.execute OngoingLoop( 69)
    at org.springframework.jms.listener.DefaultMessageLis tenerContainer$
    Caused by: org.springframework.integration.message.MessageHan dlingException: error occurred in message handler [org.springframework.integration.handler.BridgeHand ler@ac97cc]
    at org.springframework.integration.handler.AbstractMe ssageHandler.handleMessage(AbstractMessageHandler. java:70)
    at org.springframework.integration.dispatcher.Unicast ingDispatcher.doDispatch( :103)
    at org.springframework.integration.dispatcher.Unicast ingDispatcher.dispatch( 0)
    at org.springframework.integration.jms.JmsDestination BackedMessageChannel.onMessage(JmsDestinationBacke
    ... 9 more
    Caused by: java.lang.IllegalStateException: Bridge handler requires an output channel
    at org.springframework.util.Assert.state( 384)
    at org.springframework.integration.handler.BridgeHand ler.verifyOutputChannel(
    at org.springframework.integration.handler.BridgeHand ler.handleRequestMessage(
    at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.handleMessageInternal(A
    at org.springframework.integration.handler.AbstractMe ssageHandler.handleMessage(AbstractMessageHandler. java:64)
    ... 12 more

    The scenario i have will work if i use <channel > but swapping to <jms:channel > i will get the error above.

    The Basic setup i have is a Gateway, annotated with @Component, and then the methods annotated with @Gateway and each method to have a request and reply channel, ie:

    @Gateway(requestChannel="stockOfTheWeek" , replyChannel = "stockOfTheWeekReply")
    AspectResearchResponse getStockOfTheWeek(AspectResearchStockOfTheWeekData Request request);

    There is an Implementation class which implements this gateway ie:

    public class AspectResearchImpl implements AspectResearchGateway, SmartLifecycle {

    Implementation methods are then:

    @ServiceActivator(inputChannel = "modelPortfolioView", outputChannel = "modelPortfolioViewReply")
    public AspectResearchResponse getModelPortfolioView(AspectResearchModelPortfolio ViewRequest request) {
    URL url = null;

    Relevant items of spring config are then:

    <context:component-scan base-package="com.jdv.b2b.research.aspect" />

    <!--<channel id="modelPortfolioView" />-->
    <!--<channel id="modelPortfolioViewReply" />-->

    <jms:channel id="modelPortfolioView" queue="requestQueue" />
    <jms:channel id="modelPortfolioViewReply" queue="responseQueue" />

    <gateway id="aspectGateway" service-interface="com.jdv.b2b.research.aspect.AspectResea rchGateway" />

    As you can see above i have a commented out section with the channel ids, if these are uncommented and the jms:channels commented all works fine.

    Changing only to jms:channels causes the Bridge handler requires output channel error.

    This was tested on M2 and CI-752.

    Am i doing something obviously wrong or is this an issue?

  • #2
    <gateway id="aspectGateway" service-interface="com.jdv.b2b.research.aspect.AspectResea rchGateway" />

    Looks like if i attempt the same thing, but use the jms:outbound gateways i can get what i desired. I was just hoping that jms:channel could be used by way of making one (smaller) definition.

    ie use:
    <channel id="stockOfTheWeek" />
    <channel id="modelPortfolioView" />


    <jms:outbound-gateway request-destination="requestQueue" reply-destination="responseQueue" receive-timeout="6000"

    <jms:outbound-gateway request-destination="requestQueue" reply-destination="responseQueue" receive-timeout="6000"

    <jms:inbound-gateway request-destination="requestQueue" request-channel="jmsOutputChannel"/>


    • #3
      Actually i can only use jms-outbound gateway wired through to the service-activator if the message request objects are different (obvious really)

      What i was trying to do though was to use the service activator annotated with the relevant channels initiated on the gateway such that the methods were mapping 1:1. Again this works with a standard channel, but not with a jms:channel.

      I am aware that i could rewrite the code to change the model and create specific request type objects rather than 1:1 calls, but i wanted to limit the impact on existing code and try to find the easiest way to implement my solution.

      Is anyone using jms:channel successfully ?