Announcement Announcement Module
Collapse
No announcement yet.
unidirectional counterpart of @Gateway ? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • unidirectional counterpart of @Gateway ?

    Hi all,

    I have a use-case where I want a component to put a message into a channel, much like an event.

    First off, i implemented this through using @Gateway. So, my BussinessService got injected with a bean that was created by the GatewayProxyFactoryBean.

    That worked, even though i purposely did not specify a reply-channel.
    But then I read in the ref-doc that gateways are intended for bidirectional and channel adapters for unidirectional messaging, which is what I am doing. So, I refactored my gateway interface to become a class, let's say it's called MessagingDelegate, annotated with @MessageEndpoint. It has two methods: copy(Item item) and remove(String itemId). For those methods I want item and itemId to be the payload of the message.

    Right now I am confused how to get it working again, or if my approach even makes sense... I tried inbound-channel-adapter which I tied to the copy and remove methods of my MessageDelegate bean that did not yield any results. No messages end up in a channel.

    Any input is greatly appreciated
    Last edited by mirror303; Nov 18th, 2008, 10:31 AM. Reason: confused in/out bound channel adapter

  • #2
    Let me rephrase slightly, I did not really get the @Gateway solution to work completely. The message is sent and processed by its consumer, which is invoked through a service-activator. However, it remains blocked-waiting, e.g. the proxy object backing the gateway interface never returns.

    Basically I am looking for a setup which allows me to have a publish-subscribe-channel on which the producer is not interested to hear from any consumer about what they did with a message, e.g. no reply-channel is required.

    Or does that seem a bit misguided?

    Comment


    • #3
      Your use-case definitely makes sense. Can you provide an excerpt from your configuration for the 'gateway' element and also the relevant method(s) on the interface?

      Comment


      • #4
        Thnx for your reply mark..

        the code+config follows By the way, i have left JMS out of the picture for now, i am running this as a unit test.

        this is gateway interface on the producer side:

        Code:
        public interface Publisher {	
        	void publish(Publication publication);
        }
        The Publication class encapsulates a few objects that need to be processed on the consumer side.

        config for this gateway
        Code:
        <gateway id="publisher" 
        		service-interface="nl.foo.service.publication.Publisher"
        		default-request-channel="publications"
        		/>
        channel:
        Code:
        <publish-subscribe-channel id="publications" />
        I suppose i may as well add the consumer side while i'm at it...

        the method to be invoked on the receiving end of the channel has the following signature:
        Code:
        void publish(Publication publication);
        And its corresponding XML:

        Code:
        <service-activator input-channel="publications" ref="advertPublishService"
                               method="publish" />
        Execution becomes blocked waiting and this is the last debug log output:
        Code:
        DEBUG [11-19-2008 00:04:06][org.springframework.integration.channel.PublishSubscribeChannel:169] postSend (sent=true) on channel 'publications', message: [Payload=nl.foo.domain.message.Publication@665f78a2][Headers={spring.integration.id=0bf0c288-f605-4aeb-bd1f-c00f0df5a9f4, spring.integration.replyChannel=org.springframework.integration.channel.MessageChannelTemplate$TemporaryReturnAddress@3866ee93, spring.integration.errorChannel=org.springframework.integration.channel.MessageChannelTemplate$TemporaryReturnAddress@3866ee93, spring.integration.timestamp=1227049446424}]
        Last edited by mirror303; Nov 18th, 2008, 05:14 PM. Reason: added jms note

        Comment


        • #5
          What do you mean when you say that execution blocks?

          Is the method referenced by the service-activator being invoked?

          Comment


          • #6
            Yes the method designated as service-activator is invoked and it sucessfully receives and processes the message. But when this method is done and control-flow returns into the framework, execution stops at MessageChannelTemplate on line 224.

            So, consequently, control in my producer never gets past its call to the gateway proxy. (the publish() method) as described above. Maybe it is waiting for a reply it will never receive?

            Here's the thread dump:

            Code:
            "main" prio=5 tid=0x0000000101803800 nid=0x100401000 waiting on condition [0x00000001003fe000..0x0000000100400c40]
               java.lang.Thread.State: WAITING (parking)
            	at sun.misc.Unsafe.park(Native Method)
            	- parking to wait for  <0x000000010508d598> (a java.util.concurrent.CountDownLatch$Sync)
            	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
            	at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:747)
            	at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:905)
            	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1217)
            	at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:207)
            	at org.springframework.integration.channel.MessageChannelTemplate$TemporaryReturnAddress.receive(MessageChannelTemplate.java:287)
            	at org.springframework.integration.channel.MessageChannelTemplate$TemporaryReturnAddress.receive(MessageChannelTemplate.java:281)
            	at org.springframework.integration.channel.MessageChannelTemplate.doReceive(MessageChannelTemplate.java:234)
            	at org.springframework.integration.channel.MessageChannelTemplate.doSendAndReceive(MessageChannelTemplate.java:250)
            	at org.springframework.integration.channel.MessageChannelTemplate.sendAndReceive(MessageChannelTemplate.java:214)
            	at org.springframework.integration.gateway.AbstractMessagingGateway.sendAndReceiveMessage(AbstractMessagingGateway.java:151)
            	at org.springframework.integration.gateway.AbstractMessagingGateway.sendAndReceive(AbstractMessagingGateway.java:135)
            	at org.springframework.integration.gateway.AbstractMessagingGateway.sendAndReceive(AbstractMessagingGateway.java:126)
            	at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:204)
            	at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:173)
            	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
            	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
            	at $Proxy8.publish(Unknown Source)
            	at nl.foo.service.service.AdvertServiceImpl.publishAdvert(AdvertServiceImpl.java:390)
            	at nl.foo.service.publication.PublicationTest.testPublication(PublicationTest.java:46)
            	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
            	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            	at java.lang.reflect.Method.invoke(Method.java:597)
            	at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:160)
            	at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:233)
            	at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:333)
            	at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
            	at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
            	at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
            	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:160)
            	at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
            	at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
            	at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
            	at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
            	at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
            	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97)
            	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
            	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
            	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
            	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
            	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
            	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

            Comment


            • #7
              What version are you using?

              Comment


              • #8
                I am using RC2. Wouldn't want to bother you with an older one

                Comment


                • #9
                  I thought so, but I was confused by the line numbers.

                  Since your gateway method has a 'void' return it should be calling the 'send' instead of 'sendAndReceive' in which case it would not be invoking receive() on the reply channel.

                  Here's the relevant code excerpt from GatewayProxyFactoryBean:
                  Code:
                  boolean shouldReply = returnType != void.class;
                  ...
                      Object[] args = invocation.getArguments();
                      if (shouldReply) {
                          response = isReturnTypeMessage ? gateway.sendAndReceiveMessage(args) : gateway.sendAndReceive(args);
                      }
                      else {
                          gateway.send(args);
                          response = null;
                      }
                  ...
                  Is there anything else other than what you posted earlier that could possibly affect this?

                  Comment


                  • #10
                    *blush*

                    I had classpath trouble with the eclipse maven plugin (m2).
                    It still let an old version of the gateway-interface exist on the classpath of my unit test (i had been changing stuff back and forth). Attaching the SI sources to the debugger brought that out...

                    Sorry for wasting your time...

                    Comment


                    • #11
                      No problem. Does this mean it's behaving as expected now?

                      Comment


                      • #12
                        yes it does

                        Comment


                        • #13
                          Great. I'm glad is was *just* a classpath issue.

                          Comment


                          • #14
                            Originally posted by mirror303 View Post
                            Sorry for wasting your time...
                            Don't blush too hard. Carefully documenting the resolution of a common error is not a waste of time. You will not be the last to run into this.

                            Comment

                            Working...
                            X