Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: unidirectional counterpart of @Gateway ?

  1. #1
    Join Date
    Oct 2005
    Location
    Amsterdam
    Posts
    123

    Default 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 at 10:31 AM. Reason: confused in/out bound channel adapter
    Hans Westerbeek
    Software Engineer

  2. #2
    Join Date
    Oct 2005
    Location
    Amsterdam
    Posts
    123

    Default

    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?
    Hans Westerbeek
    Software Engineer

  3. #3
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,844

    Default

    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?

  4. #4
    Join Date
    Oct 2005
    Location
    Amsterdam
    Posts
    123

    Default

    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 at 05:14 PM. Reason: added jms note
    Hans Westerbeek
    Software Engineer

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

    Default

    What do you mean when you say that execution blocks?

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

  6. #6
    Join Date
    Oct 2005
    Location
    Amsterdam
    Posts
    123

    Default

    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)
    Hans Westerbeek
    Software Engineer

  7. #7
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,844

    Default

    What version are you using?

  8. #8
    Join Date
    Oct 2005
    Location
    Amsterdam
    Posts
    123

    Default

    I am using RC2. Wouldn't want to bother you with an older one
    Hans Westerbeek
    Software Engineer

  9. #9
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,844

    Default

    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?

  10. #10
    Join Date
    Oct 2005
    Location
    Amsterdam
    Posts
    123

    Default

    *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...
    Hans Westerbeek
    Software Engineer

Posting Permissions

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