Repository navigation
android: Clear and describe Java exceptions in the core JNI calls - #41
Open
Bombatomica64 wants to merge 1 commit into
Open
Bombatomica64 wants to merge 1 commit into
Bombatomica64 wants to merge 1 commit into
Conversation
A call into Java that throws leaves the exception pending. jni 0.22 then refuses every later JNI call in the same frame, and the error only says "JavaException". Several core calls converted the error with map_err(to_string) and left the exception pending; others cleared it by hand, so its message was lost, or dropped the error with `let _ =`. The new JniResultExt::or_clear clears the pending exception and returns its toString(), so errors read like "java.lang.SecurityException: ...". or_catch makes an expected exception explicit: the system chrome now falls back to the pre-API-30 flags only on NoSuchMethodError, where any failure of getInsetsController used to. The calls into Java in jni.rs, host.rs, platform.rs, window.rs, platform_view.rs and document_picker.rs use them, and their errors are returned or logged. get_string now checks that the object is a java.lang.String before reading it; before, any object handed to it was read as one. The platform packages are left for a follow-up. Part of longbridge#31. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #31 (PR 2 of the proposed list). This PR changes only the core files under
src/android/. The platform packages are left for a follow-up (PR 6 in #31).Problem
When a call into Java throws, the exception stays pending. jni 0.22 then refuses every later JNI call in the same frame. Until
with_envreturns, they all fail with the same bareJava exception was thrown, and at the endwith_envreplaces the closure's result with that exception. In the core files:map_err(|e| e.to_string())and leave the exception pending: the IME show/hide calls, the keyboard layout and thermal queries, andupdate_ime_position.find_app_class,set_system_chrome, the platform views). Some also drop the error withlet _ =.hide_keyboard_androidandreset_keyboard_compositionclear the exception before converting the error, so the message is lost there too.set_system_chromefalls back to the pre-API-30setSystemUiVisibilityflags on any failure ofgetInsetsController, not only when the method doesn't exist.get_stringreads any object as ajava.lang.Stringwithout checking its type (nativeImepasses it whatever Java sent).Change
JniResultExt::or_clear(env), forjni::errors::Result. On error it clears the pending exception and returns itstoString(), so errors read likejava.lang.SecurityException: <message>instead ofJava exception was thrown.JniResultExt::or_catch(env, class), for an exception that is an expected result: an instance ofclassis cleared and givesOk(None). Any other exception is handled likeor_clear.set_system_chromeuses it so that onlyjava/lang/NoSuchMethodError(API < 30) leads to the fallback.take_exception(env)clears the pending exception and returns its description.set_host_activityuses it in place of its own clear.jni.rs,host.rs,platform.rs,window.rs,platform_view.rsanddocument_picker.rsnow use these. Their errors are returned, or logged where the function returns nothing (warn;debugfor the per-keystroke IME calls).get_stringchecksis_instance_of(java/lang/String)first. For an object of another type it logs and returns an empty string.JniExt::e()is unchanged. Its doc now says that it leaves the exception pending, so it is for JNI calls that don't call into Java.accessibility.rsis not changed: it works throughaccesskit_android's jni 0.21 and already clears its exceptions. The JNI exports (nativeIme,nativeOnDeepLink, …) are not changed either: #31's PR 1 edits the same lines, and this keeps the two PRs independent.Testing
Run on this branch with the Android NDK 27, target
aarch64-linux-android:cargo fmt --all -- --checkcargo check --target aarch64-linux-android --all-targets, pluscargo checkofexample/cargo clippy --target aarch64-linux-android: the same 8 warnings as onmain, none newcargo test --lib: 46 passedAn earlier version of these changes ran on a OnePlus CPH2581 (Android 16), through the host entry point, as part of the full rework in Bombatomica64#1. This PR is that work ported onto the current
main: #24–#30 moved the code (per-host Activities, night mode, assets), so the hunks were redone by hand rather than cherry-picked.Follow-ups
The same helpers in the platform packages (PR 6 in #31), and the host Activity registry (PR 3), which uses
or_clear.🤖 Generated with Claude Code