slint-ui/slint · error
JNI error
Error message
JNI error: {e:#?} What it means
print_jni_error is the Android backend's centralized JNI failure handler: any jni::errors::Error returned from a JNI call (class lookup failure, wrong argument type, Java exception pending, etc.) is funneled here and turned into a panic with a debug-formatted error. It is called from many backend entry points (event processing, input method, safe-area queries, helper construction), so seeing it means a Java-side interaction failed at runtime on Android, not that Slint logic itself is wrong.
Solutions
- Inspect the debug-formatted {e:#?}; common causes are JavaLangException, JNIEnv getenv failures, or detached threads
- Ensure every JNI call goes through a valid AndroidEnv/JNIEnv obtained for the calling thread, not cached across thread boundaries
- Check exception policy: with AttachmentExceptionPolicy::PreReThrowPostCatch the jni crate re-throws; clear pending exceptions with env.exception_clear() before further calls
- Verify the Java helper classes (SlintAndroidJavaHelper, DexFileClassLoader) loaded successfully at startup; a failed class load surfaces later as a JNI error
Defensive patterns
Strategy: try-catch
When it happens
Trigger: Thrown at internal/backends/android-activity/javahelper.rs:292 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16).
Data as JSON: /api/errors/6013662203b009f2.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backends/android-activity/javahelper.rs:292
is_instance_of = {
JClassLoader,
}
}
bind_java_type! {
DexFileClassLoader => "dalvik.system.DexClassLoader",
constructors {
fn new(dex_path: JString, optimized_directory: JString, library_search_path: JString, parent: JClassLoader),
},
is_instance_of = {
JClassLoader,
}
}
// See `AttachmentExceptionPolicy::PreReThrowPostCatch` in `jni` crate.
#[track_caller]
pub fn print_jni_error(_app: &AndroidApp, e: jni::errors::Error) -> ! {
panic!("JNI error: {e:#?}")
}
#[allow(dead_code)]
pub struct JavaHelper(jni::refs::Global<SlintAndroidJavaHelper<'static>>, AndroidApp);
fn get_helper_class_loader(
env: &mut Env,
native_activity: &AndroidActivity<'_>,
) -> Result<&'static JClassLoader<'static>, jni::errors::Error> {
static DEX_CLASS_LOADER: OnceLock<jni::refs::Global<JClassLoader<'static>>> = OnceLock::new();
fn build_dex_class_loader<'local>(
env: &mut Env<'local>,
native_activity: &AndroidActivity<'_>,
) -> Result<JClassLoader<'local>, jni::errors::Error> {
let native_activity = env.new_local_ref(native_activity)?;
let app_context = AndroidContext::cast_local(env, native_activity)?;
let context_class_loader = app_context.get_class_loader(env)?;View on GitHub (pinned to bb937076de)