diff -Nru java-atk-wrapper-0.33.3/debian/changelog java-atk-wrapper-0.33.3/debian/changelog --- java-atk-wrapper-0.33.3/debian/changelog 2018-02-19 23:31:08.000000000 +0000 +++ java-atk-wrapper-0.33.3/debian/changelog 2018-02-27 07:53:28.000000000 +0000 @@ -1,7 +1,27 @@ +java-atk-wrapper (0.33.3-20) unstable; urgency=medium + + * debian/patches/GC: drop spurious println (Closes: Bug#891604) + + -- Samuel Thibault Tue, 27 Feb 2018 08:53:28 +0100 + +java-atk-wrapper (0.33.3-19) unstable; urgency=medium + + * debian/patches/parameters: Fix atk signal parameters mismatch. + * debian/patches/coords: Fix atk component coordinates. + + -- Samuel Thibault Mon, 26 Feb 2018 00:16:36 +0100 + +java-atk-wrapper (0.33.3-18) unstable; urgency=medium + + * debian/patches/GC: new patch to fix memory leaks. + + -- Samuel Thibault Sun, 25 Feb 2018 23:04:45 +0100 + java-atk-wrapper (0.33.3-17) unstable; urgency=medium * debian/patches/iter: Fix iterator initialization. * debian/patches/child_add: Fix missing reference for children. + (Closes: Bug#837081) -- Samuel Thibault Tue, 20 Feb 2018 00:31:08 +0100 diff -Nru java-atk-wrapper-0.33.3/debian/patches/coords java-atk-wrapper-0.33.3/debian/patches/coords --- java-atk-wrapper-0.33.3/debian/patches/coords 1970-01-01 00:00:00.000000000 +0000 +++ java-atk-wrapper-0.33.3/debian/patches/coords 2018-02-27 07:53:01.000000000 +0000 @@ -0,0 +1,20 @@ +https://bugzilla.gnome.org/show_bug.cgi?id=793823 +--- + wrapper/org/GNOME/Accessibility/AtkComponent.java | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/wrapper/org/GNOME/Accessibility/AtkComponent.java ++++ b/wrapper/org/GNOME/Accessibility/AtkComponent.java +@@ -95,7 +95,11 @@ public class AtkComponent { + } + + public Rectangle get_extents() { +- return acc_component.getBounds(); ++ Rectangle rect = acc_component.getBounds(); ++ Point p = acc_component.getLocationOnScreen(); ++ rect.x = p.x; ++ rect.y = p.y; ++ return rect; + } + + public int get_layer () { diff -Nru java-atk-wrapper-0.33.3/debian/patches/GC java-atk-wrapper-0.33.3/debian/patches/GC --- java-atk-wrapper-0.33.3/debian/patches/GC 1970-01-01 00:00:00.000000000 +0000 +++ java-atk-wrapper-0.33.3/debian/patches/GC 2018-02-27 07:53:13.000000000 +0000 @@ -0,0 +1,2728 @@ +https://bugzilla.gnome.org/show_bug.cgi?id=793819 +--- + jni/src/AtkWrapper.c | 6 + jni/src/AtkWrapper.h | 7 + jni/src/jawaction.c | 63 ++++-- + jni/src/jawcomponent.c | 53 +++-- + jni/src/jaweditabletext.c | 58 ++++- + jni/src/jawhyperlink.c | 52 +++-- + jni/src/jawhypertext.c | 34 ++- + jni/src/jawimage.c | 28 +- + jni/src/jawimpl.c | 100 +++++++-- + jni/src/jawimpl.h | 2 + jni/src/jawobject.c | 80 ++++++- + jni/src/jawselection.c | 60 ++++- + jni/src/jawtable.c | 212 +++++++++++++++------ + jni/src/jawtablecell.c | 50 +++- + jni/src/jawtext.c | 116 ++++++++--- + jni/src/jawutil.c | 1 + jni/src/jawvalue.c | 40 ++- + wrapper/org/GNOME/Accessibility/AtkWrapper.java.in | 16 + + 18 files changed, 737 insertions(+), 241 deletions(-) + +--- a/jni/src/jawimpl.c ++++ b/jni/src/jawimpl.c +@@ -109,9 +109,9 @@ object_table_insert (JNIEnv *jniEnv, job + classAccessibleContext, + "hashCode", + "()I"); +- gint hash_key = (gint)(*jniEnv)->CallIntMethod(jniEnv, ac, jmid); ++ jaw_impl->hash_key = (gint)(*jniEnv)->CallIntMethod(jniEnv, ac, jmid); + g_mutex_lock(&objectTableMutex); +- g_hash_table_insert(objectTable, GINT_TO_POINTER(hash_key), GINT_TO_POINTER(jaw_impl)); ++ g_hash_table_insert(objectTable, GINT_TO_POINTER(jaw_impl->hash_key), jaw_impl); + g_mutex_unlock(&objectTableMutex); + } + +@@ -139,19 +139,51 @@ object_table_lookup (JNIEnv *jniEnv, job + } + + static void +-object_table_remove(JNIEnv *jniEnv, jobject ac) ++object_table_remove(JNIEnv *jniEnv, JawImpl *jaw_impl) + { +- jclass classAccessibleContext = (*jniEnv)->FindClass( jniEnv, +- "javax/accessibility/AccessibleContext" ); +- jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +- classAccessibleContext, +- "hashCode", +- "()I" ); +- gint hash_key = (gint)(*jniEnv)->CallIntMethod( jniEnv, ac, jmid ); ++ g_mutex_lock(&objectTableMutex); ++ g_hash_table_remove(objectTable, GINT_TO_POINTER(jaw_impl->hash_key)); ++ g_mutex_unlock(&objectTableMutex); ++} ++ ++/* Called on completion of Java GC, take the opportunity to look for stale jaw_impl */ ++void ++object_table_gc(JNIEnv *jniEnv) ++{ ++ GHashTableIter iter; ++ gpointer key, value; ++ GSList *list = NULL, *cur, *next; ++ int n = 0; + + g_mutex_lock(&objectTableMutex); +- g_hash_table_remove(objectTable, GINT_TO_POINTER(hash_key)); ++ if (objectTable) ++ { ++ g_hash_table_iter_init(&iter, objectTable); ++ while (g_hash_table_iter_next(&iter, &key, &value)) ++ { ++ n++; ++ JawImpl *jaw_impl = value; ++ if ((*jniEnv)->IsSameObject(jniEnv, jaw_impl->parent.acc_context, NULL)) ++ { ++ /* Got garbage-collected, mark for dropping */ ++ list = g_slist_prepend(list, jaw_impl); ++ } ++ } ++ } + g_mutex_unlock(&objectTableMutex); ++ /* fprintf(stderr,"%d objects\n", n); */ ++ ++ n = 0; ++ for (cur = list; cur != NULL; cur = next) ++ { ++ n++; ++ JawImpl *jaw_impl = cur->data; ++ g_object_unref(G_OBJECT(cur->data)); ++ next = g_slist_next(cur); ++ g_slist_free_1(cur); ++ } ++ /* fprintf(stderr,"%d dropped\n", n); */ ++ (void) n; + } + + GHashTable* +@@ -171,7 +203,7 @@ aggregate_interface(JNIEnv *jniEnv, JawO + { + JawImpl *jaw_impl = JAW_IMPL(tflag, jaw_obj); + +- jobject ac = jaw_obj->acc_context; ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); + jaw_impl->ifaceTable = g_hash_table_new(NULL, NULL); + + if (tflag & INTERFACE_ACTION) +@@ -273,6 +305,8 @@ aggregate_interface(JNIEnv *jniEnv, JawO + (gpointer)INTERFACE_TABLE_CELL, + (gpointer)info); + } ++ ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + } + + JawImpl* +@@ -280,6 +314,7 @@ jaw_impl_get_instance (JNIEnv *jniEnv, j + { + JawImpl *jaw_impl; + jniEnv = jaw_util_get_jni_env(); ++ jobject temp_ref; + + if (jniEnv == NULL) + return NULL; +@@ -298,10 +333,11 @@ jaw_impl_get_instance (JNIEnv *jniEnv, j + if (jaw_thread == g_thread_self()) + g_warning("jaw_impl_get_instance called from jaw_thread. If you are running a screen reader, this is expected\nIf you are not running a screen reader, please report this warning to the java-atk-wrapper package, explaining how to reproduce this warning\n"); + +- jobject global_ac = (*jniEnv)->NewGlobalRef(jniEnv, ac); +- if (global_ac != NULL) ++ temp_ref = (*jniEnv)->NewGlobalRef(jniEnv, ac); ++ if (temp_ref != NULL) + { +- guint tflag = jaw_util_get_tflag_from_jobj(jniEnv, global_ac); ++ jobject weak_ref = (*jniEnv)->NewWeakGlobalRef(jniEnv, temp_ref); ++ guint tflag = jaw_util_get_tflag_from_jobj(jniEnv, temp_ref); + jaw_impl = (JawImpl*)g_object_new(JAW_TYPE_IMPL(tflag), NULL); + if (jaw_impl != NULL) + { +@@ -309,15 +345,17 @@ jaw_impl_get_instance (JNIEnv *jniEnv, j + + if (jaw_obj != NULL) + { +- jaw_obj->acc_context = global_ac; ++ jaw_obj->acc_context = weak_ref; + jaw_obj->storedData = g_hash_table_new(g_str_hash, g_str_equal); + aggregate_interface(jniEnv, jaw_obj, tflag); + atk_object_initialize(ATK_OBJECT(jaw_impl), NULL); +- object_table_insert(jniEnv, global_ac, jaw_impl); ++ object_table_insert(jniEnv, weak_ref, jaw_impl); + } else + { + if (jaw_debug) + g_warning("jaw_impl_get_instance: jaw_obj == NULL"); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, temp_ref); ++ (*jniEnv)->DeleteWeakGlobalRef(jniEnv, weak_ref); + return NULL; + } + } else +@@ -325,6 +363,7 @@ jaw_impl_get_instance (JNIEnv *jniEnv, j + if (jaw_debug) + g_warning("jaw_impl_get_instance: jaw_impl == NULL"); + } ++ (*jniEnv)->DeleteGlobalRef(jniEnv, temp_ref); + } else + { + if (jaw_debug) +@@ -535,14 +574,12 @@ static void + jaw_impl_finalize(GObject *gobject) + { + JawObject *jaw_obj = JAW_OBJECT(gobject); +- jobject global_ac = jaw_obj->acc_context; +- + JawImpl *jaw_impl = (JawImpl*)jaw_obj; + + JNIEnv *jniEnv = jaw_util_get_jni_env(); +- object_table_remove( jniEnv, global_ac ); ++ object_table_remove( jniEnv, jaw_impl ); + +- (*jniEnv)->DeleteGlobalRef(jniEnv, global_ac); ++ (*jniEnv)->DeleteWeakGlobalRef(jniEnv, jaw_obj->acc_context); + jaw_obj->acc_context = NULL; + + /* Interface finalize */ +@@ -590,8 +627,8 @@ jaw_impl_initialize (AtkObject *atk_obj, + ATK_OBJECT_CLASS(jaw_impl_parent_class)->initialize(atk_obj, data); + + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); + + jclass classAtkWrapper = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkWrapper"); +@@ -600,6 +637,7 @@ jaw_impl_initialize (AtkObject *atk_obj, + "registerPropertyChangeListener", + "(Ljavax/accessibility/AccessibleContext;)V"); + (*jniEnv)->CallStaticVoidMethod(jniEnv, classAtkWrapper, jmid, ac); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + } + + static AtkObject* +@@ -611,8 +649,11 @@ jaw_impl_get_parent (AtkObject *atk_obj) + } + + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return NULL; ++ } + + jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv, + "javax/accessibility/AccessibleContext" ); +@@ -621,6 +662,7 @@ jaw_impl_get_parent (AtkObject *atk_obj) + "getAccessibleParent", + "()Ljavax/accessibility/Accessible;"); + jobject jparent = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + if (jparent != NULL ) + { + jclass classAccessible = (*jniEnv)->FindClass(jniEnv, +@@ -644,8 +686,11 @@ static AtkObject* + jaw_impl_ref_child (AtkObject *atk_obj, gint i) + { + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return NULL; ++ } + + jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv, + "javax/accessibility/AccessibleContext" ); +@@ -654,6 +699,7 @@ jaw_impl_ref_child (AtkObject *atk_obj, + "getAccessibleChild", + "(I)Ljavax/accessibility/Accessible;" ); + jobject jchild = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid, i ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + if (jchild == NULL) + { + return NULL; +@@ -774,8 +820,11 @@ jaw_impl_ref_relation_set (AtkObject *at + return NULL; + + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return NULL; ++ } + + jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv, + "javax/accessibility/AccessibleContext" ); +@@ -784,6 +833,7 @@ jaw_impl_ref_relation_set (AtkObject *at + "getAccessibleRelationSet", + "()Ljavax/accessibility/AccessibleRelationSet;" ); + jobject jrel_set = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + + jclass classAccessibleRelationSet = (*jniEnv)->FindClass( jniEnv, + "javax/accessibility/AccessibleRelationSet"); +--- a/jni/src/AtkWrapper.c ++++ b/jni/src/AtkWrapper.c +@@ -160,6 +160,12 @@ JNICALL Java_org_GNOME_Accessibility_Atk + } + } + ++JNIEXPORT void ++JNICALL Java_org_GNOME_Accessibility_AtkWrapper_GC(JNIEnv *jniEnv) ++{ ++ object_table_gc(jniEnv); ++} ++ + enum _SignalType { + Sig_Text_Caret_Moved = 0, + Sig_Text_Property_Changed_Insert = 1, +--- a/jni/src/AtkWrapper.h ++++ b/jni/src/AtkWrapper.h +@@ -23,6 +23,13 @@ JNIEXPORT void JNICALL Java_org_GNOME_Ac + + /* + * Class: org_GNOME_Accessibility_AtkWrapper ++ * Method: GC ++ * Signature: ()V ++ */ ++JNIEXPORT void JNICALL Java_org_GNOME_Accessibility_AtkWrapper_GC(JNIEnv *); ++ ++/* ++ * Class: org_GNOME_Accessibility_AtkWrapper + * Method: focusNotify + * Signature: (Ljavax/accessibility/AccessibleContext;)V + */ +--- a/jni/src/jawimpl.h ++++ b/jni/src/jawimpl.h +@@ -47,12 +47,14 @@ struct _JawImpl + JawObject parent; + + GHashTable *ifaceTable; ++ gint hash_key; + }; + + JawImpl* jaw_impl_get_instance(JNIEnv*, jobject); + JawImpl* jaw_impl_find_instance(JNIEnv*, jobject); + GHashTable* jaw_impl_get_object_hash_table(void); + GMutex* jaw_impl_get_object_hash_table_mutex(void); ++void object_table_gc(JNIEnv *jniEnv); + + GType jaw_impl_get_type (guint); + AtkRelationType jaw_impl_get_atk_relation_type(JNIEnv *jniEnv, jstring jrel_key); +--- a/wrapper/org/GNOME/Accessibility/AtkWrapper.java.in ++++ b/wrapper/org/GNOME/Accessibility/AtkWrapper.java.in +@@ -26,6 +26,9 @@ import java.beans.*; + import java.io.*; + import javax.accessibility.*; + import java.awt.Toolkit; ++import javax.management.*; ++import java.util.*; ++import java.lang.management.*; + + public class AtkWrapper { + static boolean accessibilityEnabled = false; +@@ -42,6 +45,17 @@ public class AtkWrapper { + break; + } + } ++ ++ java.util.List gcbeans = ManagementFactory.getGarbageCollectorMXBeans(); ++ for (GarbageCollectorMXBean gcbean : gcbeans) { ++ NotificationEmitter emitter = (NotificationEmitter) gcbean; ++ NotificationListener listener = new NotificationListener() { ++ public void handleNotification(Notification notif, Object handback) { ++ AtkWrapper.GC(); ++ } ++ }; ++ emitter.addNotificationListener(listener, null, null); ++ } + } catch (Exception e) { + e.printStackTrace(); + e.getCause(); +@@ -634,6 +649,7 @@ public class AtkWrapper { + + public native static boolean initNativeLibrary(); + public native static void loadAtkBridge(); ++ public native static void GC(); + + public native static void focusNotify(javax.accessibility.AccessibleContext ac); + +--- a/jni/src/jawobject.c ++++ b/jni/src/jawobject.c +@@ -205,8 +205,11 @@ static AtkObject* jaw_object_get_parent( + } + + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return NULL; ++ } + + jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv, + "javax/accessibility/AccessibleContext" ); +@@ -215,6 +218,7 @@ static AtkObject* jaw_object_get_parent( + "getAccessibleParent", + "()Ljavax/accessibility/AccessibleContext;"); + jobject jparent = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + if (jparent != NULL ) + { + jclass classAccessible = (*jniEnv)->FindClass(jniEnv, +@@ -235,8 +239,11 @@ static void + jaw_object_set_parent(AtkObject *atk_obj, AtkObject *parent) + { + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return; ++ } + + jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv, + "javax/accessibility/AccessibleContext" ); +@@ -245,6 +252,7 @@ jaw_object_set_parent(AtkObject *atk_obj + "setAccessibleParent", + "(Ljavax/accessibility/AccessibleContext;)"); + jobject jparent = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + if (jparent != NULL ) + { + jclass classAccessible = (*jniEnv)->FindClass(jniEnv, +@@ -264,8 +272,11 @@ static const gchar* + jaw_object_get_name (AtkObject *atk_obj) + { + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return NULL; ++ } + + atk_obj->name = (gchar *)ATK_OBJECT_CLASS (parent_class)->get_name (atk_obj); + +@@ -290,6 +301,7 @@ jaw_object_get_name (AtkObject *atk_obj) + "getAccessibleName", + "()Ljava/lang/String;"); + jstring jstr = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + + if (atk_obj->name != NULL) + { +@@ -312,8 +324,11 @@ jaw_object_get_name (AtkObject *atk_obj) + static void jaw_object_set_name (AtkObject *atk_obj, const gchar *name) + { + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return; ++ } + + atk_obj->name = (gchar *)ATK_OBJECT_CLASS (parent_class)->get_name (atk_obj); + +@@ -324,6 +339,7 @@ static void jaw_object_set_name (AtkObje + "setAccessibleName", + "(Ljava/lang/String;)"); + jstring jstr = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + + if (atk_obj->name != NULL) + { +@@ -349,8 +365,11 @@ static const gchar* + jaw_object_get_description (AtkObject *atk_obj) + { + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return NULL; ++ } + + jclass classAccessibleContext = (*jniEnv)->FindClass( jniEnv, + "javax/accessibility/AccessibleContext" ); +@@ -359,6 +378,7 @@ jaw_object_get_description (AtkObject *a + "getAccessibleDescription", + "()Ljava/lang/String;"); + jstring jstr = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + + if (atk_obj->description != NULL) + { +@@ -381,8 +401,11 @@ jaw_object_get_description (AtkObject *a + static void jaw_object_set_description (AtkObject *atk_obj, const gchar *description) + { + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return; ++ } + + jclass classAccessibleContext = (*jniEnv)->FindClass( jniEnv, + "javax/accessibility/AccessibleContext" ); +@@ -391,6 +414,7 @@ static void jaw_object_set_description ( + "setAccessibleDescription", + "(Ljava/lang/String;)"); + jstring jstr = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + + if (description != NULL) + { +@@ -417,8 +441,11 @@ static gint + jaw_object_get_n_children (AtkObject *atk_obj) + { + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return 0; ++ } + + jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv, + "javax/accessibility/AccessibleContext" ); +@@ -427,6 +454,7 @@ jaw_object_get_n_children (AtkObject *at + "getAccessibleChildrenCount", + "()I"); + jint count = (*jniEnv)->CallIntMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + + return (gint)count; + } +@@ -440,8 +468,11 @@ jaw_object_get_index_in_parent (AtkObjec + } + + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return 0; ++ } + + jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv, + "javax/accessibility/AccessibleContext" ); +@@ -450,6 +481,7 @@ jaw_object_get_index_in_parent (AtkObjec + "getAccessibleIndexInParent", + "()I"); + jint index = (*jniEnv)->CallIntMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + + return (gint)index; + } +@@ -458,7 +490,13 @@ static AtkRole + jaw_object_get_role (AtkObject *atk_obj) + { + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- atk_obj->role = jaw_util_get_atk_role_from_jobj(jaw_obj->acc_context); ++ JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return 0; ++ } ++ atk_obj->role = jaw_util_get_atk_role_from_jobj(ac); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + return atk_obj->role; + } + +@@ -477,8 +515,11 @@ jaw_object_ref_state_set (AtkObject *atk + AtkStateSet* state_set = jaw_obj->state_set; + atk_state_set_clear_states( state_set ); + +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return NULL; ++ } + jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv, + "javax/accessibility/AccessibleContext" ); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -486,6 +527,7 @@ jaw_object_ref_state_set (AtkObject *atk + "getAccessibleStateSet", + "()Ljavax/accessibility/AccessibleStateSet;" ); + jobject jstate_set = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + if (jstate_set == NULL) + return NULL; + +@@ -520,8 +562,11 @@ jaw_object_ref_state_set (AtkObject *atk + static const gchar *jaw_object_get_object_locale (AtkObject *atk_obj) + { + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return NULL; ++ } + + jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv, + "javax/accessibility/AccessibleContext" ); +@@ -530,6 +575,7 @@ static const gchar *jaw_object_get_objec + "getLocale", + "()Ljavax/accessibility/AccessibleContext;"); + jobject locale = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + JawImpl *target_obj = jaw_impl_get_instance(jniEnv, locale); + if(target_obj == NULL) + return NULL; +@@ -547,8 +593,11 @@ jaw_object_ref_relation_set (AtkObject * + return NULL; + + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return NULL; ++ } + + jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv, + "javax/accessibility/AccessibleContext" ); +@@ -557,6 +606,7 @@ jaw_object_ref_relation_set (AtkObject * + "getAccessibleRelationSet", + "()Ljavax/accessibility/AccessibleRelationSet;" ); + jobject jrel_set = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + + jclass classAccessibleRelationSet = (*jniEnv)->FindClass( jniEnv, + "javax/accessibility/AccessibleRelationSet"); +@@ -620,8 +670,11 @@ static AtkObject* + jaw_object_ref_child(AtkObject *atk_obj, gint i) + { + JawObject *jaw_obj = JAW_OBJECT(atk_obj); +- jobject ac = jaw_obj->acc_context; + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context); ++ if (!ac) { ++ return NULL; ++ } + + jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv, + "javax/accessibility/AccessibleContext" ); +@@ -630,6 +683,7 @@ jaw_object_ref_child(AtkObject *atk_obj, + "getAccessibleChild", + "(I)Ljavax/accessibility/Accessible;" ); + jobject jchild = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid, i ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, ac); + if (jchild == NULL) + { + return NULL; +--- a/jni/src/jawaction.c ++++ b/jni/src/jawaction.c +@@ -70,7 +70,7 @@ jaw_action_data_init (jobject ac) + "", + "(Ljavax/accessibility/AccessibleContext;)V"); + jobject jatk_action = (*jniEnv)->NewObject(jniEnv, classAction, jmid, ac); +- data->atk_action = (*jniEnv)->NewGlobalRef(jniEnv, jatk_action); ++ data->atk_action = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_action); + + return data; + } +@@ -115,7 +115,7 @@ jaw_action_data_finalize (gpointer p) + data->action_keybinding = NULL; + } + +- (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_action); ++ (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_action); + data->atk_action = NULL; + } + } +@@ -125,9 +125,12 @@ jaw_action_do_action (AtkAction *action, + { + JawObject *jaw_obj = JAW_OBJECT(action); + ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION); +- jobject atk_action = data->atk_action; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_action = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_action); ++ if (!atk_action) { ++ return FALSE; ++ } ++ + jclass classAtkAction = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkAction"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -138,6 +141,7 @@ jaw_action_do_action (AtkAction *action, + atk_action, + jmid, + (jint)i); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_action); + + if (jresult == JNI_TRUE) + return TRUE; +@@ -150,16 +154,21 @@ jaw_action_get_n_actions (AtkAction *act + { + JawObject *jaw_obj = JAW_OBJECT(action); + ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION); +- jobject atk_action = data->atk_action; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_action = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_action); ++ if (!atk_action) { ++ return 0; ++ } ++ + jclass classAtkAction = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkAction"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, + classAtkAction, + "get_n_actions", "()I"); + +- return (gint)(*jniEnv)->CallIntMethod(jniEnv, atk_action, jmid); ++ gint ret = (gint)(*jniEnv)->CallIntMethod(jniEnv, atk_action, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_action); ++ return ret; + } + + static const gchar* +@@ -167,9 +176,12 @@ jaw_action_get_description (AtkAction *a + { + JawObject *jaw_obj = JAW_OBJECT(action); + ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION); +- jobject atk_action = data->atk_action; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_action = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_action); ++ if (!atk_action) { ++ return NULL; ++ } ++ + jclass classAtkAction = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkAction"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -180,6 +192,7 @@ jaw_action_get_description (AtkAction *a + atk_action, + jmid, + (jint)i); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_action); + + if (data->action_description != NULL) + { +@@ -202,9 +215,12 @@ jaw_action_set_description (AtkAction *a + { + JawObject *jaw_obj = JAW_OBJECT(action); + ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION); +- jobject atk_action = data->atk_action; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_action = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_action); ++ if (!atk_action) { ++ return FALSE; ++ } ++ + jclass classAtkAction = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkAction"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -216,6 +232,7 @@ jaw_action_set_description (AtkAction *a + jmid, + (jint)i, + (jstring)description); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_action); + + if (jisset == JNI_TRUE) + { +@@ -230,9 +247,12 @@ jaw_action_get_name (AtkAction *action, + { + JawObject *jaw_obj = JAW_OBJECT(action); + ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION); +- jobject atk_action = data->atk_action; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_action = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_action); ++ if (!atk_action) { ++ return NULL; ++ } ++ + jclass classAtkAction = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkAction"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -240,6 +260,7 @@ jaw_action_get_name (AtkAction *action, + "get_name", + "(I)Ljava/lang/String;"); + jstring jstr = (*jniEnv)->CallObjectMethod(jniEnv, atk_action, jmid, (jint)i); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_action); + + if (data->action_name != NULL) + { +@@ -262,15 +283,19 @@ jaw_action_get_localized_name (AtkAction + { + JawObject *jaw_obj = JAW_OBJECT(action); + ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION); +- jobject atk_action = data->atk_action; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_action = (*env)->NewGlobalRef(env, data->atk_action); ++ if (!atk_action) { ++ return NULL; ++ } ++ + jclass classAtkAction = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkAction"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkAction, + "getLocalizedName", + "(I)Ljava/lang/String;"); + jstring jstr = (*env)->CallObjectMethod(env, atk_action, jmid, (jint)i); ++ (*env)->DeleteGlobalRef(env, atk_action); + if (data->action_name != NULL) + { + (*env)->ReleaseStringUTFChars(env, data->jstrLocalizedName, data->action_name); +@@ -289,9 +314,12 @@ jaw_action_get_keybinding (AtkAction *ac + return NULL; + + ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION); +- jobject atk_action = data->atk_action; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_action = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_action); ++ if (!atk_action) { ++ return NULL; ++ } ++ + jclass classAtkAction = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkAction"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -299,6 +327,7 @@ jaw_action_get_keybinding (AtkAction *ac + "get_keybinding", + "(I)Ljava/lang/String;"); + jstring jstr = (*jniEnv)->CallObjectMethod(jniEnv, atk_action, jmid, (jint)i); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_action); + + if (data->action_keybinding != NULL) + { +--- a/jni/src/jawcomponent.c ++++ b/jni/src/jawcomponent.c +@@ -86,7 +86,7 @@ jaw_component_data_init (jobject ac) + "(Ljavax/accessibility/AccessibleContext;)V"); + + jobject jatk_component = (*jniEnv)->NewObject(jniEnv, classComponent, jmid, ac); +- data->atk_component = (*jniEnv)->NewGlobalRef(jniEnv, jatk_component); ++ data->atk_component = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_component); + + return data; + } +@@ -99,7 +99,7 @@ jaw_component_data_finalize (gpointer p) + + if (data && data->atk_component) + { +- (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_component); ++ (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_component); + data->atk_component = NULL; + } + } +@@ -131,9 +131,12 @@ jaw_component_contains (AtkComponent *co + { + JawObject *jaw_obj = JAW_OBJECT(component); + ComponentData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_COMPONENT); +- jobject atk_component = data->atk_component; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_component = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_component); ++ if (!atk_component) { ++ return FALSE; ++ } ++ + jclass classAtkComponent = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkComponent"); + +@@ -148,6 +151,7 @@ jaw_component_contains (AtkComponent *co + (jint)x, + (jint)y, + (jint)coord_type); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component); + + if (jcontains == JNI_TRUE) + { +@@ -162,9 +166,12 @@ jaw_component_ref_accessible_at_point (A + { + JawObject *jaw_obj = JAW_OBJECT(component); + ComponentData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_COMPONENT); +- jobject atk_component = data->atk_component; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_component = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_component); ++ if (!atk_component) { ++ return NULL; ++ } ++ + jclass classAtkComponent = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkComponent"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -177,6 +184,7 @@ jaw_component_ref_accessible_at_point (A + (jint)x, + (jint)y, + (jint)coord_type); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component); + + JawImpl* jaw_impl = jaw_impl_get_instance( jniEnv, child_ac ); + +@@ -202,9 +210,12 @@ jaw_component_get_extents (AtkComponent + JawObject *jaw_obj = JAW_OBJECT(component); + ComponentData *data = jaw_object_get_interface_data(jaw_obj, + INTERFACE_COMPONENT); +- jobject atk_component = data->atk_component; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_component = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_component); ++ if (!atk_component) { ++ return; ++ } ++ + jclass classAtkComponent = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkComponent"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -213,6 +224,7 @@ jaw_component_get_extents (AtkComponent + "()Ljava/awt/Rectangle;"); + + jobject jrectangle = (*jniEnv)->CallObjectMethod(jniEnv, atk_component, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component); + + if (jrectangle == NULL) + { +@@ -245,9 +257,12 @@ jaw_component_set_extents (AtkComponent + + JawObject *jaw_obj = JAW_OBJECT(component); + ComponentData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_COMPONENT); +- jobject atk_component = data->atk_component; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_component = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_component); ++ if (!atk_component) { ++ return FALSE; ++ } ++ + jclass classAtkComponent = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkComponent"); + +@@ -271,6 +286,7 @@ jaw_component_set_extents (AtkComponent + height = 0; + x = 0; + y = 0; ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component); + return FALSE; + } + +@@ -293,6 +309,7 @@ jaw_component_set_extents (AtkComponent + atk_component, + "height", + "I"); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component); + + jint jwidth = (*jniEnv)->GetIntField(jniEnv, classRectangle, jfidWidth); + jint jheight = (*jniEnv)->GetIntField(jniEnv, classRectangle, jfidHeight); +@@ -312,9 +329,12 @@ jaw_component_grab_focus (AtkComponent * + { + JawObject *jaw_obj = JAW_OBJECT(component); + ComponentData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_COMPONENT); +- jobject atk_component = data->atk_component; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_component = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_component); ++ if (!atk_component) { ++ return FALSE; ++ } ++ + jclass classAtkComponent = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkComponent"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -322,6 +342,7 @@ jaw_component_grab_focus (AtkComponent * + "grab_focus", + "()Z"); + jboolean jresult = (*jniEnv)->CallBooleanMethod(jniEnv, atk_component, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component); + + if (jresult == JNI_TRUE) + { +@@ -337,9 +358,12 @@ jaw_component_get_layer (AtkComponent *c + JawObject *jaw_obj = JAW_OBJECT(component); + ComponentData *data = jaw_object_get_interface_data(jaw_obj, + INTERFACE_COMPONENT); +- jobject atk_component = data->atk_component; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_component = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_component); ++ if (!atk_component) { ++ return 0; ++ } ++ + jclass classAtkComponent = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkComponent"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -348,6 +372,7 @@ jaw_component_get_layer (AtkComponent *c + "()I"); + + jint jlayer = (*jniEnv)->CallIntMethod(jniEnv, atk_component, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component); + + return (AtkLayer)jlayer; + } +--- a/jni/src/jaweditabletext.c ++++ b/jni/src/jaweditabletext.c +@@ -82,7 +82,7 @@ jaw_editable_text_data_init (jobject ac) + classEditableText, + jmid, + ac); +- data->atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, ++ data->atk_editable_text = (*jniEnv)->NewWeakGlobalRef(jniEnv, + jatk_editable_text); + + return data; +@@ -96,7 +96,7 @@ jaw_editable_text_data_finalize (gpointe + + if (data && data->atk_editable_text) + { +- (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_editable_text); ++ (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_editable_text); + data->atk_editable_text = NULL; + } + } +@@ -107,9 +107,12 @@ jaw_editable_text_set_text_contents (Atk + { + JawObject *jaw_obj = JAW_OBJECT(text); + EditableTextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_EDITABLE_TEXT); +- jobject atk_editable_text = data->atk_editable_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_editable_text); ++ if (!atk_editable_text) { ++ return; ++ } ++ + jclass classAtkEditableText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkEditableText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -119,6 +122,7 @@ jaw_editable_text_set_text_contents (Atk + + jstring jstr = (*jniEnv)->NewStringUTF(jniEnv, string); + (*jniEnv)->CallVoidMethod(jniEnv, atk_editable_text, jmid, jstr); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_editable_text); + } + + void +@@ -129,9 +133,12 @@ jaw_editable_text_insert_text (AtkEditab + { + JawObject *jaw_obj = JAW_OBJECT(text); + EditableTextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_EDITABLE_TEXT); +- jobject atk_editable_text = data->atk_editable_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_editable_text); ++ if (!atk_editable_text) { ++ return; ++ } ++ + jclass classAtkEditableText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkEditableText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -144,6 +151,7 @@ jaw_editable_text_insert_text (AtkEditab + atk_editable_text, + jmid, jstr, + (jint)*position); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_editable_text); + *position = *position + length; + atk_text_set_caret_offset(ATK_TEXT(jaw_obj), *position); + } +@@ -156,9 +164,12 @@ jaw_editable_text_copy_text (AtkEditable + JawObject *jaw_obj = JAW_OBJECT(text); + EditableTextData *data = jaw_object_get_interface_data(jaw_obj, + INTERFACE_EDITABLE_TEXT); +- jobject atk_editable_text = data->atk_editable_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_editable_text); ++ if (!atk_editable_text) { ++ return; ++ } ++ + jclass classAtkEditableText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkEditableText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -170,6 +181,7 @@ jaw_editable_text_copy_text (AtkEditable + jmid, + (jint)start_pos, + (jint)end_pos); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_editable_text); + } + + void +@@ -178,9 +190,12 @@ jaw_editable_text_cut_text (AtkEditableT + { + JawObject *jaw_obj = JAW_OBJECT(text); + EditableTextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_EDITABLE_TEXT); +- jobject atk_editable_text = data->atk_editable_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_editable_text); ++ if (!atk_editable_text) { ++ return; ++ } ++ + jclass classAtkEditableText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkEditableText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -192,6 +207,7 @@ jaw_editable_text_cut_text (AtkEditableT + jmid, + (jint)start_pos, + (jint)end_pos); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_editable_text); + } + + void +@@ -202,9 +218,12 @@ jaw_editable_text_delete_text (AtkEditab + JawObject *jaw_obj = JAW_OBJECT(text); + EditableTextData *data = jaw_object_get_interface_data(jaw_obj, + INTERFACE_EDITABLE_TEXT); +- jobject atk_editable_text = data->atk_editable_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_editable_text); ++ if (!atk_editable_text) { ++ return; ++ } ++ + jclass classAtkEditableText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkEditableText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -216,6 +235,7 @@ jaw_editable_text_delete_text (AtkEditab + jmid, + (jint)start_pos, + (jint)end_pos); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_editable_text); + } + + void +@@ -225,9 +245,12 @@ jaw_editable_text_paste_text (AtkEditabl + JawObject *jaw_obj = JAW_OBJECT(text); + EditableTextData *data = jaw_object_get_interface_data(jaw_obj, + INTERFACE_EDITABLE_TEXT); +- jobject atk_editable_text = data->atk_editable_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_editable_text); ++ if (!atk_editable_text) { ++ return; ++ } ++ + jclass classAtkEditableText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkEditableText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -238,6 +261,7 @@ jaw_editable_text_paste_text (AtkEditabl + atk_editable_text, + jmid, + (jint)position); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_editable_text); + } + + static gboolean +@@ -248,8 +272,11 @@ jaw_editable_text_set_run_attributes(Atk + { + JawObject *jaw_obj = JAW_OBJECT(text); + EditableTextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_EDITABLE_TEXT); +- jobject atk_editable_text = data->atk_editable_text; + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_editable_text = (*env)->NewGlobalRef(env, data->atk_editable_text); ++ if (!atk_editable_text) { ++ return FALSE; ++ } + jclass classAtkEditableText = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkEditableText"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkEditableText, +@@ -261,6 +288,7 @@ jaw_editable_text_set_run_attributes(Atk + (jobject)attrib_set, + (jint)start_offset, + (jint)end_offset); ++ (*env)->DeleteGlobalRef(env, atk_editable_text); + if (jresult == JNI_TRUE) + return TRUE; + +--- a/jni/src/jawhyperlink.c ++++ b/jni/src/jawhyperlink.c +@@ -43,7 +43,7 @@ jaw_hyperlink_new (jobject jhyperlink) + { + JawHyperlink* jaw_hyperlink = g_object_new(JAW_TYPE_HYPERLINK, NULL); + JNIEnv *jniEnv = jaw_util_get_jni_env(); +- jaw_hyperlink->jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jhyperlink); ++ jaw_hyperlink->jhyperlink = (*jniEnv)->NewWeakGlobalRef(jniEnv, jhyperlink); + + return jaw_hyperlink; + } +@@ -82,7 +82,7 @@ jaw_hyperlink_finalize(GObject *gobject) + JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(gobject); + + JNIEnv *jniEnv = jaw_util_get_jni_env(); +- (*jniEnv)->DeleteGlobalRef(jniEnv, jaw_hyperlink->jhyperlink); ++ (*jniEnv)->DeleteWeakGlobalRef(jniEnv, jaw_hyperlink->jhyperlink); + jaw_hyperlink->jhyperlink = NULL; + + /* Chain up to parent's finalize */ +@@ -94,12 +94,16 @@ jaw_hyperlink_get_uri (AtkHyperlink *atk + gint i) + { + JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(atk_hyperlink); +- jobject jhyperlink = jaw_hyperlink->jhyperlink; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jaw_hyperlink->jhyperlink); ++ if (!jhyperlink) { ++ return NULL; ++ } ++ + jclass classAtkHyperlink = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHyperlink"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHyperlink, "get_uri", "(I)Ljava/lang/String;"); + jstring jstr = (*jniEnv)->CallObjectMethod(jniEnv, jhyperlink, jmid, (jint)i); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, jhyperlink); + + if (jaw_hyperlink->uri != NULL) { + (*jniEnv)->ReleaseStringUTFChars(jniEnv, jaw_hyperlink->jstrUri, jaw_hyperlink->uri); +@@ -117,12 +121,16 @@ jaw_hyperlink_get_object (AtkHyperlink * + gint i) + { + JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(atk_hyperlink); +- jobject jhyperlink = jaw_hyperlink->jhyperlink; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jaw_hyperlink->jhyperlink); ++ if (!jhyperlink) { ++ return NULL; ++ } ++ + jclass classAtkHyperlink = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHyperlink"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHyperlink, "get_object", "(I)Ljava/lang/String;"); + jobject jobj = (*jniEnv)->CallObjectMethod(jniEnv, jhyperlink, jmid, (jint)i); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, jhyperlink); + if (jobj == NULL) { + return NULL; + } +@@ -140,12 +148,16 @@ static gint + jaw_hyperlink_get_end_index (AtkHyperlink *atk_hyperlink) + { + JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(atk_hyperlink); +- jobject jhyperlink = jaw_hyperlink->jhyperlink; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jaw_hyperlink->jhyperlink); ++ if (!jhyperlink) { ++ return 0; ++ } ++ + jclass classAtkHyperlink = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHyperlink"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHyperlink, "get_end_index", "()I"); + jint jindex = (*jniEnv)->CallIntMethod(jniEnv, jhyperlink, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, jhyperlink); + + return jindex; + } +@@ -153,12 +165,16 @@ jaw_hyperlink_get_end_index (AtkHyperlin + static gint jaw_hyperlink_get_start_index (AtkHyperlink *atk_hyperlink) + { + JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(atk_hyperlink); +- jobject jhyperlink = jaw_hyperlink->jhyperlink; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jaw_hyperlink->jhyperlink); ++ if (!jhyperlink) { ++ return 0; ++ } ++ + jclass classAtkHyperlink = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHyperlink"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHyperlink, "get_start_index", "()I"); + jint jindex = (*jniEnv)->CallIntMethod(jniEnv, jhyperlink, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, jhyperlink); + + return jindex; + } +@@ -166,12 +182,16 @@ static gint jaw_hyperlink_get_start_inde + static gboolean jaw_hyperlink_is_valid (AtkHyperlink *atk_hyperlink) + { + JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(atk_hyperlink); +- jobject jhyperlink = jaw_hyperlink->jhyperlink; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jaw_hyperlink->jhyperlink); ++ if (!jhyperlink) { ++ return FALSE; ++ } ++ + jclass classAtkHyperlink = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHyperlink"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHyperlink, "is_valid", "()Z"); + jboolean jvalid = (*jniEnv)->CallBooleanMethod(jniEnv, jhyperlink, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, jhyperlink); + + return jvalid; + } +@@ -179,12 +199,16 @@ static gboolean jaw_hyperlink_is_valid ( + static gint jaw_hyperlink_get_n_anchors (AtkHyperlink *atk_hyperlink) + { + JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(atk_hyperlink); +- jobject jhyperlink = jaw_hyperlink->jhyperlink; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jaw_hyperlink->jhyperlink); ++ if (!jhyperlink) { ++ return 0; ++ } ++ + jclass classAtkHyperlink = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHyperlink"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHyperlink, "get_n_anchors", "()I"); + jint janchors = (*jniEnv)->CallIntMethod(jniEnv, jhyperlink, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, jhyperlink); + + return janchors; + } +--- a/jni/src/jawhypertext.c ++++ b/jni/src/jawhypertext.c +@@ -63,7 +63,7 @@ jaw_hypertext_data_init (jobject ac) + jclass classHypertext = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHypertext"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classHypertext, "", "(Ljavax/accessibility/AccessibleContext;)V"); + jobject jatk_hypertext = (*jniEnv)->NewObject(jniEnv, classHypertext, jmid, ac); +- data->atk_hypertext = (*jniEnv)->NewGlobalRef(jniEnv, jatk_hypertext); ++ data->atk_hypertext = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_hypertext); + + data->link_table = g_hash_table_new_full(NULL, NULL, NULL, link_destroy_notify); + +@@ -79,7 +79,7 @@ jaw_hypertext_data_finalize (gpointer p) + if (data && data->atk_hypertext) { + g_hash_table_remove_all(data->link_table); + +- (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_hypertext); ++ (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_hypertext); + data->atk_hypertext = NULL; + } + } +@@ -89,12 +89,16 @@ jaw_hypertext_get_link (AtkHypertext *hy + { + JawObject *jaw_obj = JAW_OBJECT(hypertext); + HypertextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_HYPERTEXT); +- jobject atk_hypertext = data->atk_hypertext; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_hypertext = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_hypertext); ++ if (!atk_hypertext) { ++ return NULL; ++ } ++ + jclass classAtkHypertext = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHypertext"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHypertext, "get_link", "(I)Lorg/GNOME/Accessibility/AtkHyperlink;"); + jobject jhyperlink = (*jniEnv)->CallObjectMethod(jniEnv, atk_hypertext, jmid, (jint)link_index); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_hypertext); + + if (!jhyperlink) { + return NULL; +@@ -111,13 +115,18 @@ jaw_hypertext_get_n_links (AtkHypertext + { + JawObject *jaw_obj = JAW_OBJECT(hypertext); + HypertextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_HYPERTEXT); +- jobject atk_hypertext = data->atk_hypertext; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_hypertext = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_hypertext); ++ if (!atk_hypertext) { ++ return 0; ++ } ++ + jclass classAtkHypertext = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHypertext"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHypertext, "get_n_links", "()I"); + +- return (gint)(*jniEnv)->CallIntMethod(jniEnv, atk_hypertext, jmid); ++ gint ret = (gint)(*jniEnv)->CallIntMethod(jniEnv, atk_hypertext, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_hypertext); ++ return ret; + } + + static gint +@@ -125,12 +134,17 @@ jaw_hypertext_get_link_index (AtkHyperte + { + JawObject *jaw_obj = JAW_OBJECT(hypertext); + HypertextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_HYPERTEXT); +- jobject atk_hypertext = data->atk_hypertext; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_hypertext = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_hypertext); ++ if (!atk_hypertext) { ++ return 0; ++ } ++ + jclass classAtkHypertext = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHypertext"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHypertext, "get_link_index", "(I)I"); + +- return (gint)(*jniEnv)->CallIntMethod(jniEnv, atk_hypertext, jmid, (jint)char_index); ++ gint ret = (gint)(*jniEnv)->CallIntMethod(jniEnv, atk_hypertext, jmid, (jint)char_index); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_hypertext); ++ return ret; + } + +--- a/jni/src/jawimage.c ++++ b/jni/src/jawimage.c +@@ -59,7 +59,7 @@ jaw_image_data_init (jobject ac) + jclass classImage = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkImage"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classImage, "", "(Ljavax/accessibility/AccessibleContext;)V"); + jobject jatk_image = (*jniEnv)->NewObject(jniEnv, classImage, jmid, ac); +- data->atk_image = (*jniEnv)->NewGlobalRef(jniEnv, jatk_image); ++ data->atk_image = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_image); + + return data; + } +@@ -79,7 +79,7 @@ jaw_image_data_finalize (gpointer p) + } + + +- (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_image); ++ (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_image); + data->atk_image = NULL; + } + } +@@ -90,12 +90,16 @@ jaw_image_get_image_position (AtkImage * + { + JawObject *jaw_obj = JAW_OBJECT(image); + ImageData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_IMAGE); +- jobject atk_image = data->atk_image; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_image = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_image); ++ if (!atk_image) { ++ return; ++ } ++ + jclass classAtkImage = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkImage"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkImage, "get_image_position", "(I)Ljava/awt/Point;"); + jobject jpoint = (*jniEnv)->CallObjectMethod(jniEnv, atk_image, jmid, (jint)coord_type); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_image); + + if (jpoint == NULL) { + (*x) = 0; +@@ -118,12 +122,16 @@ jaw_image_get_image_description (AtkImag + { + JawObject *jaw_obj = JAW_OBJECT(image); + ImageData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_IMAGE); +- jobject atk_image = data->atk_image; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_image = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_image); ++ if (!atk_image) { ++ return NULL; ++ } ++ + jclass classAtkImage = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkImage"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkImage, "get_image_description", "()Ljava/lang/String;"); + jstring jstr = (*jniEnv)->CallObjectMethod(jniEnv, atk_image, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_image); + + if (data->image_description != NULL) { + (*jniEnv)->ReleaseStringUTFChars(jniEnv, data->jstrImageDescription, data->image_description); +@@ -141,12 +149,16 @@ jaw_image_get_image_size (AtkImage *imag + { + JawObject *jaw_obj = JAW_OBJECT(image); + ImageData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_IMAGE); +- jobject atk_image = data->atk_image; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_image = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_image); ++ if (!atk_image) { ++ return; ++ } ++ + jclass classAtkImage = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkImage"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkImage, "get_image_size", "()Ljava/awt/Dimension;"); + jobject jdimension = (*jniEnv)->CallObjectMethod(jniEnv, atk_image, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_image); + + if (jdimension == NULL) { + (*width) = 0; +--- a/jni/src/jawselection.c ++++ b/jni/src/jawselection.c +@@ -63,7 +63,7 @@ jaw_selection_data_init (jobject ac) + jclass classSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classSelection, "", "(Ljavax/accessibility/AccessibleContext;)V"); + jobject jatk_selection = (*jniEnv)->NewObject(jniEnv, classSelection, jmid, ac); +- data->atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, jatk_selection); ++ data->atk_selection = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_selection); + + return data; + } +@@ -75,7 +75,7 @@ jaw_selection_data_finalize (gpointer p) + JNIEnv *jniEnv = jaw_util_get_jni_env(); + + if (data && data->atk_selection) { +- (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_selection); ++ (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_selection); + data->atk_selection = NULL; + } + } +@@ -85,12 +85,16 @@ jaw_selection_add_selection (AtkSelectio + { + JawObject *jaw_obj = JAW_OBJECT(selection); + SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION); +- jobject atk_selection = data->atk_selection; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection); ++ if (!atk_selection) { ++ return FALSE; ++ } ++ + jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "add_selection", "(I)Z"); + jboolean jbool = (*jniEnv)->CallBooleanMethod(jniEnv, atk_selection, jmid, (jint)i); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection); + + if (jbool == JNI_TRUE) { + return TRUE; +@@ -104,12 +108,16 @@ jaw_selection_clear_selection (AtkSelect + { + JawObject *jaw_obj = JAW_OBJECT(selection); + SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION); +- jobject atk_selection = data->atk_selection; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection); ++ if (!atk_selection) { ++ return FALSE; ++ } ++ + jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "clear_selection", "()Z"); + jboolean jbool = (*jniEnv)->CallBooleanMethod(jniEnv, atk_selection, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection); + + if (jbool == JNI_TRUE) { + return TRUE; +@@ -123,12 +131,16 @@ jaw_selection_ref_selection (AtkSelectio + { + JawObject *jaw_obj = JAW_OBJECT(selection); + SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION); +- jobject atk_selection = data->atk_selection; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection); ++ if (!atk_selection) { ++ return NULL; ++ } ++ + jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "ref_selection", "(I)Ljavax/accessibility/Accessible;"); + jobject jchild = (*jniEnv)->CallObjectMethod(jniEnv, atk_selection, jmid, (jint)i); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection); + + if (!jchild) { + return NULL; +@@ -149,12 +161,16 @@ jaw_selection_get_selection_count (AtkSe + { + JawObject *jaw_obj = JAW_OBJECT(selection); + SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION); +- jobject atk_selection = data->atk_selection; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection); ++ if (!atk_selection) { ++ return 0; ++ } ++ + jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "get_selection_count", "()I"); + jint jcount = (*jniEnv)->CallIntMethod(jniEnv, atk_selection, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection); + + return (gint)jcount; + } +@@ -164,12 +180,16 @@ jaw_selection_is_child_selected (AtkSele + { + JawObject *jaw_obj = JAW_OBJECT(selection); + SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION); +- jobject atk_selection = data->atk_selection; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection); ++ if (!atk_selection) { ++ return FALSE; ++ } ++ + jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "is_child_selected", "(I)Z"); + jboolean jbool = (*jniEnv)->CallBooleanMethod(jniEnv, atk_selection, jmid, (jint)i); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection); + + if (jbool == JNI_TRUE) { + return TRUE; +@@ -183,12 +203,16 @@ jaw_selection_remove_selection (AtkSelec + { + JawObject *jaw_obj = JAW_OBJECT(selection); + SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION); +- jobject atk_selection = data->atk_selection; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection); ++ if (!atk_selection) { ++ return FALSE; ++ } ++ + jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "remove_selection", "(I)Z"); + jboolean jbool = (*jniEnv)->CallBooleanMethod(jniEnv, atk_selection, jmid, (jint)i); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection); + + if (jbool == JNI_TRUE) { + return TRUE; +@@ -202,12 +226,16 @@ jaw_selection_select_all_selection (AtkS + { + JawObject *jaw_obj = JAW_OBJECT(selection); + SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION); +- jobject atk_selection = data->atk_selection; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection); ++ if (!atk_selection) { ++ return FALSE; ++ } ++ + jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "select_all_selection", "()Z"); + jboolean jbool = (*jniEnv)->CallBooleanMethod(jniEnv, atk_selection, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection); + + if (jbool == JNI_TRUE) { + return TRUE; +--- a/jni/src/jawtable.c ++++ b/jni/src/jawtable.c +@@ -108,7 +108,7 @@ jaw_table_data_init (jobject ac) + "(Ljavax/accessibility/AccessibleContext;)V"); + + jobject jatk_table = (*env)->NewObject(env, classTable, jmid, ac); +- data->atk_table = (*env)->NewGlobalRef(env, jatk_table); ++ data->atk_table = (*env)->NewWeakGlobalRef(env, jatk_table); + + return data; + } +@@ -129,7 +129,7 @@ jaw_table_data_finalize (gpointer p) + data->description = NULL; + } + +- (*env)->DeleteGlobalRef(env, data->atk_table); ++ (*env)->DeleteWeakGlobalRef(env, data->atk_table); + data->atk_table = NULL; + } + } +@@ -139,15 +139,19 @@ jaw_table_ref_at (AtkTable *table, gint + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return NULL; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkTable, + "ref_at", + "(II)Ljavax/accessibility/AccessibleContext;"); + jobject jac = (*env)->CallObjectMethod(env, atk_table, jmid, (jint)row, (jint)column); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (!jac) + return NULL; +@@ -165,12 +169,16 @@ jaw_table_get_column_at_index (AtkTable + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return 0; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_column_at_index", "(I)I"); + jint jcolumn = (*env)->CallIntMethod(env, atk_table, jmid, (jint)index); ++ (*env)->DeleteGlobalRef(env, atk_table); + + return (gint)jcolumn; + } +@@ -180,12 +188,16 @@ jaw_table_get_row_at_index (AtkTable *ta + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return 0; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_row_at_index", "(I)I"); + jint jrow = (*env)->CallIntMethod(env, atk_table, jmid, (jint)index); ++ (*env)->DeleteGlobalRef(env, atk_table); + + return (gint)jrow; + } +@@ -195,12 +207,16 @@ jaw_table_get_n_columns (AtkTable *table + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return 0; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_n_columns", "()I"); + jint jcolumns = (*env)->CallIntMethod(env, atk_table, jmid); ++ (*env)->DeleteGlobalRef(env, atk_table); + + return (gint)jcolumns; + } +@@ -210,12 +226,16 @@ jaw_table_get_n_rows (AtkTable *table) + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return 0; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_n_rows", "()I"); + jint jrows = (*env)->CallIntMethod(env, atk_table, jmid); ++ (*env)->DeleteGlobalRef(env, atk_table); + + return (gint)jrows; + } +@@ -225,12 +245,16 @@ jaw_table_get_column_extent_at (AtkTable + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return 0; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_column_extent_at", "(II)I"); + jint jextent = (*env)->CallIntMethod(env, atk_table, jmid, (jint)row, (jint)column); ++ (*env)->DeleteGlobalRef(env, atk_table); + + return (gint)jextent; + } +@@ -240,12 +264,16 @@ jaw_table_get_row_extent_at (AtkTable *t + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return 0; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_row_extent_at", "(II)I"); + jint jextent = (*env)->CallIntMethod(env, atk_table, jmid, (jint)row, (jint)column); ++ (*env)->DeleteGlobalRef(env, atk_table); + + return (gint)jextent; + } +@@ -255,9 +283,12 @@ jaw_table_get_caption (AtkTable *table) + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return NULL; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkTable, +@@ -265,6 +296,7 @@ jaw_table_get_caption (AtkTable *table) + "()Ljavax/accessibility/AccessibleContext;"); + + jobject jac = (*env)->CallObjectMethod(env, atk_table, jmid); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (!jac) + return NULL; +@@ -279,12 +311,16 @@ jaw_table_get_column_description (AtkTab + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return NULL; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_column_description", "(I)Ljava/lang/String;"); + jstring jstr = (*env)->CallObjectMethod(env, atk_table, jmid, (jint)column); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (data->description != NULL) + { +@@ -303,12 +339,16 @@ jaw_table_get_row_description (AtkTable + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return NULL; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_row_description", "(I)Ljava/lang/String;"); + jstring jstr = (*env)->CallObjectMethod(env, atk_table, jmid, (jint)row); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (data->description != NULL) + { +@@ -327,12 +367,16 @@ jaw_table_get_column_header (AtkTable *t + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return NULL; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_column_header", "(I)Ljavax/accessibility/AccessibleContext;"); + jobject jac = (*env)->CallObjectMethod(env, atk_table, jmid, (jint)column); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (!jac) + return NULL; +@@ -347,12 +391,16 @@ jaw_table_get_row_header (AtkTable *tabl + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return NULL; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_row_header", "(I)Ljavax/accessibility/AccessibleContext;"); + jobject jac = (*env)->CallObjectMethod(env, atk_table, jmid, (jint)row); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (!jac) + return NULL; +@@ -367,12 +415,16 @@ jaw_table_get_summary (AtkTable *table) + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return NULL; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_summary", "()Ljavax/accessibility/AccessibleContext;"); + jobject jac = (*env)->CallObjectMethod(env, atk_table, jmid); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (!jac) + return NULL; +@@ -387,12 +439,16 @@ jaw_table_get_selected_columns (AtkTable + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return 0; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_selected_columns", "()[I"); + jintArray jcolumnArray = (*env)->CallObjectMethod(env, atk_table, jmid); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (!jcolumnArray) + return 0; +@@ -416,12 +472,16 @@ jaw_table_get_selected_rows (AtkTable *t + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return 0; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_selected_rows", "()[I"); + jintArray jrowArray = (*env)->CallObjectMethod(env, atk_table, jmid); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (!jrowArray) + return 0; +@@ -445,12 +505,16 @@ jaw_table_is_column_selected (AtkTable * + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return FALSE; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "is_column_selected", "(I)Z"); + jboolean jselected = (*env)->CallBooleanMethod(env, atk_table, jmid, (jint)column); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (jselected == JNI_TRUE) + return TRUE; +@@ -463,12 +527,16 @@ jaw_table_is_row_selected (AtkTable *tab + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return FALSE; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "is_row_selected", "(I)Z"); + jboolean jselected = (*env)->CallBooleanMethod(env, atk_table, jmid, (jint)row); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (jselected == JNI_TRUE) + return TRUE; +@@ -481,12 +549,16 @@ jaw_table_is_selected (AtkTable *table, + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return FALSE; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "is_selected", "(II)Z"); + jboolean jselected = (*env)->CallBooleanMethod(env, atk_table, jmid, (jint)row, (jint)column); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (jselected == JNI_TRUE) + return TRUE; +@@ -499,12 +571,16 @@ jaw_table_add_row_selection(AtkTable *ta + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return FALSE; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "addRowSelection", "(I)Z"); + jboolean jselected = (*env)->CallBooleanMethod(env, atk_table, jmid, (jint)row); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (jselected == JNI_TRUE) + return TRUE; +@@ -517,12 +593,16 @@ jaw_table_add_column_selection(AtkTable + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return FALSE; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "addColumnSelection", "(I)Z"); + jboolean jselected = (*env)->CallBooleanMethod(env, atk_table, jmid, (jint)column); ++ (*env)->DeleteGlobalRef(env, atk_table); + + if (jselected == JNI_TRUE) + return TRUE; +@@ -535,9 +615,12 @@ jaw_table_set_row_description(AtkTable * + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkTable, +@@ -545,6 +628,7 @@ jaw_table_set_row_description(AtkTable * + "(ILjava/lang/String;)V"); + jstring jstr = (*env)->NewStringUTF(env, description); + (*env)->CallVoidMethod(env, atk_table, jmid, (jint)row, jstr); ++ (*env)->DeleteGlobalRef(env, atk_table); + } + + static void +@@ -552,9 +636,12 @@ jaw_table_set_column_description(AtkTabl + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkTable, +@@ -562,6 +649,7 @@ jaw_table_set_column_description(AtkTabl + "(ILjava/lang/String;)V"); + jstring jstr = (*env)->NewStringUTF(env, description); + (*env)->CallVoidMethod(env, atk_table, jmid, (jint)column, jstr); ++ (*env)->DeleteGlobalRef(env, atk_table); + } + + static void +@@ -569,15 +657,19 @@ jaw_table_set_row_header(AtkTable *table + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkTable, + "setRowHeader", + "(ILjavax/accessibility/AccessibleTable;)V"); + (*env)->CallVoidMethod(env, atk_table, jmid, (jint)row, (jobject)header); ++ (*env)->DeleteGlobalRef(env, atk_table); + } + + static void +@@ -585,15 +677,19 @@ jaw_table_set_column_header(AtkTable *ta + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkTable, + "setColumnHeader", + "(ILjavax/accessibility/AccessibleTable;)V"); + (*env)->CallVoidMethod(env, atk_table, jmid, (jint)column, (jobject)header); ++ (*env)->DeleteGlobalRef(env, atk_table); + } + + static void +@@ -601,15 +697,19 @@ jaw_table_set_caption(AtkTable *table, A + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkTable, + "setCaption", + "(Ljavax/accessibility/Accessible;)V"); + (*env)->CallVoidMethod(env, atk_table, jmid, (jobject)caption); ++ (*env)->DeleteGlobalRef(env, atk_table); + } + + static void +@@ -617,13 +717,17 @@ jaw_table_set_summary(AtkTable *table, A + { + JawObject *jaw_obj = JAW_OBJECT(table); + TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE); +- jobject atk_table = data->atk_table; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table); ++ if (!atk_table) { ++ return; ++ } ++ + jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkTable, + "setSummary", + "(Ljavax/accessibility/Accessible;)V"); + (*env)->CallVoidMethod(env, atk_table, jmid, (jobject)summary); ++ (*env)->DeleteGlobalRef(env, atk_table); + } +--- a/jni/src/jawtablecell.c ++++ b/jni/src/jawtablecell.c +@@ -61,7 +61,7 @@ jaw_table_cell_data_init (jobject ac) + jclass classTableCell = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkTableCell"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classTableCell, "", "(Ljavax/accessibility/AccessibleContext;)V"); + jobject jatk_table_cell = (*jniEnv)->NewObject(jniEnv, classTableCell, jmid, ac); +- data->atk_table_cell = (*jniEnv)->NewGlobalRef(jniEnv, jatk_table_cell); ++ data->atk_table_cell = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_table_cell); + + return data; + } +@@ -82,7 +82,7 @@ jaw_table_cell_data_finalize (gpointer p + data->description = NULL; + } + +- (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_table_cell); ++ (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_table_cell); + data->atk_table_cell = NULL; + } + } +@@ -92,9 +92,12 @@ jaw_table_cell_get_table(AtkTableCell *c + { + JawObject *jaw_obj = JAW_OBJECT(cell); + TableCellData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE_CELL); +- jobject jatk_table_cell = data->atk_table_cell; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject jatk_table_cell = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_table_cell); ++ if (!jatk_table_cell) { ++ return NULL; ++ } ++ + jclass classAtkTableCell = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkTableCell"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -102,6 +105,7 @@ jaw_table_cell_get_table(AtkTableCell *c + "getTable", + "()Ljavax/accessibility/AccessibleTable;"); + jobject jac = (*jniEnv)->CallObjectMethod(jniEnv, jatk_table_cell, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, jatk_table_cell); + + if (!jac) + return NULL; +@@ -116,9 +120,12 @@ jaw_table_cell_get_position(AtkTableCell + { + JawObject *jaw_obj = JAW_OBJECT(cell); + TableCellData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE_CELL); +- jobject jatk_table_cell = data->atk_table_cell; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject jatk_table_cell = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_table_cell); ++ if (!jatk_table_cell) { ++ return FALSE; ++ } ++ + jclass classAtkTableCell = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkTableCell"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -130,6 +137,7 @@ jaw_table_cell_get_position(AtkTableCell + jmid, + (jint)GPOINTER_TO_INT(row), + (jint)GPOINTER_TO_INT(column)); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, jatk_table_cell); + + if (jposition == JNI_TRUE) + return TRUE; +@@ -145,9 +153,12 @@ static gboolean jaw_table_cell_get_row_c + { + JawObject *jaw_obj = JAW_OBJECT(cell); + TableCellData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE_CELL); +- jobject jatk_table_cell = data->atk_table_cell; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject jatk_table_cell = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_table_cell); ++ if (!jatk_table_cell) { ++ return FALSE; ++ } ++ + jclass classAtkTableCell = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkTableCell"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -162,6 +173,7 @@ static gboolean jaw_table_cell_get_row_c + (jint)GPOINTER_TO_INT(row_span), + (jint)GPOINTER_TO_INT(column_span) + ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, jatk_table_cell); + if (jspan == JNI_TRUE) + return TRUE; + +@@ -173,16 +185,21 @@ jaw_table_cell_get_row_span(AtkTableCell + { + JawObject *jaw_obj = JAW_OBJECT(cell); + TableCellData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE_CELL); +- jobject jatk_table_cell = data->atk_table_cell; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject jatk_table_cell = (*env)->NewGlobalRef(env, data->atk_table_cell); ++ if (!jatk_table_cell) { ++ return 0; ++ } ++ + jclass classAtkTableCell = (*env)->FindClass(env, + "org/GNOME/Accessibility/AtkTableCell"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkTableCell, + "getRowSpan", + "()I;"); +- return (gint) (*env)->CallIntMethod(env, jatk_table_cell, jmid); ++ gint ret = (gint) (*env)->CallIntMethod(env, jatk_table_cell, jmid); ++ (*env)->DeleteGlobalRef(env, jatk_table_cell); ++ return ret; + } + + static gint +@@ -190,15 +207,20 @@ jaw_table_cell_get_column_span(AtkTableC + { + JawObject *jaw_obj = JAW_OBJECT(cell); + TableCellData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE_CELL); +- jobject jatk_table_cell = data->atk_table_cell; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject jatk_table_cell = (*env)->NewGlobalRef(env, data->atk_table_cell); ++ if (!jatk_table_cell) { ++ return 0; ++ } ++ + jclass classAtkTableCell = (*env)->FindClass(env, + "org/GNOME/Accessibility/AtkTableCell"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkTableCell, + "getColumnSpan", + "()I;"); +- return (gint) (*env)->CallIntMethod(env, jatk_table_cell, jmid); ++ gint ret = (gint) (*env)->CallIntMethod(env, jatk_table_cell, jmid); ++ (*env)->DeleteGlobalRef(env, jatk_table_cell); ++ return ret; + } + +--- a/jni/src/jawtext.c ++++ b/jni/src/jawtext.c +@@ -118,7 +118,7 @@ jaw_text_data_init (jobject ac) + "", + "(Ljavax/accessibility/AccessibleContext;)V"); + jobject jatk_text = (*jniEnv)->NewObject(jniEnv, classText, jmid, ac); +- data->atk_text = (*jniEnv)->NewGlobalRef(jniEnv, jatk_text); ++ data->atk_text = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_text); + + return data; + } +@@ -139,7 +139,7 @@ jaw_text_data_finalize (gpointer p) + data->text = NULL; + } + +- (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_text); ++ (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_text); + data->atk_text = NULL; + } + } +@@ -164,9 +164,12 @@ jaw_text_get_text (AtkText *text, gint s + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return NULL; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -179,6 +182,7 @@ jaw_text_get_text (AtkText *text, gint s + jmid, + (jint)start_offset, + (jint)end_offset ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + return jaw_text_get_gtext_from_jstr(jniEnv, data, jstr); + } +@@ -188,9 +192,12 @@ jaw_text_get_character_at_offset (AtkTex + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return 0; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -200,6 +207,7 @@ jaw_text_get_character_at_offset (AtkTex + atk_text, + jmid, + (jint)offset ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + return (gunichar)jcharacter; + } +@@ -212,9 +220,12 @@ jaw_text_get_text_at_offset (AtkText *te + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return NULL; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -226,6 +237,7 @@ jaw_text_get_text_at_offset (AtkText *te + jmid, + (jint)offset, + (jint)boundary_type ); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + if (jStrSeq == NULL) + { +@@ -262,9 +274,12 @@ jaw_text_get_caret_offset (AtkText *text + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return 0; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -272,6 +287,7 @@ jaw_text_get_caret_offset (AtkText *text + "get_caret_offset", + "()I"); + jint joffset = (*jniEnv)->CallIntMethod(jniEnv, atk_text, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + return (gint)joffset; + } +@@ -284,9 +300,12 @@ jaw_text_get_character_extents (AtkText + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -298,6 +317,7 @@ jaw_text_get_character_extents (AtkText + jmid, + (jint)offset, + (jint)coords); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + if (jrect == NULL) + { +@@ -312,9 +332,12 @@ jaw_text_get_character_count (AtkText *t + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return 0; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -322,6 +345,7 @@ jaw_text_get_character_count (AtkText *t + "get_character_count", + "()I"); + jint jcount = (*jniEnv)->CallIntMethod(jniEnv, atk_text, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + return (gint)jcount; + } +@@ -331,9 +355,12 @@ jaw_text_get_offset_at_point (AtkText *t + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return 0; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, + classAtkText, +@@ -345,6 +372,7 @@ jaw_text_get_offset_at_point (AtkText *t + (jint)x, + (jint)y, + (jint)coords); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + return (gint)joffset; + } +@@ -363,9 +391,12 @@ jaw_text_get_range_extents (AtkText *tex + + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -378,6 +409,7 @@ jaw_text_get_range_extents (AtkText *tex + (jint)start_offset, + (jint)end_offset, + (jint)coord_type); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + if (!jrect) + { +@@ -392,9 +424,12 @@ jaw_text_get_n_selections (AtkText *text + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return 0; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -402,6 +437,7 @@ jaw_text_get_n_selections (AtkText *text + "get_n_selections", + "()I"); + jint jselections = (*jniEnv)->CallIntMethod(jniEnv, atk_text, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + return (gint)jselections; + } +@@ -411,15 +447,19 @@ jaw_text_get_selection (AtkText *text, g + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return NULL; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, + classAtkText, + "get_selection", + "()Lorg/GNOME/Accessibility/AtkText$StringSequence;"); + jobject jStrSeq = (*jniEnv)->CallObjectMethod(jniEnv, atk_text, jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + if (jStrSeq == NULL) + { +@@ -453,9 +493,12 @@ jaw_text_add_selection (AtkText *text, g + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return FALSE; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, + classAtkText, +@@ -466,6 +509,7 @@ jaw_text_add_selection (AtkText *text, g + jmid, + (jint)start_offset, + (jint)end_offset); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + if (jresult == JNI_TRUE) + { +@@ -480,9 +524,12 @@ jaw_text_remove_selection (AtkText *text + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return FALSE; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -493,6 +540,7 @@ jaw_text_remove_selection (AtkText *text + atk_text, + jmid, + (jint)selection_num); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + if (jresult == JNI_TRUE) + { +@@ -507,9 +555,12 @@ jaw_text_set_selection (AtkText *text, g + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return FALSE; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkText, "set_selection", "(III)Z"); + jboolean jresult = (*jniEnv)->CallBooleanMethod(jniEnv, +@@ -518,6 +569,7 @@ jaw_text_set_selection (AtkText *text, g + (jint)selection_num, + (jint)start_offset, + (jint)end_offset); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + if (jresult == JNI_TRUE) { + return TRUE; +@@ -531,9 +583,12 @@ jaw_text_set_caret_offset (AtkText *text + { + JawObject *jaw_obj = JAW_OBJECT(text); + TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT); +- jobject atk_text = data->atk_text; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text); ++ if (!atk_text) { ++ return FALSE; ++ } ++ + jclass classAtkText = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkText"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -544,6 +599,7 @@ jaw_text_set_caret_offset (AtkText *text + atk_text, + jmid, + (jint)offset); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text); + + if (jresult == JNI_TRUE) + { +--- a/jni/src/jawvalue.c ++++ b/jni/src/jawvalue.c +@@ -62,7 +62,7 @@ jaw_value_data_init (jobject ac) + "", + "(Ljavax/accessibility/AccessibleContext;)V"); + jobject jatk_value = (*jniEnv)->NewObject(jniEnv, classValue, jmid, ac); +- data->atk_value = (*jniEnv)->NewGlobalRef(jniEnv, jatk_value); ++ data->atk_value = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_value); + + return data; + } +@@ -75,7 +75,7 @@ jaw_value_data_finalize (gpointer p) + + if (data && data->atk_value) + { +- (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_value); ++ (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_value); + data->atk_value = NULL; + } + } +@@ -153,9 +153,12 @@ jaw_value_get_current_value (AtkValue *o + + JawObject *jaw_obj = JAW_OBJECT(obj); + ValueData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_VALUE); +- jobject atk_value = data->atk_value; +- + JNIEnv *jniEnv = jaw_util_get_jni_env(); ++ jobject atk_value = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_value); ++ if (!atk_value) { ++ return; ++ } ++ + jclass classAtkValue = (*jniEnv)->FindClass(jniEnv, + "org/GNOME/Accessibility/AtkValue"); + jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, +@@ -165,6 +168,7 @@ jaw_value_get_current_value (AtkValue *o + jobject jnumber = (*jniEnv)->CallObjectMethod(jniEnv, + atk_value, + jmid); ++ (*jniEnv)->DeleteGlobalRef(jniEnv, atk_value); + + if (!jnumber) + { +@@ -182,15 +186,19 @@ jaw_value_set_value(AtkValue *obj, const + + JawObject *jaw_obj = JAW_OBJECT(obj); + ValueData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_VALUE); +- jobject atk_value = data->atk_value; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_value = (*env)->NewGlobalRef(env, data->atk_value); ++ if (!atk_value) { ++ return; ++ } ++ + jclass classAtkValue = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkValue"); + jmethodID jmid = (*env)->GetMethodID(env, + classAtkValue, + "setValue", + "(Ljava/lang/Number;)V"); + (*env)->CallVoidMethod(env, atk_value, jmid,(jdouble)value); ++ (*env)->DeleteGlobalRef(env, atk_value); + } + + static AtkRange* +@@ -199,15 +207,20 @@ jaw_value_get_range(AtkValue *obj) + + JawObject *jaw_obj = JAW_OBJECT(obj); + ValueData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_VALUE); +- jobject atk_value = data->atk_value; +- + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_value = (*env)->NewGlobalRef(env, data->atk_value); ++ if (!atk_value) { ++ return NULL; ++ } ++ + jclass classAtkValue = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkValue"); + jmethodID jmidMin = (*env)->GetMethodID(env, classAtkValue, "getMinimumValue", "()D"); + jmethodID jmidMax = (*env)->GetMethodID(env, classAtkValue, "getMaximumValue", "()D"); +- return atk_range_new((gdouble)(*env)->CallDoubleMethod(env, atk_value, jmidMin), ++ AtkRange *ret = atk_range_new((gdouble)(*env)->CallDoubleMethod(env, atk_value, jmidMin), + (gdouble)(*env)->CallDoubleMethod(env, atk_value, jmidMax), + NULL); // NULL description ++ (*env)->DeleteGlobalRef(env, atk_value); ++ return ret; + } + + static gdouble +@@ -215,11 +228,16 @@ jaw_value_get_increment (AtkValue *obj) + { + JawObject *jaw_obj = JAW_OBJECT(obj); + ValueData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_VALUE); +- jobject atk_value = data->atk_value; + JNIEnv *env = jaw_util_get_jni_env(); ++ jobject atk_value = (*env)->NewGlobalRef(env, data->atk_value); ++ if (!atk_value) { ++ return 0.; ++ } + jclass classAtkValue = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkValue"); + jmethodID jmid = (*env)->GetMethodID(env, classAtkValue, "getIncrement", "()D"); +- return (*env)->CallDoubleMethod(env, atk_value, jmid); ++ gdouble ret = (*env)->CallDoubleMethod(env, atk_value, jmid); ++ (*env)->DeleteGlobalRef(env, atk_value); ++ return ret; + } + + #ifdef __cplusplus +--- a/jni/src/jawutil.c ++++ b/jni/src/jawutil.c +@@ -208,6 +208,7 @@ jaw_util_get_tflag_from_jobj(JNIEnv *jni + "()Ljavax/accessibility/AccessibleContext;"); + ac = (*jniEnv)->CallObjectMethod(jniEnv, jObj, jmid); + } else { ++ (*jniEnv)->DeleteGlobalRef(jniEnv, jObj); + return 0; + } + diff -Nru java-atk-wrapper-0.33.3/debian/patches/parameters java-atk-wrapper-0.33.3/debian/patches/parameters --- java-atk-wrapper-0.33.3/debian/patches/parameters 1970-01-01 00:00:00.000000000 +0000 +++ java-atk-wrapper-0.33.3/debian/patches/parameters 2018-02-27 07:53:01.000000000 +0000 @@ -0,0 +1,108 @@ +https://bugzilla.gnome.org/show_bug.cgi?id=793821 +--- + jni/src/AtkWrapper.c | 29 ++++++++++++++++------------- + 1 file changed, 16 insertions(+), 13 deletions(-) + +--- a/jni/src/AtkWrapper.c ++++ b/jni/src/AtkWrapper.c +@@ -341,10 +341,9 @@ window_open_handler (gpointer p) + g_signal_emit_by_name(ATK_OBJECT(atk_get_root()), + "children-changed::add", + n, +- atk_obj, +- NULL); ++ atk_obj); + +- g_signal_emit_by_name(atk_obj, "create", 0); ++ g_signal_emit_by_name(atk_obj, "create"); + } + + queue_free_callback_para(para); +@@ -398,10 +397,9 @@ window_close_handler (gpointer p) + g_signal_emit_by_name(ATK_OBJECT(atk_get_root()), + "children-changed::remove", + n, +- atk_obj, +- NULL); ++ atk_obj); + +- g_signal_emit_by_name(atk_obj, "destroy", 0); ++ g_signal_emit_by_name(atk_obj, "destroy"); + } + + queue_free_callback_para(para); +@@ -433,7 +431,7 @@ window_minimize_handler (gpointer p) + CallbackPara *para = (CallbackPara*)p; + AtkObject* atk_obj = ATK_OBJECT(para->jaw_impl); + +- g_signal_emit_by_name(atk_obj, "minimize", 0); ++ g_signal_emit_by_name(atk_obj, "minimize"); + + queue_free_callback_para(para); + +@@ -462,7 +460,7 @@ window_maximize_handler (gpointer p) + CallbackPara *para = (CallbackPara*)p; + AtkObject* atk_obj = ATK_OBJECT(para->jaw_impl); + +- g_signal_emit_by_name(atk_obj, "maximize", 0); ++ g_signal_emit_by_name(atk_obj, "maximize"); + + queue_free_callback_para(para); + +@@ -490,7 +488,7 @@ window_restore_handler (gpointer p) + CallbackPara *para = (CallbackPara*)p; + AtkObject* atk_obj = ATK_OBJECT(para->jaw_impl); + +- g_signal_emit_by_name(atk_obj, "restore", 0); ++ g_signal_emit_by_name(atk_obj, "restore"); + + queue_free_callback_para(para); + +@@ -519,7 +517,7 @@ window_activate_handler (gpointer p) + CallbackPara *para = (CallbackPara*)p; + AtkObject* atk_obj = ATK_OBJECT(para->jaw_impl); + +- g_signal_emit_by_name(atk_obj, "activate", 0); ++ g_signal_emit_by_name(atk_obj, "activate"); + + queue_free_callback_para(para); + +@@ -547,7 +545,7 @@ window_deactivate_handler (gpointer p) + CallbackPara *para = (CallbackPara*)p; + AtkObject* atk_obj = ATK_OBJECT(para->jaw_impl); + +- g_signal_emit_by_name(atk_obj, "deactivate", 0); ++ g_signal_emit_by_name(atk_obj, "deactivate"); + + queue_free_callback_para(para); + +@@ -577,7 +575,7 @@ window_state_change_handler (gpointer p) + CallbackPara *para = (CallbackPara*)p; + AtkObject* atk_obj = ATK_OBJECT(para->jaw_impl); + +- g_signal_emit_by_name(atk_obj, "state-change", 0); ++ g_signal_emit_by_name(atk_obj, "state-change", 0, 0); + + queue_free_callback_para(para); + +@@ -1059,6 +1057,7 @@ bounds_changed_handler (gpointer p) + { + CallbackPara *para = (CallbackPara*)p; + AtkObject* atk_obj = ATK_OBJECT(para->jaw_impl); ++ AtkRectangle rect; + + if (atk_obj == NULL) + { +@@ -1067,7 +1066,11 @@ bounds_changed_handler (gpointer p) + queue_free_callback_para(para); + return G_SOURCE_REMOVE; + } +- g_signal_emit_by_name(atk_obj, "bounds_changed"); ++ rect.x = -1; ++ rect.y = -1; ++ rect.width = -1; ++ rect.height = -1; ++ g_signal_emit_by_name(atk_obj, "bounds_changed", &rect); + queue_free_callback_para(para); + + return G_SOURCE_REMOVE; diff -Nru java-atk-wrapper-0.33.3/debian/patches/series java-atk-wrapper-0.33.3/debian/patches/series --- java-atk-wrapper-0.33.3/debian/patches/series 2018-02-19 23:26:15.000000000 +0000 +++ java-atk-wrapper-0.33.3/debian/patches/series 2018-02-27 07:53:01.000000000 +0000 @@ -16,3 +16,6 @@ jaw_ref iter child_add +GC +parameters +coords diff -Nru java-atk-wrapper-0.33.3/debian/watch java-atk-wrapper-0.33.3/debian/watch --- java-atk-wrapper-0.33.3/debian/watch 2015-09-09 02:12:13.000000000 +0000 +++ java-atk-wrapper-0.33.3/debian/watch 2018-02-27 07:53:01.000000000 +0000 @@ -1,2 +1,5 @@ -version=3 +version=4 +opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%-$1.tar.gz%" \ + https://github.com/GNOME/java-atk-wrapper/releases \ + (?:.*?/)?v?(\d[\d.]*)\.tar\.gz http://ftp.gnome.org/pub/GNOME/sources/java-atk-wrapper/([\d.]*)/java-atk-wrapper-([\d.]*).tar.(gz|xz)