[Development] Make Qt6 JNI API safer to use

Fabian Kosmale fabian.kosmale at qt.io
Fri Mar 6 13:03:29 CET 2020

Hi Bogdan,

first of all, I think improving the JNI error handling is a great idea. 
However, I'm currently not convinced that we should (unconditionally) 
require exceptions, or that we really need them. As far as I can tell, 
the Android NDK still disables exceptions by default, and the last time 
I checked, enabling them had a non-insignificant size overhead.

However, I think we can actually have our cake and eat it. It should be 
possible if we are going to use something like outcome/QSystemResult.

- Our API would always return an outcome type

- If there is an error, you just store it that information there. We can 
introduce our own error codes to distinguish between the different error 
conditions (pending exception, illegal argument, etc.). If you think we 
need more context than the type of the error, we could use a full-blown 
Result<Value, Error> type.

- If you access the normal value of the result, and exceptions are not 
enabled, just std::terminate. In addition, if a user decides that they 
can accept the cost of exceptions, this is the place where you can throw 
an exception if they are enabled.



Am 05.03.20 um 13:12 schrieb Bogdan Vatra via Development:
> Hi,
>    I started to review and move androidextras to qtbase (qtbase/src/corelib/
> platform/android). Here we have a problem with our Qt JNI API. The problem is
> that in Java exceptions are (ab)used everywhere. Even if we have a way to
> check for exceptions after each call in Qt, it's not used (not even by us in
> Qt code itself), mostly because it's a little unwieldy to use it. To fix this
> issue I'd like to discuss with you a few options:
> 1 - add something similar to std::expected[0] or outcome[1] to Qt. We can't
> use std::optional because it doesn't work for void function e.g.
> std::optional<void> callMethod(). std::expected allows our API users to
> handle the errors without try/catch. I think std::expected will be useful in
> many places not only for QtJNI e.g. QJsonDocument
> QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error =
> nullptr) or any other place where we pass the error result as an argument.
> Of course we still need to enable exceptions as if we try to access the
> returned value without checking its state first it will still throw an
> exception if the value is not valid.
> 2 - use exceptions (at least for android?). This means if a JNI call fails it
> will throw a C++ exception. IMHO this is by far the best, cleanest and easiest
> solution.
> 3 - I'm open for better ideas which makes the coding safer and *easier*.
> Cheers,
> BogDan.
> [0] https://wg21.link/P0323R9 sadly it's not in c++20 :( therefore we need to
> either use an existing implementation or implement one in Qt.
> [1] https://ned14.github.io/outcome/
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> https://lists.qt-project.org/listinfo/development

Fabian Kosmale
Software Engineer

The Qt Company GmbH
Erich-Thilo-Str. 10
D-12489 Berlin
fabian.kosmale at qt.io

Geschäftsführer: Mika Pälsi,
Juha Varelius, Mika Harjuaho
Sitz der Gesellschaft: Berlin,
Registergericht: Amtsgericht
Charlottenburg, HRB 144331 B

More information about the Development mailing list