From bb5144427a1d828780bec94b80897978da768917 Mon Sep 17 00:00:00 2001 From: Tim Burgess Date: Fri, 10 Jun 2022 23:35:41 +0800 Subject: [PATCH] fix a couple of code paths where exceptions weren't checked for (at least before the next JNI call) This was discovered with -Xcheck:jni, leading to warnings like these ``` WARNING in native method: JNI call made without checking exceptions when required to from CallStaticObjectMethodA WARNING in native method: JNI call made without checking exceptions when required to from CallObjectMethodA WARNING in native method: JNI call made without checking exceptions when required to from CallBooleanMethodA WARNING in native method: JNI call made without checking exceptions when required to from CallObjectMethodA WARNING in native method: JNI call made without checking exceptions when required to from CallObjectMethodA WARNING in native method: JNI call made without checking exceptions when required to from CallStaticObjectMethodA WARNING in native method: JNI call made without checking exceptions when required to from CallObjectMethodA WARNING in native method: JNI call made without checking exceptions when required to from CallBooleanMethodA WARNING in native method: JNI call made without checking exceptions when required to from CallStaticObjectMethodA WARNING in native method: JNI call made without checking exceptions when required to from CallObjectMethodA WARNING in native method: JNI call made without checking exceptions when required to from CallBooleanMethodA ``` --- _javabridge.pyx | 16 ++++++++++++++++ javabridge/jutil.py | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/_javabridge.pyx b/_javabridge.pyx index 756ec67..9d0cb20 100644 --- a/_javabridge.pyx +++ b/_javabridge.pyx @@ -1008,6 +1008,14 @@ cdef class JB_Env: if oresult == NULL: result = None else: + # call apparently succeeded, however: + # make_jb_object will call back into JNI to make global ref, which + # triggers JNI warnings that we did not check for exceptions + # calling code should be doing this as well - but it doesn't + # have the opportunity to do so before the next JNI call in this + # path. + jnienv[0].ExceptionOccurred(jnienv) + result, e = make_jb_object(self, oresult) if e is not None: raise e @@ -1106,6 +1114,14 @@ cdef class JB_Env: if oresult == NULL: result = None else: + # call apparently succeeded, however: + # make_jb_object will call back into JNI to make global ref, which + # triggers JNI warnings that we did not check for exceptions + # calling code should be doing this as well - but it doesn't + # have the opportunity to do so before the next JNI call in this + # path. + jnienv[0].ExceptionOccurred(jnienv) + result, e = make_jb_object(self, oresult) if e is not None: raise e diff --git a/javabridge/jutil.py b/javabridge/jutil.py index 074d1be..bb85378 100644 --- a/javabridge/jutil.py +++ b/javabridge/jutil.py @@ -1246,9 +1246,17 @@ def get_nice_result(result, sig): rklass = env.get_object_class(result) m = env.get_method_id(rklass, 'getClass', '()Ljava/lang/Class;') rclass = env.call_method(result, m) + x = env.exception_occurred() + if x is not None: + raise JavaException(x) + rkklass = env.get_object_class(rclass) m = env.get_method_id(rkklass, 'isPrimitive', '()Z') is_primitive = env.call_method(rclass, m) + x = env.exception_occurred() + if x is not None: + raise JavaException(x) + if is_primitive: rc = get_class_wrapper(rclass, True) classname = rc.getCanonicalName()