I assume now that these lines in jnius/jnius_proxy.pxi
and these lines cause the issue:
cdef jobject py_invoke0(JNIEnv *j_env, jobject j_this, jobject j_proxy, jobject
j_method, jobjectArray args) except * with gil:
from .reflect import get_signature, Method
cdef jfieldID ptrField
cdef jlong jptr
cdef object py_obj
cdef JavaClass method
cdef jobject j_arg
# get the python object
ptrField = j_env[0].GetFieldID(j_env,
j_env[0].GetObjectClass(j_env, j_this), "ptr", "J")
jptr = j_env[0].GetLongField(j_env, j_this, ptrField)
py_obj = <object><void *>jptr
# extract the method information
method = Method(noinstance=True)
method.instanciate_from(create_local_ref(j_env, j_method))
ret_signature = get_signature(method.getReturnType())
args_signature = [get_signature(x) for x in method.getParameterTypes()]
# convert java argument to python object
# native java type are given with java.lang.*, even if the signature say
# it's a native type.
py_args = []
convert_signature = {
'Z': 'Ljava/lang/Boolean;',
'B': 'Ljava/lang/Byte;',
'C': 'Ljava/lang/Character;',
'S': 'Ljava/lang/Short;',
'I': 'Ljava/lang/Integer;',
'J': 'Ljava/lang/Long;',
'F': 'Ljava/lang/Float;',
'D': 'Ljava/lang/Double;'}
for index, arg_signature in enumerate(args_signature):
arg_signature = convert_signature.get(arg_signature, arg_signature)
j_arg = j_env[0].GetObjectArrayElement(j_env, args, index)
py_arg = convert_jobject_to_python(j_env, arg_signature, j_arg)
j_env[0].DeleteLocalRef(j_env, j_arg)
py_args.append(py_arg)
# really invoke the python method
name = method.getName()
ret = py_obj.invoke(method, *py_args)
# convert back to the return type
# use the populate_args(), but in the reverse way :)
t = ret_signature[:1]
# did python returned a "native" type ?
jtype = None
if ret_signature == 'Ljava/lang/Object;':
# generic object, try to manually convert it
tp = type(ret)
if tp == int:
jtype = 'J'
elif tp == float:
jtype = 'D'
elif tp == bool:
jtype = 'Z'
elif len(ret_signature) == 1:
jtype = ret_signature
try:
return convert_python_to_jobject(j_env, jtype or ret_signature, ret)
except Exception as e:
traceback.print_exc(e)
cdef jobject invoke0(JNIEnv *j_env, jobject j_this, jobject j_proxy, jobject
j_method, jobjectArray args) with gil:
try:
return py_invoke0(j_env, j_this, j_proxy, j_method, args)
except Exception as e:
traceback.print_exc(e)
return NULL
cdef jobject convert_python_to_jobject(JNIEnv *j_env, definition, obj) except *:
cdef jobject retobject, retsubobject
cdef jclass retclass
cdef jmethodID redmidinit
cdef jvalue j_ret[1]
cdef JavaClass jc
cdef JavaObject jo
cdef JavaClassStorage jcs
cdef PythonJavaClass pc
cdef int index
if definition[0] == 'V':
return NULL
elif definition[0] == 'L':
if obj is None:
return NULL
elif isinstance(obj, basestring) and jstringy_arg(definition):
return j_env[0].NewStringUTF(j_env, <char *><bytes>obj)
elif isinstance(obj, str) and PY_MAJOR_VERSION >= 3 and jstringy_arg(definition):
utf8 = obj.encode('utf-8')
return j_env[0].NewStringUTF(j_env, <char *><bytes>utf8)
elif isinstance(obj, (int, long)) and \
definition in (
'Ljava/lang/Integer;',
'Ljava/lang/Number;',
'Ljava/lang/Long;',
'Ljava/lang/Object;'):
j_ret[0].i = obj
retclass = j_env[0].FindClass(j_env, 'java/lang/Integer')
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(I)V')
retobject = j_env[0].NewObjectA(j_env, retclass, retmidinit, j_ret)
return retobject
elif isinstance(obj, type):
jc = obj
return jc.j_cls
elif isinstance(obj, JavaClass):
jc = obj
check_assignable_from(j_env, jc, definition[1:-1])
return jc.j_self.obj
elif isinstance(obj, JavaObject):
jo = obj
return jo.obj
elif isinstance(obj, MetaJavaClass):
jcs = obj.__cls_storage
return jcs.j_cls
elif isinstance(obj, PythonJavaClass):
# from python class, get the proxy/python class
pc = obj
# get the java class
jc = pc.j_self
# get the localref
return jc.j_self.obj
elif isinstance(obj, (tuple, list)):
return convert_pyarray_to_java(j_env, definition, obj)
else:
raise JavaException('Invalid python object for this '
'argument. Want {0!r}, got {1!r}'.format(
definition[1:-1], obj))
elif definition[0] == '[':
if PY_MAJOR_VERSION < 3:
conversions = {
int: 'I',
bool: 'Z',
long: 'J',
float: 'F',
basestring: 'Ljava/lang/String;',
}
else:
conversions = {
int: 'I',
bool: 'Z',
long: 'J',
float: 'F',
str: 'Ljava/lang/String;',
bytes: 'B'
}
retclass = j_env[0].FindClass(j_env, 'java/lang/Object')
retobject = j_env[0].NewObjectArray(j_env, len(obj), retclass, NULL)
for index, item in enumerate(obj):
item_definition = conversions.get(type(item), definition[1:])
retsubobject = convert_python_to_jobject(
j_env, item_definition, item)
j_env[0].SetObjectArrayElement(j_env, retobject, index,
retsubobject)
return retobject
elif definition == 'B':
retclass = j_env[0].FindClass(j_env, 'java/lang/Byte')
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(B)V')
j_ret[0].b = obj
elif definition == 'S':
retclass = j_env[0].FindClass(j_env, 'java/lang/Short')
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(S)V')
j_ret[0].s = obj
elif definition == 'I':
retclass = j_env[0].FindClass(j_env, 'java/lang/Integer')
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(I)V')
j_ret[0].i = int(obj)
elif definition == 'J':
retclass = j_env[0].FindClass(j_env, 'java/lang/Long')
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(J)V')
j_ret[0].j = obj
elif definition == 'F':
retclass = j_env[0].FindClass(j_env, 'java/lang/Float')
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(F)V')
j_ret[0].f = obj
elif definition == 'D':
retclass = j_env[0].FindClass(j_env, 'java/lang/Double')
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(D)V')
j_ret[0].d = obj
elif definition == 'C':
retclass = j_env[0].FindClass(j_env, 'java/lang/Char')
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(C)V')
j_ret[0].c = ord(obj)
elif definition == 'Z':
retclass = j_env[0].FindClass(j_env, 'java/lang/Boolean')
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(Z)V')
j_ret[0].z = 1 if obj else 0
else:
assert(0)
assert(retclass != NULL)
# XXX do we need a globalref or something ?
retobject = j_env[0].NewObjectA(j_env, retclass, retmidinit, j_ret)
return retobject