[Py4j-users] An issue in reflection?
Status: Beta
Brought to you by:
barthe
From: Jeremy <ken...@gm...> - 2014-05-06 23:58:43
|
So I'm trying to use Py4j to let a UI talk to a Java server. The java server uses 3 threads (entry-point, server socket, client-event dispatch). The python UI registers an event call back listener and that listener eventually gets dumped into a Vector. I had some initial trouble getting the addEventListener() working but fixed it (somehow). But now any calls to removeEventListener() don't work. My first guess was something to do with different instances of the object when Vector does the lookup, but I'm not sure. I don't understand relfection concepts well enough and the Py->Java (callback) thing seems to suggest I should be fine since the original eventlistener hasn't been garbage collected yet. If you have any insight that would be great. Error: py4j.protocol.Py4JJavaError: An error occurred while calling t.removeEventListener. : py4j.Py4JException: An exception was raised by the Python Proxy. Return Message: x at py4j.Protocol.getReturnValue(Protocol.java:417) at py4j.reflection.PythonProxyHandler.invoke(PythonProxyHandler.java:113) at com.sun.proxy.$Proxy0.equals(Unknown Source) at java.util.Vector.indexOf(Vector.java:404) at java.util.Vector.indexOf(Vector.java:378) at java.util.Vector.removeElement(Vector.java:637) at java.util.Vector.remove(Vector.java:795) at pctelelog.EventOperatorThread.removeEventListener(EventOperatorThread.java:20) at pctelelog.ServerThread.removeEventListener(ServerThread.java:16) at pctelelog.Launcher.removeEventListener(Launcher.java:17) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) This code is a stripped down version of the development version but both are generating the same error. package pctelelog; public class Event { public String testData = "test"; } === package pctelelog; public interface EventListener { public void onEvent(Event event); } === package pctelelog; import java.util.Vector; public class EventOperatorThread extends Thread { private Vector<EventListener> m_listeners = new Vector<EventListener>(); public void run() { while(true) {} } public synchronized void addEventListener(EventListener listener) { System.out.println("ADD"); m_listeners.add(listener); } public synchronized void removeEventListener(EventListener listener) { System.out.println("REMOVE"); m_listeners.remove(listener); } } === package pctelelog; public class ServerThread extends Thread { private EventOperatorThread m_operator = new EventOperatorThread(); public void run() { m_operator.start(); while(true) {} } public synchronized void addEventListener(EventListener listener) { m_operator.addEventListener(listener); } public synchronized void removeEventListener(EventListener listener) { m_operator.removeEventListener(listener); } } === package pctelelog; import py4j.GatewayServer; public class Launcher { private ServerThread m_server = new ServerThread(); public Launcher() { m_server.start(); System.out.println("Server started."); } public void addEventListener(EventListener listener) { m_server.addEventListener(listener); } public void removeEventListener(EventListener listener) { m_server.removeEventListener(listener); } public static void main(String[] args) { GatewayServer gateway = new GatewayServer(new Launcher()); gateway.start(); } } === from py4j.java_gateway import JavaGateway, GatewayClient class EventListener(object): def onEvent(self, event): print event.testData; class Java: implements = ['pctelelog.EventListener'] class Launcher: def __init__(self): self.__gateway = JavaGateway(start_callback_server=True) listener = EventListener() self.__gateway.entry_point.addEventListener(listener) self.__gateway.entry_point.removeEventListener(listener) if __name__ == '__main__': Launcher() pass |