Hi, There is at least one JNI call that is designed not to return. This is that gtkMain native method in gnu.java.awt.peer.gtk.GtkToolkit. Some VMs require all Java threads to run upto a garbage collection barrier before garbage collection can be performed. If a Java thread never leaves JNI code then this will never happen and the VM deadlocks. A solution to this is to rewrite the gtkMain loop to something like what follows: in GtkTookit.java: public static void gtkMain() { try { while(true) { while(gtkEventsPending()) { gtkMainIteration(); } Thread.sleep(10); } } catch(InterruptedException e){} } public static native void gtkMainIteration(); private static native boolean gtkEventsPending(); in gnu_java_awt_peer_gtk_GtkToolkit.c (NB regenerate the JNI header files): JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkMainIteration (JNIEnv *env __attribute__((unused)), jclass obj __attribute__((unused))) { gdk_threads_enter (); gtk_main_iteration (); gdk_threads_leave (); } JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkEventsPending (JNIEnv *env __attribute__((unused)), jclass obj __attribute__((unused))) { gboolean pending; gdk_threads_enter (); pending = gtk_events_pending (); gdk_threads_leave (); return pending == TRUE ? JNI_TRUE : JNI_FALSE; } For performance the nested while loop could be moved into the JNI code. Is having all JNI code return an option for classpath? Thanks, Ian Rogers