beeware / rubicon-java Goto Github PK
View Code? Open in Web Editor NEWA bridge interface between Python and Java.
License: BSD 3-Clause "New" or "Revised" License
A bridge interface between Python and Java.
License: BSD 3-Clause "New" or "Revised" License
As I implement Toga support for Android, I notice that all rubicon-java
object accesses are JNI local references. This means they work great within one call to Python, but that they can't really be stored and used by a later call from Java to Python.
I find this pretty OK, now that I know about it. I'm bullish on declaring that rubicon-java
will avoid supporting JNI global refs. It means that we have less to worry about in terms of getting our references story right and testing that we're not creating object leaks for Java objects.
I think if we go this route, we may as well write in the README
or elsewhere in the docs that we're taking this approach, just to clarify this for users (myself included).
Or we could decide to add support for JNI global refs.
Or we could decide to switch entirely from JNI local refs to JNI global refs.
Perhaps this is just a giant can of worms, and we can close this issue and not worry about it.
Describe the bug
I'm not able to instantiate the JavaClass
. Segmentation fault (core dumped)
To Reproduce
Steps to reproduce the behavior:
make
librubicon.so
in RUBICON_LIBRARY
environment variablerubicon.java.JavaClass
the error happenedEnvironment:
Additional context
I didn't try to install the Briefcase or Toga yet
Is your feature request related to a problem? Please describe.
I wanted to call the Android Intent ACTION_OPEN_DOCUMENT where you can pass a String[] with file types.
This creates a rubicon error.
See this PR: beeware/toga#1158
Describe the solution you'd like
I would like to be able to pass in String[] to native Java methods (see PR, src/android/toga_android/window.py, open_file_dialog
I would like to map String[] to a variable, e.g.
String = JavaClass("java/lang/String")
myArray=String("one two three".split(" "))
See e.g. this test run:
https://github.com/beeware/rubicon-java/runs/658309145?check_suite_focus=true
IMHO it's not a showstopper for v0.2.0, but I wanted to flag it in so we don't lose track of it.
Describe the bug
As noted at beeware/briefcase#538, BeeWare doesn't work on Android API level 22 or older. But I've found that the app on page 2 of the tutorial also crashes on some newer Android versions.
The crash happens with the x86_64 emulator on API levels 23 and 25, but not on levels 26, 27 or 31. I don't know if it also affects physical devices, because I don't have one in the level 23-25 range.
I've reduced it to the following minimal example. Either the label or the button alone works fine: the crash only happens if I include both of them. Two labels is also fine.
import toga
from toga.style import Pack
from toga.style.pack import COLUMN, ROW
class HelloWorld(toga.App):
def startup(self):
main_box = toga.Box()
label = toga.Label("Hello world")
main_box.add(label)
button = toga.Button("Hello world")
main_box.add(button)
self.main_window = toga.MainWindow(title=self.formal_name)
self.main_window.content = main_box
self.main_window.show()
def main():
return HelloWorld()
Environment:
Log from API level 25:
D/MainActivity: Python.run() start
D/Python: Running 'helloworld' as __main__...
W/mple.helloworld: type=1400 audit(0.0:15): avc: denied { read } for name="/" dev="rootfs" ino=1 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:rootfs:s0 tclass=dir permissive=0
I/Python: Python app launched & stored in Android Activity class
A/art: art/runtime/indirect_reference_table.cc:132] JNI ERROR (app bug): local reference table overflow (max=512)
A/art: art/runtime/indirect_reference_table.cc:132] local reference table dump:
A/art: art/runtime/indirect_reference_table.cc:132] Last 10 entries (of 512):
A/art: art/runtime/indirect_reference_table.cc:132] 511: 0x70ff5510 java.lang.String "int"
A/art: art/runtime/indirect_reference_table.cc:132] 510: 0x70f5cd68 java.lang.Class<int>
A/art: art/runtime/indirect_reference_table.cc:132] 509: 0x12d5e870 java.lang.Class[] (1 elements)
A/art: art/runtime/indirect_reference_table.cc:132] 508: 0x12d02100 java.lang.reflect.Method
A/art: art/runtime/indirect_reference_table.cc:132] 507: 0x12d5e8a0 java.lang.reflect.Method[] (1 elements)
A/art: art/runtime/indirect_reference_table.cc:132] 506: 0x12c4f480 java.lang.String "getDimensionPixe... (21 chars)
A/art: art/runtime/indirect_reference_table.cc:132] 505: 0x12c4f440 java.lang.String "getDimensionPixe... (21 chars)
A/art: art/runtime/indirect_reference_table.cc:132] 504: 0x12c09e98 android.content.res.Resources
A/art: art/runtime/indirect_reference_table.cc:132] 503: 0x12c42230 org.beeware.android.MainActivity
A/art: art/runtime/indirect_reference_table.cc:132] 502: 0x12d0e6e0 java.lang.String "android"
A/art: art/runtime/indirect_reference_table.cc:132] Summary:
A/art: art/runtime/indirect_reference_table.cc:132] 1 of $Proxy1
A/art: art/runtime/indirect_reference_table.cc:132] 1 of $Proxy2
A/art: art/runtime/indirect_reference_table.cc:132] 1 of $Proxy0
A/art: art/runtime/indirect_reference_table.cc:132] 10 of org.beeware.android.MainActivity (1 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 1 of java.io.FileDescriptor
A/art: art/runtime/indirect_reference_table.cc:132] 79 of java.lang.reflect.Method (79 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 172 of java.lang.String (133 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 112 of java.lang.Class (89 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 15 of java.lang.Class[] (1 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 27 of java.lang.Class[] (1 elements) (27 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 14 of java.lang.Class[] (2 elements) (14 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 12 of java.lang.Class[] (3 elements) (12 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 11 of java.lang.Class[] (4 elements) (11 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 26 of java.lang.reflect.Method[] (1 elements) (26 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 2 of java.lang.reflect.Method[] (2 elements) (2 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 5 of java.lang.reflect.Method[] (3 elements) (5 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 2 of java.lang.reflect.Method[] (6 elements) (2 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 1 of java.lang.reflect.Method[] (22 elements)
A/art: art/runtime/indirect_reference_table.cc:132] 1 of java.lang.String[] (4 elements)
A/art: art/runtime/indirect_reference_table.cc:132] 3 of android.util.DisplayMetrics (1 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 1 of android.graphics.Typeface
A/art: art/runtime/indirect_reference_table.cc:132] 1 of android.widget.TextView
A/art: art/runtime/indirect_reference_table.cc:132] 3 of android.view.View (3 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 5 of android.content.res.Resources (1 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132] 1 of android.os.Looper
A/art: art/runtime/indirect_reference_table.cc:132] 1 of android.widget.Button
A/art: art/runtime/indirect_reference_table.cc:132] 1 of android.os.MessageQueue
A/art: art/runtime/indirect_reference_table.cc:132] 1 of android.widget.RelativeLayout
A/art: art/runtime/indirect_reference_table.cc:132] 2 of android.widget.RelativeLayout$LayoutParams (2 unique instances)
A/art: art/runtime/indirect_reference_table.cc:132]
A/art: art/runtime/runtime.cc:422] Runtime aborting...
A/art: art/runtime/runtime.cc:422] Aborting thread:
A/art: art/runtime/runtime.cc:422] "main" prio=10 tid=1 Runnable
A/art: art/runtime/runtime.cc:422] | group="" sCount=0 dsCount=0 obj=0x7612b260 self=0x7b50da695a00
A/art: art/runtime/runtime.cc:422] | sysTid=3303 nice=-10 cgrp=default sched=0/0 handle=0x7b50df011b40
A/art: art/runtime/runtime.cc:422] | state=R schedstat=( 0 0 0 ) utm=735 stm=126 core=3 HZ=100
A/art: art/runtime/runtime.cc:422] | stack=0x7fff22df3000-0x7fff22df5000 stackSize=8MB
A/art: art/runtime/runtime.cc:422] | held mutexes= "abort lock" "mutator lock"(shared held)
A/art: art/runtime/runtime.cc:422] native: #00 pc 0000000000531a6e /system/lib64/libart.so (_ZN3art15DumpNativeStackERNSt3__113basic_ostreamIcNS0_11char_traitsIcEEEEiP12BacktraceMapPKcPNS_9ArtMethodEPv+238)
A/art: art/runtime/runtime.cc:422] native: #01 pc 000000000050278c /system/lib64/libart.so (_ZNK3art6Thread9DumpStackERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEEbP12BacktraceMap+412)
A/art: art/runtime/runtime.cc:422] native: #02 pc 00000000004ef4cb /system/lib64/libart.so (_ZNK3art10AbortState10DumpThreadERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEEPNS_6ThreadE+43)
A/art: art/runtime/runtime.cc:422] native: #03 pc 00000000004ef232 /system/lib64/libart.so (_ZNK3art10AbortState4DumpERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE+274)
A/art: art/runtime/runtime.cc:422] native: #04 pc 00000000004e2000 /system/lib64/libart.so (_ZN3art7Runtime5AbortEPKc+128)
A/art: art/runtime/runtime.cc:422] native: #05 pc 000000000014ceae /system/lib64/libart.so (_ZN3art10LogMessageD1Ev+1630)
A/art: art/runtime/runtime.cc:422] native: #06 pc 00000000002cd310 /system/lib64/libart.so (_ZN3art22IndirectReferenceTable3AddEjPNS_6mirror6ObjectE+304)
A/art: art/runtime/runtime.cc:422] native: #07 pc 00000000003e29c0 /system/lib64/libart.so (_ZN3art3JNI21GetObjectArrayElementEP7_JNIEnvP13_jobjectArrayi+832)
A/art: art/runtime/runtime.cc:422] native: #08 pc 0000000000162e8b /system/lib64/libart.so (_ZN3art8CheckJNI21GetObjectArrayElementEP7_JNIEnvP13_jobjectArrayi+843)
A/art: art/runtime/runtime.cc:422] native: #09 pc 000000000000a43c /data/app/com.example.helloworld-1/lib/x86_64/libffi.so (???)
A/art: art/runtime/runtime.cc:422] native: #10 pc 000000000000977d /data/app/com.example.helloworld-1/lib/x86_64/libffi.so (???)
A/art: art/runtime/runtime.cc:422] native: #11 pc 0000000000009315 /data/app/com.example.helloworld-1/lib/x86_64/libffi.so (ffi_call+101)
A/art: art/runtime/runtime.cc:422] native: #12 pc 00000000000157bb /data/data/com.example.helloworld/files/python/stdlib/lib/python3.8/lib-dynload/_ctypes.cpython-38.so (_call_function_pointer+331)
A/art: art/runtime/runtime.cc:422] native: #13 pc 000000000001521f /data/data/com.example.helloworld/files/python/stdlib/lib/python3.8/lib-dynload/_ctypes.cpython-38.so (_ctypes_callproc+1119)
A/art: art/runtime/runtime.cc:422] native: #14 pc 000000000000a931 /data/data/com.example.helloworld/files/python/stdlib/lib/python3.8/lib-dynload/_ctypes.cpython-38.so (PyCFuncPtr_call+737)
A/art: art/runtime/runtime.cc:422] native: #15 pc 0000000000098ea2 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyObject_MakeTpCall+450)
A/art: art/runtime/runtime.cc:422] native: #16 pc 00000000001c8701 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #17 pc 00000000001c60b3 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #18 pc 00000000001c2cf4 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyEval_EvalFrameDefault+26452)
A/art: art/runtime/runtime.cc:422] native: #19 pc 00000000001bc596 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (PyEval_EvalFrameEx+86)
A/art: art/runtime/runtime.cc:422] native: #20 pc 0000000000099edb /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #21 pc 000000000009a0c9 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyFunction_Vectorcall+249)
A/art: art/runtime/runtime.cc:422] native: #22 pc 00000000001c8720 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #23 pc 00000000001c60b3 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #24 pc 00000000001c2d9f /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyEval_EvalFrameDefault+26623)
A/art: art/runtime/runtime.cc:422] native: #25 pc 00000000001bc596 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (PyEval_EvalFrameEx+86)
A/art: art/runtime/runtime.cc:422] native: #26 pc 0000000000099edb /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #27 pc 000000000009a0c9 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyFunction_Vectorcall+249)
A/art: art/runtime/runtime.cc:422] native: #28 pc 00000000001c8720 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #29 pc 00000000001c60b3 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #30 pc 00000000001c2d9f /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyEval_EvalFrameDefault+26623)
A/art: art/runtime/runtime.cc:422] native: #31 pc 00000000001bc596 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (PyEval_EvalFrameEx+86)
A/art: art/runtime/runtime.cc:422] native: #32 pc 0000000000099edb /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #33 pc 000000000009a0c9 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyFunction_Vectorcall+249)
A/art: art/runtime/runtime.cc:422] native: #34 pc 00000000001c8720 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #35 pc 00000000001c60b3 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #36 pc 00000000001c2d9f /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyEval_EvalFrameDefault+26623)
A/art: art/runtime/runtime.cc:422] native: #37 pc 00000000001bc596 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (PyEval_EvalFrameEx+86)
A/art: art/runtime/runtime.cc:422] native: #38 pc 0000000000099edb /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #39 pc 000000000009a0c9 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyFunction_Vectorcall+249)
A/art: art/runtime/runtime.cc:422] native: #40 pc 000000000009f0d0 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #41 pc 000000000009e17d /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #42 pc 000000000009cac0 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #43 pc 000000000009aff8 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #44 pc 000000000009c5d5 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #45 pc 000000000009c9ba /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (PyObject_CallFunctionObjArgs+346)
A/art: art/runtime/runtime.cc:422] native: #46 pc 000000000011beee /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #47 pc 00000000001178a6 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #48 pc 00000000000f8fc7 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (PyObject_GetAttr+151)
A/art: art/runtime/runtime.cc:422] native: #49 pc 00000000000f9da6 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyObject_GetMethod+118)
A/art: art/runtime/runtime.cc:422] native: #50 pc 00000000001c2c12 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyEval_EvalFrameDefault+26226)
A/art: art/runtime/runtime.cc:422] native: #51 pc 00000000001bc596 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (PyEval_EvalFrameEx+86)
A/art: art/runtime/runtime.cc:422] native: #52 pc 0000000000099edb /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #53 pc 000000000009a0c9 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyFunction_Vectorcall+249)
A/art: art/runtime/runtime.cc:422] native: #54 pc 00000000001c8720 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #55 pc 00000000001c60b3 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #56 pc 00000000001c2d34 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyEval_EvalFrameDefault+26516)
A/art: art/runtime/runtime.cc:422] native: #57 pc 00000000001bc596 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (PyEval_EvalFrameEx+86)
A/art: art/runtime/runtime.cc:422] native: #58 pc 0000000000099edb /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #59 pc 000000000009a0c9 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyFunction_Vectorcall+249)
A/art: art/runtime/runtime.cc:422] native: #60 pc 00000000000a99a0 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #61 pc 00000000000a9928 /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #62 pc 00000000000a82cd /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (???)
A/art: art/runtime/runtime.cc:422] native: #63 pc 00000000000f998b /data/app/com.example.helloworld-1/lib/x86_64/libpython3.8.so (_PyObject_GenericGetAttrWithDict+315)
A/art: art/runtime/runtime.cc:422] at org.beeware.rubicon.Python.run(Native method)
A/art: art/runtime/runtime.cc:422] at org.beeware.android.MainActivity.startPython(MainActivity.java:231)
A/art: art/runtime/runtime.cc:422] at org.beeware.android.MainActivity.onCreate(MainActivity.java:248)
A/art: art/runtime/runtime.cc:422] at android.app.Activity.performCreate(Activity.java:6679)
A/art: art/runtime/runtime.cc:422] at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
A/art: art/runtime/runtime.cc:422] at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
A/art: art/runtime/runtime.cc:422] at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
A/art: art/runtime/runtime.cc:422] at android.app.ActivityThread.-wrap12(ActivityThread.java:-1)
A/art: art/runtime/runtime.cc:422] at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
A/art: art/runtime/runtime.cc:422] at android.os.Handler.dispatchMessage(Handler.java:102)
A/art: art/runtime/runtime.cc:422] at android.os.Looper.loop(Looper.java:154)
A/art: art/runtime/runtime.cc:422] at android.app.ActivityThread.main(ActivityThread.java:6119)
A/art: art/runtime/runtime.cc:422] at java.lang.reflect.Method.invoke!(Native method)
A/art: art/runtime/runtime.cc:422] at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
A/art: art/runtime/runtime.cc:422] at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Describe the bug
It seems to want to call the hashCode() method but the Python Object doesn't know about hashCode
To Reproduce
Steps to reproduce the behavior:
This guy is having the same problem doing the same thing as me.
https://gist.github.com/telent/6409c94ff9a4f448ecbd6b5859718669
My Code:
ILocationListener = JavaInterface('android/location/LocationListener')
class location_helper(ILocationListener):
........
_location_helper = location_helper()
LocationManager = JavaClass('android/location/LocationManager')
location_manager_object = self.activity.getSystemService('location')
print(str(location_manager_object))
location_manager = LocationManager(__jni__=java.NewGlobalRef(location_manager_object))
print(str(location_manager))
location_manager.requestLocationUpdates("gps", 0, 0.0, self._location_helper)
I uncommented line 32 of rubicon/java/api.py and added this at line 34
print(str(pyinstance._methods))
Results:
07-23 15:35:03.969 15631 15631 I Python : android.location.LocationManager@f81e026
07-23 15:35:03.972 15631 15631 I Python : android.location.LocationManager@f81e026
07-23 15:35:03.983 15631 15631 D Python : Native invocation 514799255360 :: hashCode
07-23 15:35:03.983 15631 15631 I Python : PYTHON SIDE DISPATCH 514799255360 hashCode ()
07-23 15:35:03.984 15631 15631 I Python : {'onLocationChanged': {(b'Landroid/location/Location;',)}, 'onProviderDisabled': {(b'Ljava/lang/String;',)}, 'onProviderEnabled': {(b'Ljava/lang/String;',)}, 'onStatusChanged': {(b'Ljava/lang/String;', b'I', b'Landroid/os/Bun
dle;')}}
07-23 15:35:03.984 15631 15631 E Python : Error invoking callback
07-23 15:35:03.984 15631 15631 E Python : Traceback (most recent call last):
07-23 15:35:03.984 15631 15631 E Python : File "/data/user/0/au.gov.aims.gregbee/files/python/user_code/app_packages/rubicon/java/api.py", line 37, in dispatch
07-23 15:35:03.985 15631 15631 E Python : if len(signatures) == 1:
07-23 15:35:03.985 15631 15631 E Python : TypeError: object of type 'NoneType' has no len()
Expected behavior
I am pretty sure the error is coming from this line
location_manager.requestLocationUpdates("gps", 0, 0.0, self._location_helper)
I want that line to run without an error
Screenshots
If applicable, add screenshots to help explain your problem.
Environment:
Additional context
Add any other context about the problem here.
Hi, I see there's only very little bit of C in repository.
Which makes me wonder, how hard would it be to use PyPy as interpreter instead of CPython?
If this is truly difficult, please document what the hard points are.
Thanks for the awesome project!
D.
Describe the bug
When running the test suite on Apple Silicon, an error is generated because the librubicon.dylib is compiled for arm64 architecture, not x86_64. An x86_64 build is required regardless of the native platform because Java does not currently provide an arm64 build.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Test suite should pass.
Screenshots
Running tox -e py39
yields:
...
Exception in thread "main" java.lang.UnsatisfiedLinkError: /Users/rkm/beeware/rubicon/java/build/librubicon.dylib: dlopen(/Users/rkm/beeware/rubicon/java/build/librubicon.dylib, 0x0001): tried: '/Users/rkm/beeware/rubicon/java/build/librubicon.dylib' (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')), '/usr/local/lib/librubicon.dylib' (no such file), '/usr/lib/librubicon.dylib' (no such file)
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1946)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1861)
at java.lang.Runtime.loadLibrary0(Runtime.java:871)
at java.lang.System.loadLibrary(System.java:1124)
at org.beeware.rubicon.Python.<clinit>(Python.java:27)
at org.beeware.rubicon.test.Test.main(Test.java:7)
make: *** [test] Error 1
Environment:
Do you have a detailed tutorial?
I didn't find a detailed tutorial on the official website.
I use rubicon-java can't access android classes,such as "machine_build = JavaClass('android.os.Build')"
Traceback (most recent call last):
File "/dima/j2/lib/python2.7/site-packages/pip/basecommand.py", line 122, in main
status = self.run(options, args)
File "/dima/j2/lib/python2.7/site-packages/pip/commands/install.py", line 278, in run
requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
File "/dima/j2/lib/python2.7/site-packages/pip/req.py", line 1177, in prepare_files
url = finder.find_requirement(req_to_install, upgrade=self.upgrade)
File "/dima/j2/lib/python2.7/site-packages/pip/index.py", line 277, in find_requirement
raise DistributionNotFound('No distributions at all found for %s' % req)
DistributionNotFound: No distributions at all found for rubicon-java
tested with both python 2.7 and 3.4 on linux.
Is your feature request related to a problem? Please describe.
Java differentiates between "local" and "global" JNI references. Local references only last as long the JNI invocation; global references persist between invocations.
Rubicon generates local references by default, but sometimes a global JNI reference is required.
Rubicon should have a mechanism to convert a local JNI reference to a global reference.
Describe the solution you'd like
A naive implementation would be something like:
def jni_global(instance):
return instance.__class__(__jni__=java.NewGlobalRef(instance))
This would involve "casting" local objects to be global. It might be possible to add this as an instance method, although we would need to be careful about potential overload between this utility instance method, and actual methods on the Java instance.
Additional context
See https://github.com/beeware/toga/pull/1242/files#r606873807 for historical context.
Describe the bug
If there's a Java exception, we need to at least clear the exception so JNI knows we're aware of it.
When do we so, it is smart to print its stacktrace or otherwise do something useful for debugging. It might be sensible to raise a Python exception.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Clear the JNI exception state. Additionally, perhaps see a Java stacktrace or other information about what caused the exception, perhaps in the form of a Python exception.
Actual behavior
On Android, the process gets killed, and this gets logged. Note the text about a "pending exception."
I/DEBUG ( 1143): signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
I/DEBUG ( 1143): Abort message: 'art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: JNI NewGlobalRef called with pending exception 'java.lang.ClassNotFoundException' thrown in unknown throw location'
I/DEBUG ( 1143): eax 00000000 ebx 00000a47 ecx 00000a47 edx 00000006
I/DEBUG ( 1143): esi b77cfc48 edi 0000000b
I/DEBUG ( 1143): xcs 00000073 xds 0000007b xes 0000007b xfs 00000007 xss 0000007b
I/DEBUG ( 1143): eip b755d2e6 ebp 00000a47 esp bf96dcd0 flags 00000286
Additional context
See e.g. https://www.developer.com/java/data/exception-handling-in-jni.html and https://docs.oracle.com/en/java/javase/13/docs/specs/jni/functions.html#exceptioncheck to check for these exceptions.
Currently, rubicon-java
cannot be used to implement a Java Interface's methods that return data types other than int
and void
. This means the following Interface is unimplementable in Python at the moment.
interface StringMaker {
public String makeString();
}
If a rubicon-java user attempts to implement an interface like that with Python code such as:
StringMaker = JavaInterface("StringMaker")
class MakeString(StringMaker):
def makeString(self):
return "I like string"
Java will crash with a NullPointerException
.
This is fixable; hence this ticket. :) We can either blindly convert a method's return type to the most relevant Java type, or we can introspect the Java Interface to see what is expected.
Currently non-working return types include String
, really all Object
s, long
, float
, double
, etc. See also #42, which added support for returning int
.
Describe the bug
If you attempt to start an asyncio event loop on Android using Python 3.6, the app will crash.
The problem appears to be that run_loop_cooperatively()
references _set_coroutine_origin_tracking()
, which didn't exist in Python 3.6.
To Reproduce
A vanilla briefcase Hello World app, deployed to Android, using Python 3.6.
See beeware/briefcase#454 for details and an error log.
Right now, rubicon-java only looks at the immediate interfaces a class implements along with its superclasses. ArrayAdapter
in Android fails to find SpinnerAdapter
, so we have to do this ugly hinting.
https://github.com/beeware/toga/pull/905/files#diff-2a4e44cc48a82e70ea678ecb88a8a66fR23
# Indicate to `rubicon-java` that `ArrayAdapter` can also be typecast into a
# `SpinnerAdapter`. This is required until `rubicon-java` explores the interfaces
# implemented by a class's subclasses.
ArrayAdapter._alternates.append(b'Landroid/widget/SpinnerAdapter;')
Is your feature request related to a problem? Please describe.
Some Java methods return java.lang.Object
, and expect the end user to cast the return type into the object type they need. For example, Android's getSystemService()
method returns java.lang.Object, but the underlying objects are types like android.content.ClipboardManager
.
Rubicon should provide a simple mechanism for casting objects into different (but compatible) types.
Describe the solution you'd like
Something like the following should be possible:
typecast_object = java_cast(generic_object, MyJavaClass)
which would convert the java.lang.Object
instance generic_object
into the MyJavaClass
instance typecast_object
. typecast_object
could then be used anywhere that a MyJavaClass
argument is required.
Describe alternatives you've considered
This can be achieved manually; e.g., in the Android Clipboard example:
from rubicon.java.jni import java
tmp = self._native_activity.getSystemService("clipboard")
clipboard_manager = android.ClipboardManager(__jni__=java.NewGlobalRef(tmp))
where ClipboardManager
is an instance of JavaClass('android/content/ClipboardManager')
.
Additional context
This example code implicitly creates a global JNI reference; it might be desirable to make local/global referencing an option.
#23 added an explicit warning for any attempt to subclass a Java class.
This is a workaround to flag a known error case. We should add support for subclassing.
The underlying problem is that a Java-side object is needed to serve as the recipient for Java invocations. The approach used for interfaces (java.lang.reflect.InvocationHandler
) won't work, because InvocationHandler
explicitly takes Interfaces, not classes.
One possible solution: Use Python metaclass handling to define the bytecode for a class implementation that can proxy it's calls into native invocations, and use a ClassLoader
to instantiate an instance of that class that can be wrapped Python-side.
Some edge cases that will need to be handled:
Syntactically, something like the following should be possible:
class MyStackClass(
JavaClass,
extends="java.lang.Stack",
implements=["org.example.FirstInterface", "org.example.OtherInterface"]
):
def push(self, item: "java.lang.Object") -> None:
...
def ElementAt(self, index: int) -> "java.lang.Object":
...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.