Hi folks, I am trying to figure out some of the more advanced Lingo usage... trying to get a simple working example of EventListener remoting, but so far I have had no luck.

I'm trying to get a super-simple ping/pong from a client to a set of nodes listening on a topic, where the invocation is one-way, and the server's ping responder will invoke a method on an ping listener to send its pong.

This is what I've got:

<snip>
public interface PingListener
    extends EventListener
{
    void pong();
}

public interface PingResponder
{
    void ping(PingListener listener);
}

public class PingResponderImpl
    implements PingResponder
{
    public void ping(final PingListener listener) {
        log.info("Responding to PING")
        listener.pong();
    }
}
</snip>

My client is also simple, though in this example I've trimmed out the bits which load the spring ctx and autowire the components:

<snip>
public class PingClient
{
    public void ping() {
        PingCollector collector = new PingCollector();
        responder.ping(collector);
        // wait for ctrl-c to end
    }

    public class PingCollector
        implements PingListener
    {
        public void pong() {
            log.info("Received PONG");
        }
    }
}
</snip>

And then the spring ctx:

<snip>
<beans xmlns="http://www.springframework.org/schema/beans";
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xsi:schemaLocation="http://www.springframework.org/schema/ beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd";>

<bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory" scope="singleton"> <property name="brokerURL" value="vm://localhost? broker.persistent=false"/>
    </bean>

<bean id="pingResponderDestination" class="org.apache.activemq.command.ActiveMQTopic" scope="singleton">
        <constructor-arg index="0" value="gbuild.pingResponder"/>
    </bean>

<bean id="pingResponder" class="org.logicblaze.lingo.jms.JmsProxyFactoryBean"> <property name="serviceInterface" value="org.apache.geronimo.gbuild.ping.PingResponder"/>
        <property name="connectionFactory" ref="jmsFactory"/>
        <property name="destination" ref="pingResponderDestination"/>
    </bean>

<bean id="pingReponderImpl" class="org.apache.geronimo.gbuild.ping.PingResponderImpl" scope="singleton"/>

<bean id="pingReponderService" class="org.logicblaze.lingo.jms.JmsServiceExporter" scope="singleton">
        <property name="service" ref="pingReponderImpl"/>
<property name="serviceInterface" value="org.apache.geronimo.gbuild.ping.PingResponder"/>
        <property name="connectionFactory" ref="jmsFactory"/>
        <property name="destination" ref="pingResponderDestination"/>
    </bean>
</beans>
</snip>

In this configuration, I see the "Responding to PING" and "Received PONG" log messages, which is followed by some exceptions after a delay:

<snip>
15:39:43,075 WARN [JmsClientInterceptor] Remote access error: invocation: method 'pong', arguments []; target is null javax.jms.JMSException: edu.emory.mathcs.backport.java.util.concurrent.TimeoutException at org.logicblaze.lingo.jms.impl.MultiplexingRequestor.createJMSException (MultiplexingRequestor.java:205) at org.logicblaze.lingo.jms.impl.MultiplexingRequestor.request (MultiplexingRequestor.java:133) at org.logicblaze.lingo.jms.JmsClientInterceptor.invoke (JmsClientInterceptor.java:138) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:185) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke (JdkDynamicAopProxy.java:209)
        at $Proxy6.pong(Unknown Source)
...
</snip>

And then a warning from the MultiplexingRequestor:

<snip>
15:39:43,113 WARN [MultiplexingRequestor] Response received for unknown correlationID: 2 request: ActiveMQObjectMessage {commandId = 9, responseRequired = true, messageId = ID:Bliss.local-52836-1162510752209-2:6:1:1:2, originalDestination = null, originalTransactionId = null, producerId = ID:Bliss.local-52836-1162510752209-2:6:1:1, destination = temp- queue://ID:Bliss.local-52836-1162510752209-2:13:1, transactionId = null, expiration = 1162510813098, timestamp = 1162510783104, arrival = 0, correlationId = 2, replyTo = null, persistent = true, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = [EMAIL PROTECTED], marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 12390, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false}
</snip>

And at this point, the method call to responder.ping() is still blocking.

If I change the destination to use a queue, then I get the same timeout trace, but the call to responder.ping() unblocks due to the JMSException being propagated.

If I enable a metadata strategy to make this async for one way voids, with something like:

<snip>
<bean id="pingResponder" class="org.logicblaze.lingo.jms.JmsProxyFactoryBean"> <property name="serviceInterface" value="org.apache.geronimo.gbuild.ping.PingResponder"/>
        <property name="connectionFactory" ref="jmsFactory"/>
        <property name="destination" ref="pingResponderDestination"/>
        <property name="metadataStrategy">
            <bean class="org.logicblaze.lingo.SimpleMetadataStrategy">
                <constructor-arg value="true"/>
            </bean>
        </property>
    </bean>
</snip>

The I see the "Responding to PING" but right after I get this exception:

<snip>
15:46:35,401 WARN [RemoteInvocationTraceInterceptor] Processing of JmsServiceExporter remote call resulted in fatal exception: org.apache.geronimo.gbuild.ping.PingResponder.ping java.lang.UnsupportedOperationException: A destination must be specified. at org.apache.activemq.ActiveMQMessageProducer.send (ActiveMQMessageProducer.java:448) at org.logicblaze.lingo.jms.impl.OneWayRequestor.doSend (OneWayRequestor.java:196) at org.logicblaze.lingo.jms.impl.MultiplexingRequestor.doSend (MultiplexingRequestor.java:189) at org.logicblaze.lingo.jms.impl.OneWayRequestor.send (OneWayRequestor.java:101) at org.logicblaze.lingo.jms.impl.OneWayRequestor.send (OneWayRequestor.java:97) at org.logicblaze.lingo.jms.impl.MultiplexingRequestor.request (MultiplexingRequestor.java:122) at org.logicblaze.lingo.jms.JmsClientInterceptor.invoke (JmsClientInterceptor.java:138) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:185) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke (JdkDynamicAopProxy.java:209)
        at $Proxy6.pong(Unknown Source)
...
</snip>

I am using Apple's JDK 1.5, Lingo 1.3 and Spring 2.0. Other simple sync invocations work fine... but I really need to get something working for more complicated invocations to and from an arbitrary set of nodes.

Does anyone have any ideas how to get this working? I have been digging around in the lingo svn, looking at the tests. Looks like there is a test that uses an EventListener... and it appears to pass, but I don't know what I am doing differently.

I've also been looking for other input on the lingo nabble forums... but so far... no luck.

Any help is appreciated.

Thanks,

--jason

Reply via email to