Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java UncaughtExceptionHandler haven't got any exception using JNI

I have a Java library which run a series of tasks. And I registered a default uncaught exception handler using:

Thread.setDefaultUncaughtExceptionHandler(new JavaUncaughtExceptionHandler());

The UncaughtExceptionHandler implements UncaughtExceptionHandler and only log the error information in STDERR.

My Java library is called through JNI from C++ code, and the JNI is calling it with ExceptionCheck() and log the error as FATAL in C++.

The problem is:

In the runtime, when there's a RuntimeException (or any other uncaught exception) happens in my Java code, the error got captured in C++ instead of my JavaUncaughtExceptionHandler registered as thread default uncaught exception handler.

  1. Is that the excepted behaviour?
  2. When will the DefaultUncaughtExceptionHandler actually got called? I know before thread got shutdown, but when specifically in JNI case. Is that called before return to C++ or after C++ code finished as well). I think it's related to the thread management in JNI, please share any related information as well.
  3. Is there anyway I can catch all the exceptions in my Java code (other alternative way except put a try/catch blocks)

Thanks so much.

like image 680
user788767 Avatar asked Aug 24 '16 15:08

user788767


1 Answers

It sounds like you are talking about the Java Invocation API (i.e., you are calling Java methods from within a C++ program, as opposed to simple JNI where the calls go the other way.)

I'm not a big expert, but I have worked with the Java Invocation API.

As far as I know, an uncaught exception handler only will be invoked when an exception is thrown by a Java thread's run() method. But there isn't any run() method in a thread that was created by C/C++ code.

I wrote C, not C++, so my calls into Java all looked like

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

When that's called from C, it always returns, but before you use the return_value, you have to check whether the method returned normally or threw an exception.

If it threw an exception, there's no way for the exception to be "uncaught", If the C code doesn't call (*env)->ExceptionClear(env) (i.e., if the C code doesn't "catch" the exception), then I don't remember what happens, but I don't think it's good.

like image 117
Solomon Slow Avatar answered Sep 28 '22 07:09

Solomon Slow