7

我有一个运行一系列任务的 Java 库。我使用以下方法注册了一个默认的未捕获异常处理程序:

Thread.setDefaultUncaughtExceptionHandler(new JavaUncaughtExceptionHandler());

UncaughtExceptionHandler 实现UncaughtExceptionHandler并且仅将错误信息记录在STDERR.

我的 Java 库是通过 C++ 代码中的 JNI 调用的,而 JNI 正在调用它ExceptionCheck()并将错误记录为 C++ 中的 FATAL。

问题是:

在运行时,当RuntimeException我的 Java 代码中发生(或任何其他未捕获的异常)时,错误会在 C++ 中捕获,而不是我JavaUncaughtExceptionHandler注册为线程默认的未捕获异常处理程序。

  1. 那是例外行为吗?
  2. 什么时候会DefaultUncaughtExceptionHandler真正被调用?我知道在线程关闭之前,但特别是在 JNI 情况下。是在返回 C++ 之前调用还是在 C++ 代码完成之后调用)。我认为它与JNI中的线程管理有关,请分享任何相关信息。
  3. 无论如何我可以在我的Java代码中捕获所有异常(除了放置try/catch块之外的其他替代方式)

非常感谢。

4

1 回答 1

1

听起来您在谈论Java 调用 API(即,您从 C++ 程序中调用 Java 方法,而不是简单的 JNI,其中调用以另一种方式进行。)

我不是一个大专家,但我使用过 Java Invocation API。

run()据我所知,只有在 Java 线程的方法抛出异常时才会调用未捕获的异常处理程序。但是在由 C/C++ 代码创建的线程中没有任何run()方法。

我写的是 C,而不是 C++,所以我对 Java 的调用看起来都像

jobject return_value = (*env)->CallObjectMethod(env, instance, method_id, ...);

当从 C 中调用时,它总是返回,但在使用 之前return_value,您必须检查该方法是正常返回还是抛出异常。

如果它抛出了一个异常,那么这个异常就不可能“未被捕获”,如果 C 代码没有调用(*env)->ExceptionClear(env)(即,如果 C 代码没有“捕获”异常),那么我不记得是什么发生了,但我不认为这很好。

于 2016-08-24T17:19:22.900 回答