Repository navigation
flutter_tools: Enable native access for Gradle - #193814
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a gradleEnvironment getter on the Java class to append the --enable-native-access=ALL-UNNAMED flag to GRADLE_OPTS when running on JDK 24 or later, and updates Gradle execution paths to use this new environment. Feedback on the changes highlights an issue where existing GRADLE_OPTS are completely omitted from the returned environment map if they already contain --enable-native-access. The reviewer suggests defensively copying the environment map, preserving the existing options, and updating the corresponding unit tests to verify this behavior.
b2604f2 to
fcd9d8f
Compare
fcd9d8f to
36336f4
Compare
JDK 24 (JEP 472) prints a warning when particular JNI/FFM methods such as `System::load` are called unless it has been granted native access via a flag or jar manifest. Gradle loads its native-platform library this way, so we get the following warnings on every Gradle invocation on JDK 24 and later: WARNING: A restricted method in java.lang.System has been called WARNING: java.lang.System::load has been called by net.rubygrapefruit.platform.internal.NativeLibraryLoader in an unnamed module (...) WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module WARNING: Restricted methods will be blocked in a future release unless native access is enabled This breaks run_debug_test_android and run_release_test in the devicelab. Gradle fixed this upstream in 8.14 by adding an `Enable-Native-Access: ALL-UNNAMED` manifest attribute to gradle-wrapper.jar and launching it from gradlew via `-jar`. However, the Gradle wrapper that flutter_tools injects into projects (bin/internal/gradle_wrapper.version) was a clone from Gradle 2.10 in 2017. Its gradlew launches it via `-classpath`, so it doesn't pick up the fix. We now invoke gradle with `--enable-native-access=ALL-UNNAMED` via GRADLE_OPTS. I verified and this flag is supported on JDK 17 (our Android minimum). This fixes the warning regardless of which wrapper a project uses. We'll want to update the injected wrapper in a followup patch. We copy the wrapper into every new project on `flutter create` and inject into any project where it's missing on `flutter build` but we never overwrite the wrapper if it exists, so we'll likely want this change regardless, or at least until that issue is solved. See: https://openjdk.org/jeps/472 See: gradle/gradle#31625
36336f4 to
95ad41a
Compare
|
Detected the If you add the The "Merge" button is also unlocked. To bypass presubmits as well as the tree status, press the GitHub "Add to Merge Queue". |
JDK 24 (JEP 472) prints a warning when particular JNI/FFM methods such as `System::load` are called unless it has been granted native access via a flag or jar manifest. Gradle loads its native-platform library this way, so we get the following warnings on every Gradle invocation on JDK 24 and later: WARNING: A restricted method in java.lang.System has been called WARNING: java.lang.System::load has been called by net.rubygrapefruit.platform.internal.NativeLibraryLoader in an unnamed module (...) WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module WARNING: Restricted methods will be blocked in a future release unless native access is enabled This breaks run_debug_test_android and run_release_test in the devicelab. Gradle fixed this upstream in 8.14 by adding an `Enable-Native-Access: ALL-UNNAMED` manifest attribute to gradle-wrapper.jar and launching it from gradlew via `-jar`. However, the Gradle wrapper that flutter_tools injects into projects (bin/internal/gradle_wrapper.version) was a clone from Gradle 2.10 in 2017. Its gradlew launches it via `-classpath`, so it doesn't pick up the fix. We now invoke gradle with `--enable-native-access=ALL-UNNAMED` via GRADLE_OPTS. I verified and this flag is supported on JDK 17 (our Android minimum). This fixes the warning regardless of which wrapper a project uses. We'll want to update the injected wrapper in a followup patch. We copy the wrapper into every new project on `flutter create` and inject into any project where it's missing on `flutter build` but we never overwrite the wrapper if it exists, so we'll likely want this change regardless, or at least until that issue is solved. See: https://openjdk.org/jeps/472 See: gradle/gradle#31625 <!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> ## Pre-launch Checklist - [X] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [X] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [X] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [X] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [X] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [X] I updated/added relevant in-code documentation (doc comments with `///`). - [X] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). - [X] I added new tests to check the change I am making, or this PR is [test-exempt]. - [X] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [X] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). 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. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [AI contribution guidelines]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [flutter/website]: https://github.com/flutter/website [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
JDK 24 (JEP 472) prints a warning when particular JNI/FFM methods such
as
System::loadare called unless it has been granted native accessvia a flag or jar manifest. Gradle loads its native-platform library
this way, so we get the following warnings on every Gradle invocation on
JDK 24 and later:
WARNING: A restricted method in java.lang.System has been called
WARNING: java.lang.System::load has been called by net.rubygrapefruit.platform.internal.NativeLibraryLoader in an unnamed module (...)
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
This breaks run_debug_test_android and run_release_test in the
devicelab.
Gradle fixed this upstream in 8.14 by adding an
Enable-Native-Access: ALL-UNNAMEDmanifest attribute to gradle-wrapper.jar and launching itfrom gradlew via
-jar. However, the Gradle wrapper that flutter_toolsinjects into projects (bin/internal/gradle_wrapper.version) was a clone
from Gradle 2.10 in 2017. Its gradlew launches it via
-classpath, soit doesn't pick up the fix.
We now invoke gradle with
--enable-native-access=ALL-UNNAMEDviaGRADLE_OPTS. I verified and this flag is supported on JDK 17 (our
Android minimum). This fixes the warning regardless of which wrapper a
project uses. We'll want to update the injected wrapper in a followup
patch.
We copy the wrapper into every new project on
flutter createandinject into any project where it's missing on
flutter buildbut wenever overwrite the wrapper if it exists, so we'll likely want this
change regardless, or at least until that issue is solved.
See: https://openjdk.org/jeps/472
See: gradle/gradle#31625
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot 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.