Message6641
First, note that threading.py contains these two classes:
class JavaThread(object):
class Thread(JavaThread):
That is, "JavaThread" extends only python objects (although it contains a native java thread). Therefore, it should be possible to extend both Thread and a java interface, and then pass an instance of the resulting class to a java function accepting the interface. However, if you try something like that after defining a single-method interface and a function that accepts an instance of that interface:
# BEGIN
from com.invitemedia.jython import JythonTestMethods
from com.invitemedia.jython import StringInterface
from threading import Thread
class Foo(Thread, StringInterface):
def stringMethod(self):
return "yo yo yo"
a = JythonTestMethods()
print a.doStringInterfaceThing(Foo())
# END
You end up with this error:
$ CLASSPATH=bin /opt/jython*/bin/jython ~/testThreadtojava.py
Traceback (most recent call last):
File "/home/dtm/testThreadtojava.py", line 11, in <module>
print a.doStringInterfaceThing(Foo())
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: argument type mismatch
The issue is a combination of how threading.JavaThread overrides __tojava__ and how PyObjectDerived implements __tojava__.
JavaThread says:
def __tojava__(self, c):
if isinstance(self._thread, c):
return self._thread
if isinstance(self, c):
return self
return Py.NoConversion
PyObjectDerived says (in part, but this is the relevant part):
PyType self_type=getType();
PyObject impl=self_type.lookup("__tojava__");
if (impl!=null)
return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class);
return super.__tojava__(c);
What happens is that JavaThread's __tojava__ method is first called with StringInterface; this hits the "return self" line, which then results in JavaThread's __tojava__ method being called with Java.lang.Object and hitting the "return self._thread" line. The end result is that PyObjectDerived's __tojava__ called with StringInterface.class returns an org.python.core.FunctionThread object.
I think that the best solution to this is to modify PyObjectDerived so that if __call__ to the __tojava__ method returns *this*, we delegate to super.__tojava__(c). Patch attached.
With the patch applied, the script above works as it should. |
|
Date |
User |
Action |
Args |
2011-09-07 14:02:08 | dtmGoogle | set | recipients:
+ dtmGoogle |
2011-09-07 14:02:08 | dtmGoogle | set | messageid: <1315404128.71.0.62079274999.issue1795@psf.upfronthosting.co.za> |
2011-09-07 14:02:08 | dtmGoogle | link | issue1795 messages |
2011-09-07 14:02:08 | dtmGoogle | create | |
|