Open cmacdonald opened 4 years ago
Here's the top of the stack according to the JVM dump:
V [libjvm.dylib+0x3dd1e9] jni_GetObjectClass+0xe3
C [jnius.cpython-36m-darwin.so+0x42b3a] __pyx_f_5jnius_lookup_java_object_name+0x1a
C [jnius.cpython-36m-darwin.so+0x40b4c] __pyx_f_5jnius_convert_jobject_to_python+0x7c
C [jnius.cpython-36m-darwin.so+0x3fd2d] __pyx_f_5jnius_convert_jarray_to_python+0xaed
C [jnius.cpython-36m-darwin.so+0x34fcc] __pyx_f_5jnius_release_args+0x3cc
C [jnius.cpython-36m-darwin.so+0x4711a] __pyx_pw_5jnius_10JavaMethod_9__call__+0xf2a
C [python+0x9cc1] _PyObject_FastCallDict+0xb1
This may imply that the call succeeded (release_args) is called in the finally block (https://github.com/kivy/pyjnius/blob/master/jnius/jnius_export_class.pxi#L786)
Why is the jarray converted back to Python? in case it has been updated?
Segfault must be at or the following line. https://github.com/kivy/pyjnius/blob/8380ee8c1408d12df427faa34558e162cad878c6/jnius/jnius_utils.pxi#L210
also hitting this :/
This is still there with v1.3.0.
An easy and environment agnostic set of steps to reproduce :
docker run -it --rm agileops/centos-javapython:latest bash
pip3 install pyjnius==1.3.0
python3
And then run the following script
from jnius import autoclass
Arrays = autoclass('java.util.Arrays')
l = Arrays.asList(1, 2, 5)
Gives a nice core dump.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f95ca97a8d9, pid=20, tid=0x00007f95cdbea740
#
# JRE version: OpenJDK Runtime Environment (8.0_171-b10) (build 1.8.0_171-b10)
# Java VM: OpenJDK 64-Bit Server VM (25.171-b10 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V [libjvm.so+0x6858d9]
#
# Core dump written. Default location: //core or core.20
#
# An error report file with more information is saved as:
# //hs_err_pid20.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
#
Aborted (core dumped)
Solution? Nothing yet, switch to JPype.
A few notes for anyone who is trying this code under JPype.
JPype does handle this case though autoboxing without a casting operator, but may not be what you desire. The output of this autoconversion will be of type Number by contract as it has to refer to Python objects with a Python type int. Currently, the best match for this is java.lang.Long. In future releases, the exact type can be different (for example it may wish to use PyLong) as we try to better to actually store Python objects on Java objects rather than risk truncation.
>>> import jpype
>>> jpype.startJVM()
>>> Arrays = jpype.JClass('java.util.Arrays')
>>> l = Arrays.asList(1,2,5)
>>> print(type(l[0]))
<java class 'java.lang.Long'>
In general if you want a specific type of boxing casting first is needed
l = Arrays.asList(JInt(1),JLong(2),JShort(5))
Note that in JPype varargs can auto unpack lists. The reason this works is that varargs in Java is implemented as Object[] so a Python list is checked to see if it can be unpacked to Object[]. If the elements all have defined Java conversions then the list unpacks into the varargs without error.
>>> l = Arrays.asList([jpype.JInt(i) for i in (1,2,5)])
>>> print(type(l[0]))
<java class 'java.lang.Integer'>
Arrays.asList() uses varargs and a generic type