java-native-access/jna · error
JNA: error while handling callback exception, continuing
Error message
JNA: error while handling callback exception, continuing
What it means
When a Java callback throws, invoke_callback hands the throwable to handle_exception (the Callback.UncaughtExceptionHandler path). If that handler itself fails, JNA prints this message, has already cleared the exception, zeroes the native return buffer (for non-void returns), and continues the native call. It signals that both the callback and its exception handler failed.
Source
Thrown at native/callback.c:557
}
}
}
else {
jobject result;
jobjectArray params =
(*env)->NewObjectArray(env, cif->nargs, classObject, NULL);
unsigned int i;
for (i=0;i < cif->nargs;i++) {
jobject arg = new_object(env, cb->arg_jtypes[i], cbargs[i], JNI_FALSE, cb->encoding);
(*env)->SetObjectArrayElement(env, params, i, arg);
}
result = (*env)->CallObjectMethod(env, self, cb->methodID, params);
if ((*env)->ExceptionCheck(env)) {
jthrowable throwable = (*env)->ExceptionOccurred(env);
(*env)->ExceptionClear(env);
if (!handle_exception(env, self, throwable)) {
fprintf(stderr, "JNA: error while handling callback exception, continuing\n");
}
if (cif->rtype->type != FFI_TYPE_VOID)
memset(resp, 0, cif->rtype->size);
}
else {
extract_value(env, result, resp, cif->rtype->size, JNI_TRUE, cb->encoding);
}
}
}
static TLS_KEY_T tls_thread_data_key;
static thread_storage* get_thread_storage(JNIEnv* env) {
thread_storage* tls = (thread_storage *)TLS_GET(tls_thread_data_key);
if (tls == NULL) {
tls = (thread_storage*)calloc(1, sizeof(thread_storage));
if (!tls) {
throwByName(env, EOutOfMemory, "JNA: Can't allocate thread storage");
}View on GitHub (pinned to d036ad9781)
Solutions
- Fix the exception inside your callback so no exception ever reaches handle_exception.
- Make the Callback's UncaughtExceptionHandler bulletproof: wrap its body in try-catch and never throw.
- Check stderr/stdout of the process for the original exception stack trace printed before this message.
- Ensure the callback class and its dependencies are loadable from the native callback thread's context classloader.
Example fix
// before
handler = ex -> log.info(ex.getMessage()); // NPE if message null -> handler throws
// after
handler = ex -> { try { log.warn("callback failed", ex); } catch (Throwable t) { /* swallow */ } }; Defensive patterns
Strategy: try-catch
Try / catch
// Install a handler that can never throw
callbackRef.setUncaughtExceptionHandler((cb, ex) -> {
try { LOGGER.log(Level.SEVERE, "callback failed", ex); }
catch (Throwable ignored) { }
}); Prevention
- Wrap all callback body logic in try-catch inside the Callback implementation
- Never let logging/config code in an UncaughtExceptionHandler throw
- Log the full stack trace at the callback boundary so root causes are visible
- Test callbacks from native threads, not just Java threads
When it happens
Trigger: A Java Callback implementation throws, and the installed UncaughtExceptionHandler (or default handling via handle_exception) itself throws an exception or fails to run, right after CallObjectMethod sets a pending JNI exception.
Common situations: An uncaught exception handler that itself throws (e.g. logger misconfigured, NPE inside handler), exceptions thrown in callbacks invoked from native threads where class loading of the handler fails, or OOM inside exception handling.
Related errors
- JNA: error handling callback exception, continuing
- JNA: Unhandled result conversion: %d
- JNA: couldn't obtain thread-local storage
- JNA: Out of memory: Can't allocate local frame
- JNA: could not detach thread
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/7f9f200da39d0b74.
Report an issue: GitHub.