Skip to content

Commit

Permalink
Fixes multiples memory leak in exception analysis, find_javaclass, an…
Browse files Browse the repository at this point in the history
…d class instanciations
  • Loading branch information
tito committed Jul 26, 2015
1 parent ae359e0 commit 2627d95
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 7 deletions.
2 changes: 2 additions & 0 deletions jnius/jnius_export_class.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class MetaJavaClass(type):
jcs.j_cls = j_env[0].CallStaticObjectMethod(
j_env, baseclass, getProxyClass, jargs)

j_env[0].DeleteLocalRef(j_env, baseclass)

if jcs.j_cls == NULL:
raise JavaException('Unable to create the class'
' {0}'.format(__javaclass__))
Expand Down
1 change: 1 addition & 0 deletions jnius/jnius_export_func.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ def find_javaclass(bytes name):

cls = Class(noinstance=True)
cls.instanciate_from(create_local_ref(j_env, jc))
j_env[0].DeleteLocalRef(j_env, jc)
return cls

27 changes: 20 additions & 7 deletions jnius/jnius_utils.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,21 @@ cdef void check_exception(JNIEnv *j_env) except *:
cdef jstring e_msg
cdef jboolean isCopy
cdef jthrowable exc = j_env[0].ExceptionOccurred(j_env)
cdef jclass cls_object = NULL
cdef jclass cls_throwable = NULL
if exc:
# ExceptionDescribe always writes to stderr, preventing tidy exception
# handling, so should only be for debugging
# j_env[0].ExceptionDescribe(j_env)
j_env[0].ExceptionClear(j_env)

toString = j_env[0].GetMethodID(j_env, j_env[0].FindClass(j_env, "java/lang/Object"), "toString", "()Ljava/lang/String;");
getMessage = j_env[0].GetMethodID(j_env, j_env[0].FindClass(j_env, "java/lang/Throwable"), "getMessage", "()Ljava/lang/String;");
getCause = j_env[0].GetMethodID(j_env, j_env[0].FindClass(j_env, "java/lang/Throwable"), "getCause", "()Ljava/lang/Throwable;");
getStackTrace = j_env[0].GetMethodID(j_env, j_env[0].FindClass(j_env, "java/lang/Throwable"), "getStackTrace", "()[Ljava/lang/StackTraceElement;");
cls_object = j_env[0].FindClass(j_env, "java/lang/Object")
cls_throwable = j_env[0].FindClass(j_env, "java/lang/Throwable")

toString = j_env[0].GetMethodID(j_env, cls_object, "toString", "()Ljava/lang/String;");
getMessage = j_env[0].GetMethodID(j_env, cls_throwable, "getMessage", "()Ljava/lang/String;");
getCause = j_env[0].GetMethodID(j_env, cls_throwable, "getCause", "()Ljava/lang/Throwable;");
getStackTrace = j_env[0].GetMethodID(j_env, cls_throwable, "getStackTrace", "()[Ljava/lang/StackTraceElement;");

e_msg = j_env[0].CallObjectMethod(j_env, exc, getMessage);
pymsg = None if e_msg == NULL else convert_jobject_to_python(j_env, <bytes> 'Ljava/lang/String;', e_msg)
Expand All @@ -62,6 +67,12 @@ cdef void check_exception(JNIEnv *j_env) except *:

pyexcclass = lookup_java_object_name(j_env, exc).replace('/', '.')

j_env[0].DeleteLocalRef(j_env, cls_object)
j_env[0].DeleteLocalRef(j_env, cls_throwable)
if e_msg != NULL:
j_env[0].DeleteLocalRef(j_env, e_msg)
j_env[0].DeleteLocalRef(j_env, exc)

raise JavaException('JVM exception occurred: %s' % (pymsg if pymsg is not None else pyexcclass), pyexcclass, pymsg, pystack)


Expand All @@ -88,7 +99,8 @@ cdef void _append_exception_trace_messages(
if len(pystack) > 0:
pystack.append("Caused by:")
pystack.append(pystr)
j_env[0].DeleteLocalRef(j_env, msg_obj)
if msg_obj != NULL:
j_env[0].DeleteLocalRef(j_env, msg_obj)

# Append stack trace messages if there are any.
if frames_length > 0:
Expand All @@ -98,7 +110,8 @@ cdef void _append_exception_trace_messages(
msg_obj = j_env[0].CallObjectMethod(j_env, frame, mid_toString)
pystr = None if msg_obj == NULL else convert_jobject_to_python(j_env, <bytes> 'Ljava/lang/String;', msg_obj)
pystack.append(pystr)
j_env[0].DeleteLocalRef(j_env, msg_obj)
if msg_obj != NULL:
j_env[0].DeleteLocalRef(j_env, msg_obj)
j_env[0].DeleteLocalRef(j_env, frame)

# If 'exc' has a cause then append the stack trace messages from the cause.
Expand All @@ -107,7 +120,7 @@ cdef void _append_exception_trace_messages(
if cause != NULL:
_append_exception_trace_messages(j_env, pystack, cause,
mid_getCause, mid_getStackTrace, mid_toString)
j_env[0].DeleteLocalRef(j_env, cause)
j_env[0].DeleteLocalRef(j_env, cause)

j_env[0].DeleteLocalRef(j_env, frames)

Expand Down

0 comments on commit 2627d95

Please sign in to comment.