Skip to content

Linux: report both WebKitGTK load errors; never switch on Xlib threads late - #68

Merged
shannah merged 2 commits into
masterfrom
claude/kind-ptolemy-eujfg9
Oct 3, 2026
Merged

shannah merged 2 commits into
masterfrom
claude/kind-ptolemy-eujfg9

Conversation

@shannah

@shannah shannah commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Two Linux fixes found while getting an agentic-app-framework app (Cloudbeds Assistant) running on Ubuntu 22.04.

1. Report both WebKitGTK load errors and publish them to Java (Canvas 8)

On a 22.04 host without WebKitGTK, the loader message showed only the last dlerror(). So a 4.1 library that is installed but fails to load looked the same as having no WebKitGTK at all. The reason also reached only stderr, because the JVM turns JNI_ERR into a generic UnsatisfiedLinkError: unsupported JNI version 0xFFFFFFFF.

  • The message now gives each SONAME's own reason (WebKit and JSC); the buffer grows from 512 to 1024 bytes.
  • JNI_OnLoad publishes the message as the system property ca.weblite.webview.nativeLoadError before returning JNI_ERR. This is best effort and never changes the outcome. Embedders read it; webliteca/agentic-app-framework#458 shows it in a dialog.
  • Verified on stock 22.04: without WebKitGTK, both reasons appear on stderr and in the property; with libwebkit2gtk-4.1-0 installed, the library loads and the property stays unset.

2. Never switch on Xlib threads after a GDK display exists (Canvas 7)

Crash: on Ubuntu 22.04 (libX11 1.7.5), a jDeploy-launched app crashes with segfault at 10 … in libc.so.6 when you focus a text field. The core dump from the affected VM:

#0 pthread_mutex_lock (NULL)  #1 XrmQGetResource  #2 XGetDefault  #3 _XcursorGetDisplayInfo
… libgdk-3 / libwebkit2gtk-4.1 … #23 gtk_main  #24 embed::GtkPump::ensure_started()

Cause:

  1. The jDeploy launcher initialises GTK for its splash before the JVM starts, without XInitThreads(). With libX11 < 1.8, that display and its resource database get no locks.
  2. The pump calls XInitThreads() late, then gtk_init reuses that display.
  3. When WebKit loads the I-beam cursor, Xlib locks the NULL Xrm mutex.

Change: GtkPump::ensure_started calls XInitThreads() only when gdk_display_get_default() is NULL, that is, when nothing has opened a GDK display yet. gdk_set_allowed_backends("x11") moves ahead of the check, since it must run before the display manager is created. Canvas 7 gets an Approach note, a Structure note and a never-relax Safeguard.

Verification with a minimal GTK program on Ubuntu 22.04 / libX11 1.7.5, using a display that has a resource database:

  • GTK init, then XGetDefault, then a late XInitThreads(), then XGetDefault → SIGSEGV (139).
  • The same sequence with the late call skipped → survives.
  • XInitThreads() first (the launcher fix, shannah/client4jgo#78) → survives.

The launcher fix is the primary one. This change makes swingwebview safe under any host that initialises GTK first, including launchers that predate that fix.

Both changes build with the release recipe and pass the no-WebKit-NEEDED and glibc ≤ 2.31 gates.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KJGbJfSqGDbZWCbUnoKYVx

claude added 2 commits October 2, 2026 21:12
The Linux loader kept only the last dlerror(), so a 4.1 library that was
installed but failed to load read exactly like a host with no WebKitGTK.
Each attempt's reason is now kept, for WebKit and JavaScriptCore alike.

JNI_OnLoad's JNI_ERR makes the JVM throw a generic "unsupported JNI
version 0xFFFFFFFF", so the reason only ever reached stderr. The loader
now also sets the system property ca.weblite.webview.nativeLoadError
before failing, so an embedder can tell the user why the WebView is
unavailable. Publishing is best effort and never changes the outcome.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KJGbJfSqGDbZWCbUnoKYVx
Xlib needs XInitThreads() before any display is opened. The jDeploy
launcher initialises GTK for its splash before the JVM starts, so the
pump's gtk_init reuses a display that has no locks; the pump's late
XInitThreads() then makes Xlib lock it, and the first cursor WebKit
loads (Xcursor -> XGetDefault -> XrmQGetResource) calls
pthread_mutex_lock(NULL) on libX11 1.7.x (Ubuntu 22.04): a SIGSEGV on
focusing any text field, seen with a core dump.

GtkPump::ensure_started now calls XInitThreads() only when
gdk_display_get_default() is NULL, i.e. when nothing has opened a GDK
display yet. Reproduced on Ubuntu 22.04 / libX11 1.7.5 with a minimal
GTK program: late XInitThreads -> SIGSEGV; skipped -> survives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KJGbJfSqGDbZWCbUnoKYVx
@shannah shannah changed the title Report both WebKitGTK load errors and publish them to Java Linux: report both WebKitGTK load errors; never switch on Xlib threads late Oct 2, 2026
@shannah shannah closed this Oct 3, 2026
@shannah shannah reopened this Oct 3, 2026
@shannah
shannah marked this pull request as ready for review October 3, 2026 14:10
@shannah
shannah merged commit 9ce3b2e into master Oct 3, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants