Skip to content

[TrimmableTypeMap] Enable JNI replacement APIs#11270

Open
simonrozsival wants to merge 1 commit intomainfrom
dev/simonrozsival/trimmable-replacements
Open

[TrimmableTypeMap] Enable JNI replacement APIs#11270
simonrozsival wants to merge 1 commit intomainfrom
dev/simonrozsival/trimmable-replacements

Conversation

@simonrozsival
Copy link
Copy Markdown
Member

@simonrozsival simonrozsival commented May 2, 2026

Summary

  • share JNI remapping replacement lookup between the native and trimmable typemap type managers
  • enable replacement type and method lookup for TrimmableTypeMapTypeManager
  • preserve remapping counts across incremental builds when remap native-code generation is skipped
  • re-enable the CoreCLRTrimmable Java.Interop replacement tests

Implementation note

The shared replacement lookup logic lives in dotnet/android as JniRemappingLookup rather than moving into the common Java.Interop type-manager base class. The base layer is in the external/Java.Interop submodule, while this lookup depends on Android-specific runtime state and native entry points (JNIEnvInit.jniRemappingInUse, _monodroid_lookup_replacement_type, and _monodroid_lookup_replacement_method_info). Keeping the helper in this repo avoids a Java.Interop/submodule change while still sharing the logic between AndroidTypeManager and TrimmableTypeMapTypeManager.

Test Plan

  • ./dotnet-local.sh test bin/TestDebug/net10.0/Xamarin.Android.Build.Tests.dll --filter "Name=Build_WithTrimmableTypeMap_RemappingCountsAreInApplicationConfig" -- NUnit.NumberOfTestWorkers=1
  • CoreCLRTrimmable Mono.Android.NET-Tests device lane: 887 total, 0 failures
  • Mono Mono.Android.NET-Tests device lane: 273 total, 0 failures
  • CoreCLR Mono.Android.NET-Tests device lane: 273 total, 0 failures

Rebased on main.

Closes #10968

Copilot AI review requested due to automatic review settings May 2, 2026 13:49
Copy link
Copy Markdown
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

This PR extends JNI remapping support to the trimmable typemap runtime path and updates the build/runtime plumbing so remapping metadata can be reused across native and trimmable type managers. It fits into the ongoing trimmable typemap work by bringing replacement-type/method handling closer to feature parity with the existing runtime path.

Changes:

  • Extract shared JNI remapping lookup logic into a new JniRemappingLookup helper and wire it into both runtime type manager implementations.
  • Pass remapping XML into native application-config generation and add a build test for preserving remapping counts across an incremental build where remap native code generation is skipped.
  • Re-enable previously excluded Java.Interop remapping tests for the trimmable typemap lane.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.RuntimeTests/NUnitInstrumentation.cs Removes trimmable-only exclusions for Java.Interop remapping tests.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets Passes remapping XML into native app-config generation.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/TrimmableTypeMapBuildTests.cs Adds incremental-build coverage for remapping counts in application config.
src/Xamarin.Android.Build.Tasks/Tasks/GenerateNativeApplicationConfigSources.cs Falls back to reading remap metadata directly when task-object state is unavailable.
src/Xamarin.Android.Build.Tasks/Tasks/GenerateJniRemappingNativeCode.cs Extracts reusable XML parsing/counting logic for remapping metadata.
src/Mono.Android/Mono.Android.csproj Includes the new shared remapping lookup source file.
src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMapTypeManager.cs Enables replacement type/method and desugar fallback lookup for trimmable typemap.
src/Mono.Android/Microsoft.Android.Runtime/ManagedTypeManager.cs Reuses the shared fallback-type helper.
src/Mono.Android/Microsoft.Android.Runtime/JniRemappingLookup.cs Introduces shared native remapping lookup helpers.
src/Mono.Android/Android.Runtime/AndroidRuntime.cs Replaces duplicated AndroidTypeManager remapping logic with shared helper calls.

Comment thread src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets Outdated
@simonrozsival simonrozsival force-pushed the dev/simonrozsival/trimmable-replacements branch from d530869 to 9eb074f Compare May 2, 2026 14:33
@simonrozsival simonrozsival changed the base branch from trimmable-typemap-startup-fixes to main May 2, 2026 14:33
Share JNI remapping lookup between native and trimmable typemap type managers and enable replacement type and method lookup for TrimmableTypeMapTypeManager.

Re-enable the CoreCLRTrimmable Java.Interop replacement tests covered by the implementation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@simonrozsival simonrozsival force-pushed the dev/simonrozsival/trimmable-replacements branch from 9eb074f to 8c1d5a2 Compare May 2, 2026 14:48
@simonrozsival
Copy link
Copy Markdown
Member Author

/review

@simonrozsival simonrozsival added copilot `copilot-cli` or other AIs were used to author this trimmable-type-map ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). labels May 2, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

Android PR Reviewer completed successfully!

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

✅ LGTM — Clean refactoring with a subtle correctness fix

Summary: Extracts shared JNI remapping logic from AndroidTypeManager into a new JniRemappingLookup helper class, reuses it across all three type managers, and enables replacement type/method lookup for TrimmableTypeMapTypeManager. Well-structured and minimal diff.

Positive callouts:

  • The shared JniRemappingLookup eliminates three copies of the desugar-type construction and provides a single point of truth
  • Nullable improvements on the interop struct fields (string? + explicit validation) are a correctness win over the old non-nullable fields that Marshal.PtrToStructure could silently return null for
  • Typo fix: "one one of""one of" in the log message
  • Test exclusion removal is consistent with the feature enablement

One item to document: The shared code appends $_CC to the first fallback type (DesugarFoo$_CC), while the old AndroidTypeManager returned just DesugarFoo. This aligns all three type managers and is likely the correct behavior for D8/R8 companion classes, but worth noting in the commit message since it's a behavioral change beyond pure refactoring.

Severity Count
💡 Suggestion 3

CI: license/cla ✅, dotnet-android (public) ✅. Internal Xamarin.Android-PR pipeline status not visible from public checks — maintainer should verify.

Generated by Android PR Reviewer for issue #11270 · ● 4.9M

? $"{jniSimpleReference.Substring (0, slash + 1)}Desugar{jniSimpleReference.Substring (slash + 1)}"
: $"Desugar{jniSimpleReference}";

var typeWithPrefix = $"{desugarType}$_CC";
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 💡 Correctness — The old AndroidTypeManager.GetStaticMethodFallbackTypesCore set typeWithPrefix = desugarType.ToString() (e.g. com/example/DesugarFoo — no $_CC), while this shared implementation appends $_CC (→ com/example/DesugarFoo$_CC).

This aligns AndroidTypeManager with ManagedTypeManager and TrimmableTypeMapTypeManager, both of which already included $_CC. Given that D8/R8 desugared companion classes use $_CC, the old AndroidTypeManager was likely the odd one out, and device tests passing confirms this works — just worth a note in the commit message that this is an intentional fix alongside the refactoring.

Rule: Commit messages omit non-obvious choices (Postmortem #69)

Comment thread src/Mono.Android/Microsoft.Android.Runtime/JniRemappingLookup.cs
Comment thread src/Mono.Android/Microsoft.Android.Runtime/JniRemappingLookup.cs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

copilot `copilot-cli` or other AIs were used to author this ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). trimmable-type-map

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[TrimmableTypeMap] Unify InTune/method replacement support between AndroidTypeManager and TrimmableTypeMapTypeManager

2 participants