Announcement Announcement Module
Collapse
No announcement yet.
Converting Remote calls to use Jms:channel Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • 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 dMessageChannel.java:158)
    at org.springframework.jms.listener.AbstractMessageLi stenerContainer.doInvokeListener(AbstractMessageLi stenerContainer.java:559)
    at org.springframework.jms.listener.AbstractMessageLi stenerContainer.invokeListener(AbstractMessageList enerContainer.java:498)
    at org.springframework.jms.listener.AbstractMessageLi stenerContainer.doExecuteListener(AbstractMessageL istenerContainer.java:467)
    at org.springframework.jms.listener.AbstractPollingMe ssageListenerContainer.doReceiveAndExecute(Abstrac tPollingMessageListenerContainer.java:323)
    at org.springframework.jms.listener.AbstractPollingMe ssageListenerContainer.receiveAndExecute(AbstractP ollingMessageListenerContainer.java:261)
    at org.springframework.jms.listener.DefaultMessageLis tenerContainer$AsyncMessageListenerInvoker.invokeL istener(DefaultMessageListenerContainer.java:977)
    at org.springframework.jms.listener.DefaultMessageLis tenerContainer$AsyncMessageListenerInvoker.execute OngoingLoop(DefaultMessageListenerContainer.java:9 69)
    at org.springframework.jms.listener.DefaultMessageLis tenerContainer$AsyncMessageListenerInvoker.run(Def aultMessageListenerContainer.java:871)
    at java.lang.Thread.run(Thread.java:619)
    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(UnicastingDispatcher.java :103)
    at org.springframework.integration.dispatcher.Unicast ingDispatcher.dispatch(UnicastingDispatcher.java:9 0)
    at org.springframework.integration.jms.JmsDestination BackedMessageChannel.onMessage(JmsDestinationBacke dMessageChannel.java:155)
    ... 9 more
    Caused by: java.lang.IllegalStateException: Bridge handler requires an output channel
    at org.springframework.util.Assert.state(Assert.java: 384)
    at org.springframework.integration.handler.BridgeHand ler.verifyOutputChannel(BridgeHandler.java:47)
    at org.springframework.integration.handler.BridgeHand ler.handleRequestMessage(BridgeHandler.java:41)
    at org.springframework.integration.handler.AbstractRe plyProducingMessageHandler.handleMessageInternal(A bstractReplyProducingMessageHandler.java:100)
    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:

    @MessageEndpoint
    @Configuration
    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:

    <integration:annotation-config/>
    <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" />

    Then:

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

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


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

    Comment


    • #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 ?

      Comment

      Working...
      X