Skip to content

[release/10.0.1xx] Support for exempting native libraries from JNI preload#10879

Merged
jonathanpeppers merged 6 commits intorelease/10.0.1xxfrom
dev/peppers/jnipreload-net10
Mar 5, 2026
Merged

[release/10.0.1xx] Support for exempting native libraries from JNI preload#10879
jonathanpeppers merged 6 commits intorelease/10.0.1xxfrom
dev/peppers/jnipreload-net10

Conversation

@jonathanpeppers
Copy link
Member

@jonathanpeppers jonathanpeppers commented Mar 3, 2026

Backport of: #10787
Fixes: #10617
Context: cba39dc

cba39dc introduced support for preloading of JNI native libraries at application startup. However, it appears that in some scenarios this behavior isn't desired.

This PR introduces a mechanism which allows exempting some or all (with exception of the BCL libraries) libraries from the preload mechanism.

In order to not preload any JNI libraries it's now possible to set the $(AndroidIgnoreAllJniPreload) MSBuild property to true.

It is also possible to exempt individual libraries from preload by adding their name to the AndroidNativeLibraryNoJniPreload MSBuild item group, for instance:

<ItemGroup>
  <AndroidNativeLibraryNoJniPreload Include="libMyLibrary.so" />
</ItemGroup>

Fixes: #10617
Context: cba39dc

cba39dc introduced support for preloading of JNI native libraries at
application startup.  However, it appears that in some scenarios this
behavior isn't desired.

This PR introduces a mechanism which allows exempting some or all (with
exception of the BCL libraries) libraries from the preload mechanism.

In order to not preload any JNI libraries it's now possible to set the
`$(AndroidIgnoreAllJniPreload)` MSBuild property to `true`.

It is also possible to exempt individual libraries from preload by
adding their name to the `AndroidNativeLibraryNoJniPreload` MSBuild
item group, for instance:

    <ItemGroup>
      <AndroidNativeLibraryNoJniPreload Include="libMyLibrary.so" />
    </ItemGroup>
Copilot AI review requested due to automatic review settings March 3, 2026 15:47
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an opt-out mechanism for the JNI native-library preload behavior introduced for .NET Android startup, allowing projects to exempt specific native libraries (or all of them) from being preloaded while still preserving required framework defaults.

Changes:

  • Introduces $(AndroidIgnoreAllJniPreload) and @(AndroidNativeLibraryNoJniPreload) to control JNI preload behavior from MSBuild.
  • Extends native application config generation to honor “always preload” and “never preload” library lists.
  • Adds a small native “test JNI library” plus new build/test infrastructure and NUnit tests validating preload behavior.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/native/native.targets Builds a new test JNI library as part of native runtime build orchestration.
src/native/common/test-jni-library/stub.cc Adds a minimal JNI_OnLoad implementation for preload testing.
src/native/common/test-jni-library/CMakeLists.txt CMake rules to build and place the test JNI library in test output.
src/native/CMakePresets.json.in Adds XA_TEST_OUTPUT_DIR to CMake cache variables.
src/native/CMakeLists.txt Requires XA_TEST_OUTPUT_DIR and wires the test JNI library subdirectory.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets Adds MSBuild property + item groups and passes new inputs to config generation.
src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs Adds helpers for minimum API lookup and normalizing native library names.
src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigNativeAssemblyGeneratorCLR.cs Implements “ignore/always preload” decision logic for CoreCLR config generation.
src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigNativeAssemblyGenerator.cs Implements the same “ignore/always preload” decision logic for MonoVM config generation.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/AndroidItem.cs Adds a ProjectTools item wrapper for AndroidNativeLibraryNoJniPreload.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/AndroidBuildActions.cs Adds build action constant for AndroidNativeLibraryNoJniPreload.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/EnvironmentHelper.cs Adds parsing/validation helpers for JNI preload index data from generated native sources.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest3.cs New NUnit coverage for JNI preload inclusion/exclusion scenarios.
src/Xamarin.Android.Build.Tasks/Tasks/GenerateNativeApplicationConfigSources.cs Wires MSBuild inputs into the native config generator.
build-tools/xaprepare/xaprepare/xaprepare.targets Adds placeholder replacement for @TestOutputDirectory@.
build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs Plumbs XA_TEST_OUTPUT_DIR placeholder into generated CMake presets.
build-tools/xaprepare/xaprepare/Application/Properties.Defaults.cs.in Adds KnownProperties.TestOutputDirectory default wiring.
build-tools/xaprepare/xaprepare/Application/KnownProperties.cs Adds TestOutputDirectory to known xaprepare properties.
Documentation/docs-mobile/building-apps/build-properties.md Documents AndroidIgnoreAllJniPreload.
Documentation/docs-mobile/building-apps/build-items.md Documents AndroidNativeLibraryNoJniPreload.

Copilot AI added a commit that referenced this pull request Mar 3, 2026
- Fix grammar in build-items.md: "on individual basis" → "on an individual basis"
- Fix grammar in build-properties.md: "allows to effectively disable this behavior" → "allows you to effectively disable it"
- Fix typo NativeLibrarysAlwaysJniPreload → NativeLibrariesAlwaysJniPreload

Co-authored-by: jonathanpeppers <[email protected]>
@jonathanpeppers
Copy link
Member Author

This has test failures like:

Expected the '.byte' field type in file 'C:\a_work\1\a\TestRelease\03-03_23.16.24\temp\NativeLibraryJniPreloadDefaultsWorkCoreCLR\obj\Release\android\environment.arm64-v8a.s:53': .word. File generated from 'C:\a_work\1\a\TestRelease\03-03_23.16.24\temp\NativeLibraryJniPreloadDefaultsWorkCoreCLR\obj\Release\android\environment.arm64-v8a.ll'
String lengths are both 5. Strings differ at index 1.
Expected: ".byte"
But was:  ".word"
------------^

jonathanpeppers added a commit that referenced this pull request Mar 4, 2026
Context: #10879 (review)

* Fix typos and documentation wording from PR #10879 review
* Fix grammar in build-items.md: "on individual basis" → "on an individual basis"
* Fix grammar in build-properties.md: "allows to effectively disable this behavior" → "allows you to effectively disable it"
* Fix typo NativeLibrarysAlwaysJniPreload → NativeLibrariesAlwaysJniPreload

Co-authored-by: Jonathan Peppers <[email protected]>
Copilot AI and others added 2 commits March 4, 2026 15:46
Context: #10879 (review)

* Fix typos and documentation wording from PR #10879 review
* Fix grammar in build-items.md: "on individual basis" → "on an individual basis"
* Fix grammar in build-properties.md: "allows to effectively disable this behavior" → "allows you to effectively disable it"
* Fix typo NativeLibrarysAlwaysJniPreload → NativeLibrariesAlwaysJniPreload

Co-authored-by: Jonathan Peppers <[email protected]>
EnvironmentHelper.ReadApplicationConfig only supports the MonoVM
application_config struct layout (27 fields). The CoreCLR struct
(ApplicationConfigCLR) has a different layout (20 fields, fewer bools),
causing field type mismatches when tests run with CoreCLR on this branch.

Co-authored-by: Copilot <[email protected]>
@jonathanpeppers jonathanpeppers merged commit 84a449f into release/10.0.1xx Mar 5, 2026
2 checks passed
@jonathanpeppers jonathanpeppers deleted the dev/peppers/jnipreload-net10 branch March 5, 2026 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants