java-native-access/jna · warning

JNA: error handling callback exception, continuing

Error message

JNA: error handling callback exception, continuing

What it means

After ffi_call invokes the Java callback, if a Java exception is pending and the internal handle_exception path fails (returns 0), JNA prints this message to stderr, clears/continues, and zeroes the return buffer for non-void returns. It indicates an exception escaped the Java callback AND the installed exception handler (Callback.UncaughtExceptionHandler) could not process it.

Source

Thrown at native/callback.c:481

          break;
        }
      }
    }

    if (cb->rflag == CVT_STRUCTURE_BYVAL) {
      resp = alloca(sizeof(jobject));
    }
    else if (cb->cif.rtype->size > cif->rtype->size) {
      resp = alloca(cb->cif.rtype->size);
    }
#define FPTR(ENV,OFFSET) (*(void **)((char *)(*(ENV)) + OFFSET))
#define JNI_FN(X) ((void (*)(void))(X))
    ffi_call(&cb->java_cif, JNI_FN(FPTR(env, cb->fptr_offset)), resp, args);
    if ((*env)->ExceptionCheck(env)) {
      jthrowable throwable = (*env)->ExceptionOccurred(env);
      (*env)->ExceptionClear(env);
      if (!handle_exception(env, self, throwable)) {
        fprintf(stderr, "JNA: error handling callback exception, continuing\n");
      }
      if (cif->rtype->type != FFI_TYPE_VOID) {
        memset(oldresp, 0, cif->rtype->size);
      }
    }
    else switch(cb->rflag) {
    case CVT_INTEGER_TYPE:
      if (cb->cif.rtype->size > sizeof(ffi_arg)) {
        *(jlong *)oldresp = getIntegerTypeValue(env, *(void **)resp);
      }
      else {
        *(ffi_arg *)oldresp = (ffi_arg)getIntegerTypeValue(env, *(void **)resp);
      }
      break;
    case CVT_POINTER_TYPE:
      *(void **)resp = getPointerTypeAddress(env, *(void **)resp);
      break;
    case CVT_NATIVE_MAPPED:

View on GitHub (pinned to d036ad9781)

Solutions

  1. Wrap the callback body in try-catch and handle/log exceptions inside the callback itself.
  2. Install a robust Callback.UncaughtExceptionHandler that cannot itself throw.
  3. Note that the native return value is zeroed — design native callers to tolerate a zero/NULL result.

Example fix

// before
public void invoke() { doWork(); } // exception escapes to native
// after
public void invoke() {
    try { doWork(); } catch (Throwable t) { log(t); }
}
Defensive patterns

Strategy: try-catch

Try / catch

// Inside every callback body
public ReturnType invoke(...) {
    try {
        return realWork(...);
    } catch (Throwable t) {
        log.error("callback failed", t);
        return defaultValue; // zero/NULL-equivalent
    }
}

Prevention

When it happens

Trigger: The Java callback method throws, and the registered UncaughtExceptionHandler itself throws, or none is installed and the default handling fails, when native code invokes the callback via ffi_call.

Common situations: Callbacks that throw unexpected runtime exceptions (NPE, etc.) while native code holds no Java exception expectations; misconfigured Callback.UncaughtExceptionHandler that itself errors.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/cc18d24f968fd7f1. Report an issue: GitHub.