Giter Club home page Giter Club logo

rubicon-java's People

Contributors

bracketcove avatar freakboy3742 avatar glasnt avatar jacebrowning avatar paulproteus avatar romankharin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rubicon-java's Issues

Decide if rubicon-java will support JNI global refs

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.

Segmentation fault (core dumped) when instantiating the JavaClass

Describe the bug
I'm not able to instantiate the JavaClass. Segmentation fault (core dumped)

To Reproduce
Steps to reproduce the behavior:

  1. Cloned the repository;
  2. Installed the package locally
  3. Ran make
  4. Had to set librubicon.so in RUBICON_LIBRARY environment variable
  5. When I entered the python shell and tried to instantiate the rubicon.java.JavaClass the error happened

Screenshots
image
image

Environment:

  • Operating System: Ubuntu 20.04.2 LTS
  • Python version: 3.8.10

Additional context
I didn't try to install the Briefcase or Toga yet

Enable string arrays in Java methods

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

  1. 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

  2. I would like to map String[] to a variable, e.g.
    String = JavaClass("java/lang/String")
    myArray=String("one two three".split(" "))

Local reference table overflow on Android API levels 23-25

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:

  • Operating System: Windows 10
  • Python version: 3.8
  • Software versions:
    • Briefcase: 0.3.7
    • Toga: 0.3.0.dev34
    • rubicon-java: 0.2.6

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)

Error when an implementation of a java interface is used as parameter to a Java Object's Method

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:

  • Operating System: Developing on windows 10 for deployment to Android
  • Python version: 3.8
  • Software versions:
    • Briefcase: 0.3.5
    • Toga: 0.3.0
    • ...

Additional context
Add any other context about the problem here.

PyPy? (stretch goal)

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.

Rubicon-java test suite doesn't run on Apple Silicon

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:

  1. Run the rubicon Java test suite on Apple M1 hardware

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:

  • Operating System: macOS
  • Python version: Any
  • Software versions:
    • Rubicon Java 0.2.6

Pip install doesn't work

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.

Add ability to escalate references to global

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.

If a Java call triggers an exception, clear the exception so JNI can continue operation

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:

  • Run some Python code that triggers an unhandled Java exception
  • Immediately after that, run some more Python code that does operations against JNI

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

beeware/briefcase#538

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.

Add support for implementing interfaces with methods that expect `String` or `long` or other return types

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 Objects, long, float, double, etc. See also #42, which added support for returning int.

Explore the full inheritance/interface graph

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;')

Add ability to cast objects to different classes

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.

Add support for Java subclassing

#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:

  • Extending an abstract base class
  • Extending a class and adding additional interfaces.
  • Java code invoking a method on a Python class that overrides the definition on the base class
  • Java code invoking a method on a Python class that is not overridden.
  • Python code invoking a method from the base class
  • Python code invoking the super() implementation on the base class.

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":
        ...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.