question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

some proxy classes dissapear

See original GitHub issue

I have a reproducible test scenario. I overwrite System.setOut() and System.setErr() using two Java objects that each wrap a Python object accessing sys.stderr / sys.stdout. See https://github.com/terrier-org/pyterrier/blob/master/pyterrier/bootstrap.py#L85

I do some writing from Java to System.err, which calls back to the Python stderr stream, and works fine; The Java code then writes to System.out, which segfaults:

The relevant line in jnius_proxy.pxi is ret = py_obj.invoke(method, *py_args), where py_obj = <object><void *>jptr. I checked jptr - both have the correct value, but the cast back for the stdout doesnt work.

I have also seen

AttributeError: 'dict' object has no attribute 'invoke'
Traceback (most recent call last):
  File "jnius/jnius_proxy.pxi", line 156, in jnius.invoke0
  File "jnius/jnius_proxy.pxi", line 124, in jnius.py_invoke0

which others have reported. It appears that one of the Python objects that has been proxied is disappearing (I thought the Python object might be garbage collected, but even keeping a global reference to it doesnt help).

Do we know why the pointer can become invalid? I can try to develop a simplified test case.

Interestingly, if I keep a dict mapping the <long long> pointer back to the actual Python object, all works fine. This is illustrated in the patch below. This obviously keeps the Python object around for ever, but perhaps thats OK?

diff --git a/jnius/jnius_proxy.pxi b/jnius/jnius_proxy.pxi
index 0a1325c..8e04fdf 100644
--- a/jnius/jnius_proxy.pxi
+++ b/jnius/jnius_proxy.pxi
@@ -90,7 +90,8 @@ cdef jobject py_invoke0(JNIEnv *j_env, jobject j_this, jobject j_proxy, jobject
     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
+    py_obj = proxy_register[jptr]
+    #py_obj = <object><void *>jptr
 
     # extract the method information
     method = Method(noinstance=True)
@@ -149,6 +151,7 @@ cdef jobject py_invoke0(JNIEnv *j_env, jobject j_this, jobject j_proxy, jobject
     except Exception:
         traceback.print_exc()
 
+cdef dict proxy_register = {}
 
 cdef jobject invoke0(JNIEnv *j_env, jobject j_this, jobject j_proxy, jobject
         j_method, jobjectArray args) with gil:
@@ -174,6 +177,10 @@ cdef create_proxy_instance(JNIEnv *j_env, py_obj, j_interfaces, javacontext):
     invoke_methods[0].fnPtr = <void *>&invoke0
     j_env[0].RegisterNatives(j_env, nih.j_cls, <JNINativeMethod *>invoke_methods, 1)
 
+    print("Registering proxy for %s with interfaces %s, pointer %d"  % (py_obj.__class__, j_interfaces, <long long><void *>py_obj))
+    proxy_register[<long long><void *>py_obj] = py_obj
+    print(str(proxy_register))
+
     # create the proxy and pass it the invocation handler
     cdef JavaClass j_obj
     if javacontext == 'app':

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
cmacdonaldcommented, Apr 18, 2020

Yes, that matches with what I figured out. Indeed, keeping a global ref to the Python object fixes the issue. This commit fixes it: https://github.com/terrier-org/pyterrier/commit/156f68d2498f5da51102e2c667234a0d37f79b9c

I can make a PR for documentation change, then we can close the issue. Thanks both

1reaction
cmacdonaldcommented, Aug 19, 2022

GCd == garbage collected. The Python object goes out of scope to the Python interpreter, even if a reference to it still exists in Java land. See example of @tshirtman above.

See also https://github.com/kivy/pyjnius/blob/master/docs/source/api.rst#java-lambda-implementation-in-python-using-lambdas-and-function-references, particularly “You must hold a reference to the Python lambda for as long as it will be used by Java.”

Read more comments on GitHub >

github_iconTop Results From Across the Web

Missing proxy class 'Drupal\features\ProxyClass\ ...
Using the lastest Drupal 8 (-dev), when I install Drupal using a custom profile that contains some features, I have this error :...
Read more >
Proxy Classes missing in ECC Quality
Sometimes it happens that while creating proxy some of the objects were missed in TR so check in your TR whether it contains...
Read more >
Missing proxy classes when container compiles custom ...
The container is not build a states that there are missing proxy classes. This output is from the browser and it runs in...
Read more >
c# - Proxy class definition missing FieldSpecified properties
I am referencing an external SOAP service (by external I mean created by another development team) as a service reference in my .NET...
Read more >
Proxy settings disappearing - TechNet - Microsoft
I have users with Windows 7 and IE 9 who are supposed to receive a group policy setting their proxy settings. However at...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found