Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-119791

Can no longer detect Java exceptions from C++ code with Qt 6

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.6.0
    • Extras: Android
    • None
    • Android
    • 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?

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            qtandroidteam Qt Android Team
            roballan Rob Allan
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes