Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
6.6.0
-
None
-
Android
-
-
2023wk52FOQtforAndroid, 2025Season1QtforAndroid
Description
In Qt 5, it was possible to detect Java exceptions from C++, using code like the following:
jlong space = QAndroidJniObject::callStaticMethod<jlong> ( "com/trimble/access/FileSystem", "freeSpace", "(Ljava/lang/String;)J", QAndroidJniObject::fromString(dirName)); QAndroidJniEnvironment env; if (env->ExceptionCheck ()) { // Java exception! Handle it here... ... env->ExceptionClear (); }
This approach doesn't work any more in Qt 6, because - as far as I can tell - every implementation of callMethod(), callObjectMethod(), callStaticMethod(), etc, now calls env.checkAndClearExceptions(). That means, by the time we return from the method call, and call env->ExceptionCheck(), it will never detect an exception, because it has already been cleared by the call to env.checkAndClearExceptions().
I guess that change was made as part of the refactoring in this area, done by assam a couple of years ago.
There are pros and cons to this change in behaviour:
- Java exceptions now get notified to the handler function registered via qInstallMessageHandler(). We can, and do, log these out to a diagnostic file, which is somewhat useful.
- Java exceptions will no longer crash/terminate the app, since they are checked and cleared by the Qt code. It's debatable whether that's an improvement - arguably, an unhandled exception should crash the app, and by clearing it and just reporting a warning, this could be viewed as sweeping a potential problem under the rug.
- It seems a definite disadvantage that the calling app can no longer check and clear any Java exceptions itself. Yes, we can rewrite code like the above example so that it relies on a return value instead of looking for an exception, since the Java method that's being called is in our codebase. But that's not possible when using Android or Java library classes - for example, if I call available() on a java.io.InputStream object, then it could throw an IOException - and there's no way I can detect that.
I wonder if there might be a way to make this behaviour conditional, e.g. could we set a flag on QJniEnvironment to indicate whether we want Qt to consume Java exceptions (as it does now), or leave them alone so that our application code can handle them?