Skip to content

[pigeon] Fix native interop (JNI) calls in minified Android release builds - #13151

Merged
auto-submit[bot] merged 2 commits into
flutter:mainfrom
tarrinneal:keep-error-class
Oct 7, 2026
Merged

auto-submit[bot] merged 2 commits into
flutter:mainfrom
tarrinneal:keep-error-class

Conversation

@tarrinneal

Copy link
Copy Markdown
Contributor

Flutter minifies Android release builds with R8, which removes or renames classes that it doesn't see being used. JNI looks up classes and members by name at runtime, from Dart code that R8 can't see. As a result, native interop calls that work in debug builds fail in release builds with ClassNotFoundException or NoSuchMethodError.

This PR:

  • Kotlin generator: When useJni is set, adds @Keep to every generated class that JNI reaches by name:

    • data classes, including sealed classes;
    • enums and their companion objects;
    • the FlutterApi interface and its Registrar;
    • the error class.

    The HostApi interface and Registrar already had @Keep. The test plugin and example app are regenerated.

  • Docs: Documents keep rules for six Kotlin standard library classes. package:jni and the generated Dart code look these up by name to call and implement suspend (@async) methods. Library classes can't be annotated, so these rules are needed until package:jni ships them ([jnigen] Suspend functions fail in minified release builds: keep the Kotlin classes jni looks up by name dart-lang/native#3732).

    • Updated native_interop_guide.md, native_interop_migration_guide.md and the migration skill.
    • Each spot has a TODO linking that issue.
  • CI: Adds an android_kotlin_native_interop_release_tests suite to the Linux_android custom_package_tests shard. It runs the native interop integration tests in a minified release build.

Results for the native interop suite (339 tests) in a minified release build on an arm64 emulator:

Passed Failed Didn't run
Before (old generated code, with the Kotlin rules) 106 70 163
This PR, without the Kotlin rules 210 129 0
This PR 339 0 0
  • Before: 163 tests didn't run. R8 had removed the FlutterApi interface, so registering the FlutterApi threw ClassNotFoundException during test setup.
  • Without the Kotlin rules: every failure is a call through a suspend function. Each one fails with NoSuchMethodError, because R8 renames kotlin.coroutines.Continuation.

Fixes flutter/flutter#193880
Temporary fix for dart-lang/native#3732

Pre-Review Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Oct 6, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates Pigeon to add the @Keep annotation to generated Kotlin classes when generating for JNI, preventing ClassNotFoundException in minified Android release builds. It also updates documentation, adds consumer Proguard rules for Kotlin standard library classes, and introduces a new integration test suite (androidKotlinNativeInteropReleaseTests) to verify native interop in release mode. Feedback on the changes suggests wrapping the release-mode test execution in a try-finally block to prevent process and stream leaks, and handling potential UnsupportedError when using ProcessSignal.sigkill on Windows.

@dkwingsmt dkwingsmt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@tarrinneal tarrinneal added the autosubmit Merge PR when tree becomes green via auto submit App label Oct 7, 2026
@auto-submit
auto-submit Bot merged commit bbc5975 into flutter:main Oct 7, 2026
13 checks passed
Mairramer pushed a commit to Mairramer/flutter that referenced this pull request Oct 8, 2026
flutter/packages@7660d46...54706bd

2026-10-08 [email protected] [image_picker_ios] Return an error
for undecodable image data (flutter/packages#12267)
2026-10-07 [email protected] [flutter shaders] update min flutter
version (flutter/packages#13160)
2026-10-07 [email protected] Import flutter_shaders package
(flutter/packages#12583)
2026-10-07 [email protected]
[material_ui] Migrate M3 Typography template to use new gen_defaults
(flutter/packages#13074)
2026-10-07 [email protected] Sync release-material_ui-1.6.0 to
main (flutter/packages#13149)
2026-10-07 [email protected] [pigeon] Fix native interop (JNI) calls
in minified Android release builds (flutter/packages#13151)
2026-10-06 [email protected] [material_ui] Migrate
ListTile and SwitchListTile API doc snippets to {@example} (batch 10)
(flutter/packages#13097)
2026-10-06 [email protected] Sync release-cupertino_ui-1.1.2 to
main (flutter/packages#13150)
2026-10-06 [email protected]
[material_ui] Fix `TabBar` assertion to allow `indicatorWeight: 0` with
a themed `indicator` (flutter/packages#12696)
2026-10-06 [email protected] [material_ui] Fix time picker input
validation for 24-hour locales (flutter/packages#13033)
2026-10-06 [email protected] [material_ui] Migrate
Checkbox, CheckboxListTile, Radio, and RadioListTile API doc snippets to
{@example} (batch 9) (flutter/packages#13112)
2026-10-06 [email protected] [quick_actions_android] Return null from
getLaunchAction when no activity is attached (flutter/packages#12331)

If this roll has caused a breakage, revert this CL and set the roller
to dry run mode using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC [email protected] on the revert to ensure that a
human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
flutter/packages@7660d46...54706bd

2026-10-08 [email protected] [image_picker_ios] Return an error
for undecodable image data (flutter/packages#12267)
2026-10-07 [email protected] [flutter shaders] update min flutter
version (flutter/packages#13160)
2026-10-07 [email protected] Import flutter_shaders package
(flutter/packages#12583)
2026-10-07 [email protected]
[material_ui] Migrate M3 Typography template to use new gen_defaults
(flutter/packages#13074)
2026-10-07 [email protected] Sync release-material_ui-1.6.0 to
main (flutter/packages#13149)
2026-10-07 [email protected] [pigeon] Fix native interop (JNI) calls
in minified Android release builds (flutter/packages#13151)
2026-10-06 [email protected] [material_ui] Migrate
ListTile and SwitchListTile API doc snippets to {@example} (batch 10)
(flutter/packages#13097)
2026-10-06 [email protected] Sync release-cupertino_ui-1.1.2 to
main (flutter/packages#13150)
2026-10-06 [email protected]
[material_ui] Fix `TabBar` assertion to allow `indicatorWeight: 0` with
a themed `indicator` (flutter/packages#12696)
2026-10-06 [email protected] [material_ui] Fix time picker input
validation for 24-hour locales (flutter/packages#13033)
2026-10-06 [email protected] [material_ui] Migrate
Checkbox, CheckboxListTile, Radio, and RadioListTile API doc snippets to
{@example} (batch 9) (flutter/packages#13112)
2026-10-06 [email protected] [quick_actions_android] Return null from
getLaunchAction when no activity is attached (flutter/packages#12331)

If this roll has caused a breakage, revert this CL and set the roller
to dry run mode using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC [email protected] on the revert to ensure that a
human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD p: pigeon platform-android

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[pigeon] Native interop (JNI) calls fail with ClassNotFoundException in minified Android release builds

2 participants