From 3daf7a3135e252fa13636e6553e77b78d41bb509 Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Wed, 16 Sep 2026 03:56:00 +0200 Subject: [PATCH] [GTK] Look up the accessibility class once in os_custom.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit call_accessible_object_function() called FindClass for every accessibility callback. The class is now looked up once and kept as a global reference, primed when an accessible is registered, and a failed lookup clears the pending exception instead of leaving it for the next JNI call. FindClass resolves against the class loader of the calling Java method, so it only finds AccessibleObject while the C code is entered from a JNI native method. Assisted-by: multiple AI agents and layers of automated tooling 🤖 --- .../Eclipse SWT PI/gtk/library/os_custom.c | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c index 0b2f7acce92..d979a197e11 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.c @@ -1040,6 +1040,23 @@ G_DEFINE_TYPE_WITH_CODE (SwtFixedAccessible, swt_fixed_accessible, GTK_TYPE_CONT // Fully qualified Java class name for the Java implementation of ATK functions const char *ACCESSIBILITY_CLASS_NAME = "org/eclipse/swt/accessibility/AccessibleObject"; +static jclass accessibility_class = NULL; + +// FindClass resolves against the class loader of the calling Java method, which only is SWT's +// when called from a JNI native method, so the class is looked up once and kept. +static jclass get_accessibility_class (JNIEnv *env) { + if (accessibility_class == NULL) { + jclass cls = (*env)->FindClass(env, ACCESSIBILITY_CLASS_NAME); + if (cls == NULL) { + (*env)->ExceptionClear(env); + return NULL; + } + accessibility_class = (*env)->NewGlobalRef(env, cls); + (*env)->DeleteLocalRef(env, cls); + } + return accessibility_class; +} + static void swt_fixed_accessible_init (SwtFixedAccessible *accessible) { // Initialize the SwtFixedAccessiblePrivate struct accessible->priv = swt_fixed_accessible_get_instance_private (accessible); @@ -1105,6 +1122,11 @@ void swt_fixed_accessible_register_accessible (AtkObject *obj, gboolean is_nativ SwtFixedAccessiblePrivate *private = fixed->priv; private->has_accessible = TRUE; + JNIEnv *env; + if ((*JVM)->GetEnv(JVM, (void **)&env, JNI_VERSION_10) == JNI_OK) { + get_accessibility_class(env); + } + if (!is_native) { gtk_accessible_set_widget (GTK_ACCESSIBLE (obj), to_map); private->widget = to_map; @@ -2122,7 +2144,7 @@ jlong call_accessible_object_function (const char *method_name, const char *meth } // Find the class pointer - cls = (*env)->FindClass(env, ACCESSIBILITY_CLASS_NAME); + cls = get_accessibility_class(env); if (cls == NULL) { g_critical("JNI class pointer is NULL for class %s\n", ACCESSIBILITY_CLASS_NAME); return 0;