Skip to content

Remove legacy native typemap runtime support - #12890

Merged
simonrozsival merged 5 commits into
mainfrom
simonrozsival-remove-legacy-typemap-runtime
Oct 5, 2026
Merged

simonrozsival merged 5 commits into
mainfrom
simonrozsival-remove-legacy-typemap-runtime

Conversation

@simonrozsival

@simonrozsival simonrozsival commented Sep 23, 2026 •

Copy link
Copy Markdown
Member

Summary

Remove the obsolete native typemap and reflection-backed activation path now that the managed trimmable typemap is the supported CoreCLR/NativeAOT runtime path. This removes compatibility stubs and duplicated build/runtime machinery that no longer serve applications.

  • Remove CLR native typemap lookups, app-DSO typemap/marshal symbols, internal P/Invoke exports, reflection-backed managers, and legacy Java activation registration.
  • Use trimmable type/value managers and JNI registration unconditionally. Preserve the current JNI-remapping startup data and managed lookup implementation from main.
  • Remove legacy platform JCW generation and mono.android.jar/mono.android.dex targeting-pack entries. Binding and application Javac use java_runtime_trimmable.jar; application builds generate framework JCWs through the trimmable typemap.
  • Retain P/Invoke preservation under the renamed GenerateNativeRuntimeLinkingSources task, including the framework-only filtering fix and its multi-ABI/duplicate-assembly regression tests.
  • Update startup/config layouts and tests, remove the duplicate application-config test that blocked the previous CI build, and remove the obsolete activation-cache benchmark and empty native translation units.

The prerequisite #12889 has merged. This PR now targets main and is rebased onto 4126afa379785ba94bd951586d9e05f4658f8262, with the cleanup history consolidated as requested.

Compatibility

Third-party Java sources importing legacy platform JCW implementation classes from mono.android.jar no longer resolve those classes during standalone binding compilation. Framework JCWs are generated and compiled per application. This removal is intentional; TypeManager.Activate and reflection-backed activation are not restored. The public explicit type-registration shim is retained but throws NotSupportedException; Java peer types must use [Register].

Validation

  • dotnet test src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj -v minimal --filter 'FullyQualifiedName~TrimmableTypeMap|FullyQualifiedName~GenerateTrimmableTypeMap|FullyQualifiedName~ExtractTypeMapKeys' — passed: 31 tests, 7 skipped.
  • dotnet test src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj --no-restore -v minimal — passed: 60 tests, 7 skipped. The skipped tests require a locally built Mono.Android assembly.
  • JAVA_HOME=$(/usr/libexec/java_home) && clang++ -std=c++20 -fsyntax-only -DDEBUG -Duint=uint32_t -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -Isrc/native/clr/include -Isrc/native/common/include src/native/clr/xamarin-app-stub/application_dso_stub.cc && clang++ -std=c++20 -fsyntax-only -DRELEASE -Duint=uint32_t -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -Isrc/native/clr/include -Isrc/native/common/include src/native/clr/xamarin-app-stub/application_dso_stub.cc — passed. These are host syntax checks, not Android ABI builds; the explicit uint alias supplies the Android typedef on macOS.
  • Changed MSBuild XML parsed; managed/native startup field order agrees; git diff origin/main --check passed; no unmerged paths or conflict markers remain.
  • Full SDK/ref-pack, host integration, native multi-ABI linking, benchmark-app build, and device runtime tests were not run: this worktree has no locally built Android SDK, and full validation was explicitly deferred to CI. The rebased head still needs a successful pipeline before merge.

Pull Request
title and
description
should follow the
commit-messages.md workflow documentation, and in particular should include:

  • Useful description of why the change is necessary.
  • Links to issues fixed
  • Unit tests

Copilot AI lite review requested due to automatic review settings September 23, 2026 06:56
@simonrozsival
simonrozsival added this pull request to stack #12891 September 23, 2026 06:57

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Unresolved callable-wrapper, benchmark/AOT profile, and runtime-linking test issues remain.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

This pull request removes legacy CLR native typemap and marshal-method runtime support, making the managed trimmable typemap the CoreCLR/NativeAOT path.

Changes:

  • Removes legacy typemap, reflection activation, Java activation, and native build support.
  • Updates startup, configuration, runtime linking, packaging, tests, and documentation.
  • Retains trimmable typemap registration and runtime bookkeeping.
File Summary
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Xamarin.Android.RuntimeTests/​TestInstrumentation.cs Updates runtime test exclusions.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Xamarin.Android.Net/​TrustManagerMarshallingTests.cs Removes legacy feature gating.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Mono.Android.NET-Tests.csproj Removes obsolete activation tests.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​TrimmableTypeMapTypeManagerTests.cs Makes trimmable typemap tests unconditional.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​TrimmableTypeMapRuntimeCoverageTests.cs Removes obsolete feature checks.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​ManagedObjectProxyTests.cs Retains trimmable proxy behavior.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​JnienvTest.cs Updates activation documentation.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​JavaConvertTest.cs Removes obsolete typemap gating.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​InvokerActivationTests.cs Removes legacy gating.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​ExportTests.cs Removes legacy export-path gating.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​ConstructorActivationTests.cs Removes reflection activation tests.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​ActivationConstructorCacheTests.cs Deletes obsolete cache tests.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Android.Runtime/​JnienvArrayMarshaling.cs Removes legacy path assumptions.
src/​Xamarin.Android.Build.Tasks/​Xamarin.Android.Common.targets Replaces marshal-method wiring with runtime-linking generation.
src/​Xamarin.Android.Build.Tasks/​Utilities/​MarshalMethodsNativeAssemblyGenerator.cs Deletes the obsolete generator.
src/​Xamarin.Android.Build.Tasks/​Utilities/​ApplicationConfigNativeAssemblyGenerator.cs Removes obsolete configuration fields.
src/​Xamarin.Android.Build.Tasks/​Utilities/​ApplicationConfig.cs Updates application configuration layout.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​Utilities/​EnvironmentHelper.cs Updates configuration parsing expectations.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​Tasks/​LlvmIrGeneratorTests.cs Removes obsolete generator coverage.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​Tasks/​GenerateNativeApplicationConfigSourcesTests.cs Verifies removed configuration symbols.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​IncrementalBuildTest.cs Removes legacy typemap assertions.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​BuildTest2.cs Removes obsolete timestamp checks.
src/​Xamarin.Android.Build.Tasks/​Tasks/​PrepareAbiItems.cs Removes marshal-method handling.
src/​Xamarin.Android.Build.Tasks/​Tasks/​GenerateNativeRuntimeLinkingSources.cs Adds dedicated P/Invoke preservation generation. Nit (1 vote): add focused output coverage.
src/​Xamarin.Android.Build.Tasks/​Tasks/​GenerateNativeMarshalMethodSources.cs Deletes the obsolete task.
src/​Xamarin.Android.Build.Tasks/​Tasks/​GenerateNativeApplicationConfigSources.cs Removes obsolete startup tokens.
src/​Xamarin.Android.Build.Tasks/​Tasks/​GenerateEmptyTypemapStub.cs Deletes native typemap stub generation.
src/​Xamarin.Android.Build.Tasks/​Tasks/​BuildAppBundle.cs Removes legacy typemap bundle handling.
src/​Xamarin.Android.Build.Tasks/​Microsoft.Android.Sdk/​targets/​Microsoft.Android.Sdk.TypeMap.Trimmable.targets Removes native typemap target wiring.
src/​Xamarin.Android.Build.Tasks/​Microsoft.Android.Sdk/​targets/​Microsoft.Android.Sdk.CoreCLR.targets Removes the obsolete runtime switch.
src/​native/​nativeaot/​include/​runtime-base/​internal-pinvokes.hh Removes legacy typemap exports.
src/​native/​nativeaot/​host/​internal-pinvoke-stubs.cc Deletes legacy typemap stubs.
src/​native/​common/​runtime-base/​timing-internal.cc Removes typemap timing counters.
src/​native/​common/​include/​managed-interface.hh Updates startup arguments.
src/​native/​clr/​xamarin-app-stub/​application_dso_stub.cc Removes legacy app-DSO symbols.
src/​native/​clr/​pinvoke-override/​precompiled.cc Removes obsolete symbol resolution.
src/​native/​clr/​include/​xamarin-app.hh Updates native configuration declarations.
src/​native/​clr/​include/​runtime-base/​internal-pinvokes.hh Removes legacy declarations.
src/​native/​clr/​include/​host/​typemap.hh Deletes the legacy typemap interface.
src/​native/​clr/​include/​host/​host.hh Removes obsolete registration state.
src/​native/​clr/​host/​typemap.cc Deletes the native typemap implementation.
src/​native/​clr/​host/​internal-pinvokes-shared.cc Removes the typemap include.
src/​native/​clr/​host/​internal-pinvokes-clr.cc Removes typemap P/Invoke implementations.
src/​native/​clr/​host/​host.cc Simplifies startup and registration.
src/​native/​clr/​host/​CMakeLists.txt Removes typemap compilation.
src/​Mono.Android/​Mono.Android.csproj Removes the reflection value manager. Critical (1 vote): the default XAJavaInterop1 callable-wrapper path still references mono.android.TypeManager.Activate.
src/​Mono.Android/​Microsoft.Android.Runtime/​TrimmableTypeMapValueManager.cs Updates trimmable activation errors.
src/​Mono.Android/​Microsoft.Android.Runtime/​TrimmableTypeMap.cs Simplifies initialization diagnostics.
src/​Mono.Android/​Microsoft.Android.Runtime/​RuntimeFeature.cs Removes obsolete feature switches.
src/​Mono.Android/​Microsoft.Android.Runtime/​JavaMarshalValueManager.cs Deletes reflection-backed value management.
src/​Mono.Android/​java/​mono/​android/​TypeManager.java Deletes legacy Java activation registration.
src/​Mono.Android/​Java.Interop/​TypeManager.cs Removes legacy activation and native typemap lookup. Moderate (1 vote): update or remove the benchmark resolving deleted CreateProxy; regenerate and commit both default AOT profile artifacts containing stale legacy entries.
src/​Mono.Android/​Java.Interop/​JavaConvert.cs Makes trimmable conversion paths unconditional.
src/​Mono.Android/​Android.Runtime/​RuntimeNativeMethods.cs Removes legacy typemap P/Invokes.
src/​Mono.Android/​Android.Runtime/​JNIEnvInit.cs Makes trimmable managers and registration unconditional.
src/​Mono.Android/​Android.Runtime/​JNIEnv.cs Removes native typemap lookup.
src/​Mono.Android/​Android.Runtime/​AndroidRuntime.cs Removes reflection-backed runtime managers.
src/​Microsoft.Android.Sdk.ILLink/​PreserveLists/​Mono.Android.xml Removes obsolete preservation entries.
src/​Microsoft.Android.Runtime.NativeAOT/​Java.Interop/​JreRuntime.cs Uses trimmable value management.
src/​Microsoft.Android.Runtime.NativeAOT/​Android.Runtime.NativeAOT/​JavaInteropRuntime.cs Updates manager initialization.
Documentation/​guides/​internals/​JavaJNI_Interop.md Marks the legacy pipeline historical.
Documentation/​guides/​app-bundles.md Removes legacy typemap bundle entries.

@@ -367,7 +367,6 @@
<Compile Include="Microsoft.Android.Runtime\ITypeMap.cs" />
<Compile Include="Microsoft.Android.Runtime\JniRemappingLookup.cs" />
<Compile Include="Microsoft.Android.Runtime\JavaMarshalRegisteredPeers.cs" />
@simonrozsival
simonrozsival force-pushed the simonrozsival-remove-legacy-typemap-runtime branch from 20e8350 to cfeefee Compare September 23, 2026 07:36
@simonrozsival
simonrozsival force-pushed the simonrozsival-remove-legacy-typemap-runtime branch from 76d8591 to f38be86 Compare September 23, 2026 09:10
@simonrozsival
simonrozsival force-pushed the simonrozsival-remove-legacy-typemap-runtime branch 2 times, most recently from e74f5de to bd99358 Compare September 23, 2026 09:39
@simonrozsival
simonrozsival force-pushed the simonrozsival-remove-legacy-typemap-runtime branch from 62d9032 to 2fccae2 Compare September 23, 2026 12:22
@simonrozsival
simonrozsival force-pushed the simonrozsival-remove-legacy-typemap-runtime branch from 2fccae2 to 01bb1a7 Compare September 23, 2026 14:28
@simonrozsival
simonrozsival force-pushed the simonrozsival-remove-legacy-typemap-runtime branch from 01bb1a7 to 046c6e6 Compare September 24, 2026 05:58
@simonrozsival
simonrozsival force-pushed the simonrozsival-remove-legacy-typemap-runtime branch 2 times, most recently from 57df1fc to 710fbc0 Compare September 24, 2026 12:25
@simonrozsival
simonrozsival force-pushed the simonrozsival-remove-legacy-typemap-runtime branch from 710fbc0 to e03abb7 Compare September 24, 2026 14:08
Base automatically changed from simonrozsival-remove-llvm-ir-typemap-build-pipeline to main October 3, 2026 20:07
simonrozsival added a commit that referenced this pull request Oct 3, 2026
Stacked on #12887; **base: `simonrozsival-default-trimmable-typemap`**.

## Summary
- Remove the obsolete llvm-ir typemap targets and generators, native typemap output, marshal-method assembly rewriting, legacy Java-stub tasks, and dead after-link chain. Keep shared application configuration, NativeAOT bootstrap, Java remapping, and the empty native symbols still required until #12890.
- Preserve the trimmable build behavior previously mixed into #12887 as six separate, scoped commits: CoreCLR additional process providers; pre-ILLink abstract-method repair on project-local assembly copies; effective-RID post-trim JCW selection and Proguard inputs; typemap assembly metadata and FastDeploy preference for linked/ReadyToRun DLLs; Java-library categorization before nested D8; and the deserialization callback trimmer root.
- Keep the shared post-ILLink steps, `LinkDescription`, `LinkerDumpDependencies`, and incremental file tracking. Reject `AndroidEnableMarshalMethods=true` with `XA1049` rather than accepting an unsupported path.

The default property and `XA4265` validation remain in the small bottom PR. JVM-only test cleanup is in #12894; this PR does not replay the old bottom branch's broad CI and test-fixture changes.

## Validation
- 1,025 standalone trimmable typemap tests and 11 focused build-task tests passed (7 fixture-dependent cases skipped); the FastDeploy task project built without warnings or errors.
- Changed XML and the target dependency graph were checked, as was the diff.
- Full build-task, host, and device integration tests could not run here without the built in-tree Android SDK and generated `generator.dll`; CI must validate the combined path.
simonrozsival and others added 2 commits October 3, 2026 22:15
Consolidate the runtime cleanup onto the merged typemap pipeline. Preserve the new JNI remapping startup data, filter framework P/Invokes before ABI indexing, and keep the runtime-linking regression tests. Remove the duplicated application-config test that blocked CI.

Co-authored-by: Copilot App <[email protected]>
Remove the obsolete activation-cache benchmark and now-empty native P/Invoke translation units. Update newly merged peer-identity, JNI-remapping, and incremental-build tests to use the unconditional trimmable runtime and the reduced application config.

Co-authored-by: Copilot App <[email protected]>
@simonrozsival
simonrozsival force-pushed the simonrozsival-remove-legacy-typemap-runtime branch from 6a51f54 to 40bec60 Compare October 3, 2026 20:20
Remove the no-op Runtime.register JNI shim, obsolete startup fields and state, unused config tokens and remapping counters, and their build-time plumbing. Preserve live exception propagation, class-name lookup, and JNI remapping data.

Update the config parser and regression coverage, and remove the dead marshal compile switch, trace enums, TimeZone cache, test matrix, and XA0002 resources.

Co-authored-by: Copilot App <[email protected]>
@simonrozsival

Copy link
Copy Markdown
Member Author

@dalexsoto review

Retain the GC bridge bootstrap in CoreCLR and NativeAOT startup, assert its presence after linking, and refresh Release APK size baselines for the legacy runtime removal.

Co-authored-by: Copilot App <[email protected]>

@dalexsoto dalexsoto left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The complete 87-file/current-hunk review, separate material replacement/integration pass and final independent sweep leave one current test blocker. The GC-bridge initialization and unsupported-JVM-fixture corrections are fixed in current source; the intentional legacy typemap/platform-JCW compatibility removal remains accepted.

Make the R8 exception-peer assertion runtime-specific (BuildTest2.cs:1609-1621). BuildProguardEnabledProject requires Landroid/runtime/JavaProxyThrowable; for both runtimes. After removing mono.android.jar, NativeAOT retains application/framework JCWs according to ILC reachability; this app does not retain that otherwise-unused platform peer. Its supported exception dispatch instead uses net/dot/jni/internal/JavaProxyThrowable, supplied by the trimmable runtime jar and covered by the net.dot.jni.** keep rule.

Actual existing CI build1622337 fails this exact DEX assertion in both NativeAOT variants: run44954574/result100148 (android-arm64) and run44954602/result100173 (emptyRID). CI uses merge 36f92ba, not the exact head tree; the failed test is byte-identical to this head and the relevant runtime/retention sources were reconciled. These are source-related test expectations, not infrastructure failures.

Keep the CoreCLR assertion and validate NativeAOT's actual exception peer in its branch. Restoring the legacy jar or activation path is unnecessary. No additional high-confidence blocker remained. This combines immutable source/contract proof and observed existing CI results, not locally executed builds/device tests or a green-pipeline claim.

Keep the Android.Runtime proxy assertion for CoreCLR and check the Java.Interop proxy used by NativeAOT. Removing the legacy platform JAR allows R8 to discard the unused platform proxy in NativeAOT apps.

Co-authored-by: Copilot App <[email protected]>
@simonrozsival

Copy link
Copy Markdown
Member Author

@dalexsoto Addressed in a61493e.

I reproduced both NativeAOT failures locally before changing the test; both CoreCLR controls passed. The NativeAOT build generates the platform android.runtime.JavaProxyThrowable source, but its ILC-derived keep rules do not retain that unused peer. Its actual DEX contains net.dot.jni.internal.JavaProxyThrowable, present in both the generated keep rules and the unchanged net.dot.jni.** runtime keep rule. Removing the legacy platform JAR exposes that distinction.

The runtime source confirms it: NativeAOT creates JreRuntime, which inherits JniRuntime.RaisePendingException → JniEnvironment.Exceptions.Throw → Java.Interop's proxy. CoreCLR overrides RaisePendingException to create Android.Runtime's platform proxy.

BuildProguardEnabledProject now checks the correct exception peer in each runtime branch. The CoreCLR assertion and all provider/other retention assertions remain; no legacy JAR or activation path was restored.

Local validation on macOS arm64:

./dotnet-local.sh build src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj -c Release --no-restore -v minimal

Passed, 0 errors (38 existing warnings).

DOTNET_ROLL_FORWARD=Major ./dotnet-local.sh test bin/TestRelease/net10.0/Xamarin.Android.Build.Tests.dll --filter 'Name~BuildProguardEnabledProject|Name~NativeAotKeepsRuntimeAcwJavaTypesUnderR8|Name~CoreClrTrimmableTypeMap_PackagesJavaProxyThrowable' -v minimal --logger 'trx;LogFileName=nativeaot-proguard-after.trx' --results-directory bin/TestRelease/TestResults

6 passed, 0 failed: all four runtime/RID cases, NativeAOT runtime-ACW retention under R8, and the CoreCLR throwable-constructor check.

PATH="$PWD/bin/Release/dotnet:$PATH" DOTNET_ROLL_FORWARD=Major ./dotnet-local.sh test bin/TestRelease/MSBuildDeviceIntegration/net10.0/MSBuildDeviceIntegration.dll --filter 'Name~EnsureUncaughtExceptionWorks' -v minimal --logger 'trx;LogFileName=nativeaot-exception-dispatch.trx' --results-directory bin/TestRelease/TestResults

2 passed, 0 failed on the arm64 emulator: Java → managed → Java exception propagation and the Java catch/finally sequence work for CoreCLR and NativeAOT.

These are local results; the new head still needs CI validation.

@dalexsoto dalexsoto left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The complete current 87-file/253-hunk review, separate supported-runtime/build/packaging integration pass and final independent sweep leave no high-confidence blocker. The GC-bridge initialization and unsupported-fixture fixes remain intact. The R8 test now checks Java.Interop's actual NativeAOT exception peer while preserving CoreCLR's platform peer and both providers; the current dispatch, runtime Jar and retention contracts agree. The intentional legacy typemap/reflection/platform-JCW removal remains accepted.

This is source-level review, not independently executed local/device validation or a green-pipeline claim; CI was still in progress at the latest snapshot.

@simonrozsival
simonrozsival merged commit 7ef934d into main Oct 5, 2026
44 checks passed
@simonrozsival
simonrozsival deleted the simonrozsival-remove-legacy-typemap-runtime branch October 5, 2026 06:37
simonrozsival added a commit that referenced this pull request Oct 7, 2026
…13024)

The trimmable type map is the sole supported implementation after #12889 and #12890. `$(AndroidTypeMapImplementation)` no longer selects between working implementations, but still adds conditions, defaults, validation, and redundant test parameters throughout the build.

Remove the selector rather than preserving an extension point for a hypothetical future implementation:

- Remove its defaults, property-cache entry, target/import conditions, and UCO binding prerequisite checks. Always select `java_runtime_trimmable.jar`; retain application/library, runtime, trimming, design-time, and inner-RID guards.
- Simplify constant typemap test parameters while retaining the CoreCLR/NativeAOT matrices. Make the callback fixture reference and callback/manifest test sources unconditional, and remove the obsolete `CoreCLRTrimmable` test flavor default.
- Replace selector-validation tests with coverage that applications still generate typemaps and libraries do not, regardless of obsolete assignments. Add standalone R8 target regression coverage for omitted, empty, `llvm-ir`, `trimmable`, and unknown values.
- Retire XA4267, remove selector wording from XA4265/XA4266, and update build-property documentation, contributor guidance, and test commands. Generated non-English localization files are unchanged.

**Compatibility:** Existing assignments to `$(AndroidTypeMapImplementation)` are now ignored, including previously rejected `llvm-ir`, unknown, and explicitly empty global values. The documentation retains an obsolete-property notice so users can remove those assignments.

No linked issue; this follows the legacy typemap removal PRs and the redundant test-lane removal in #13011.

## Validation

After merging `main` and resolving review feedback, expanded standalone coverage: **98 passed, 7 skipped, 0 failed**. This includes the obsolete-property regression cases and the new transferred-reference activation tests from `main`. The skipped tests require locally built Android assemblies. NativeAOT target cases were exercised with the NDK tools.

```bash
dotnet test src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj -v minimal -p:_NativeAotLlvmReadObjPath=/Users/simon/android-toolchain/ndk/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-readobj --filter 'FullyQualifiedName~TypeMapProguardTargetsTests|FullyQualifiedName~GenerateTrimmableTypeMapTests|FullyQualifiedName~TrimmableTypeMapIncrementalTests|FullyQualifiedName~TrimmableTypeMapManifestAliasTests|FullyQualifiedName~TrimmableTypeMapRidCallbackTests|FullyQualifiedName~ExtractTypeMapKeysFromAssembliesTests|FullyQualifiedName~ExtractTypeMapKeysFromNativeAotObjectTests|FullyQualifiedName~GenerateTypeMapProguardConfigurationTests|FullyQualifiedName~GenerateTypeMapMemberProguardConfigurationTests|FullyQualifiedName~TransferredReferenceActivationTests'
```

The earlier focused obsolete-property regression run passed **all 5 cases**:

```bash
dotnet test src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj -v minimal --filter 'Name~AssemblyTargetConsumesLinkedMetadataAcrossRidsAndEmptyStubs'
```

`git diff --cached --check` passed. All 12 modified XML files parsed successfully. Merge-resolution checks confirmed all 84 `Compile` items and five `ProjectReference` items from `main` are preserved; the five formerly gated runtime source entries (including the new `TransferredReferenceTests`) and callback project reference are unconditional. The initial implementation also verified unchanged target ordering/incremental inputs and outputs, preservation of non-selector guards and 169 explicit test cases.

**Full SDK validation is blocked:** Retrying `make prepare && make all` after the merge failed during preparation with NU1102 because the configured feeds cannot supply `Microsoft.NETCore.App.Ref` version `10.0.13`; `make all` did not run. Earlier attempts using `make prepare MSBUILD_ARGS=-p:DotNetPreviewTool=/usr/local/share/dotnet/dotnet` and `dotnet build src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj -v minimal -p:DotNetStableTargetFramework=net11.0` failed for the same dependency. Full-build application/library regressions, device integration tests, and on-device runtime tests have therefore not run locally.

----

Pull Request
[title](https://github.com/dotnet/android/blob/main/Documentation/workflow/commit-messages.md#commit-summary) and
[description](https://github.com/dotnet/android/blob/main/Documentation/workflow/commit-messages.md#commit-body)
should follow the
[`commit-messages.md` workflow documentation](https://github.com/dotnet/android/blob/main/Documentation/workflow/commit-messages.md), and in particular should include:

- [x] Useful description of *why the change is necessary*.
- [ ] Links to issues fixed
- [x] Unit tests
simonrozsival added a commit that referenced this pull request Oct 9, 2026
## Summary

Retire the experimental `JavaInterop1` binding/Java Callable Wrapper (JCW) generation paths and their obsolete runtime infrastructure. Keep **`XAJavaInterop1`** as the supported binding/legacy JCW shape, and keep the trimmable typemap's Java generator as a **separate, targetless pipeline**.

This implements the Android cleanup tracked by [#11727](#11727), including removal of `ManagedPeer`, `GCUserPeerable`, the handwritten Java.Interop proxies, and `java-interop.jar`. Preserve managed-object transport and consolidate exception transport onto the existing generated `Android.Runtime.JavaProxyThrowable` for both CoreCLR and NativeAOT.

The branch is rebased onto `main` commit `058e71b5867c63fd92a00ae545c7899f2b60ed6e`, including the Android test relocation in [#13019](#13019) and the retained-typemap R8 pipeline in [#12829](#12829). This remains a draft; local validation is documented below, not presented as a claim that CI is green. No tracking issue is auto-closed.

## Android compatibility: why this can be removed

### Normal .NET for Android and .NET MAUI codegen is unchanged

The standard .NET for Android application/binding pipeline, also used by .NET MAUI Android applications, uses **`XAJavaInterop1`**, not the experimental `JavaInterop1` shape. This PR preserves that supported code-generation path.

NativeAOT previously selected `JavaInterop1` for its JCWs. Android NativeAOT has remained an experimental runtime option, documented by [XA1040](https://github.com/dotnet/android/blob/e2230e9d5d/Documentation/docs-mobile/messages/xa1040.md), and **merged [#12133](#12133 already switched it to `XAJavaInterop1` and unified the Android GC bridge around `mono.android.IGCUserPeer`. Before this PoC, the SDK defaults already selected `XAJavaInterop1` for both `AndroidCodegenTarget` and `_AndroidJcwCodegenTarget`.

The old `JavaInterop1` option was explicitly documented as **experimental** in the [build-property documentation](https://github.com/dotnet/android/blob/e2230e9d5d/Documentation/docs-mobile/building-apps/build-properties.md#androidcodegentarget). Its historical NativeAOT-default description is stale after #12133 and is corrected here.

The supported Android paths have already migrated:

- [#12133](#12133) migrated NativeAOT's JCW shape and GC bridge.
- [#12152](#12152) removed the built-in proxies' dependency on `ManagedPeer` for native registration.
- [#12887](#12887) made the trimmable typemap the default and rejected legacy typemap selection.
- [#12890](#12890) removed the old native typemap/reflection-backed Android activation path.
- [#13018](#13018) removed the remaining reflection-backed JNI managers. Current Android runtimes use the trimmable managers.

All these prerequisites are merged. No supported current Android code-generation or activation path needs `ManagedPeer.construct` or JavaInterop1-style wrappers. Some obsolete helpers were still packaged or initialized through common runtime plumbing; removing that leftover machinery does not remove the codegen used by normal .NET for Android or .NET MAUI apps.

### Each removed runtime component has an Android replacement or no supported consumer

| Removed component | Android justification / replacement |
|---|---|
| `Java.Interop.ManagedPeer` and `net.dot.jni.ManagedPeer` | No supported generated JCW shape needs their reflective constructor/native-registration trampoline after #12133 and the trimmable migration. Remove initialization, feature-switch plumbing, built-in mappings, scanner exemptions, suppressions, and ProGuard retention together. |
| `net.dot.jni.GCUserPeerable`, `jiAddManagedReference`, and `jiClearManagedReferences` | Android GC processing uses `mono.android.IGCUserPeer`. Migrate surviving handwritten Android fixtures to that contract; remove the obsolete runtime field, host/managed marker lookups, and matching managed/native initialization-struct field. Android GC/reference tracking is retained. |
| `Java.Interop.JavaProxyObject` and `net.dot.jni.internal.JavaProxyObject` | No consumer remains in the active Android value-manager path. Keep the existing `TrimmableJavaProxyObject` and its Java identity semantics; the removed handwritten class is not its implementation. |
| `Java.Interop.JavaProxyThrowable` and `net.dot.jni.internal.JavaProxyThrowable` | NativeAOT still used this exception-transport path, so it is **replaced before removal**, not simply deleted as unused. Route NativeAOT through the existing generated `Android.Runtime.JavaProxyThrowable`, as CoreCLR already did. No third `TrimmableJavaProxyThrowable` is introduced. |
| `java-interop.jar` | After deleting its obsolete helpers, it has no remaining supported Android runtime content. Remove build/install wiring and references. Android fixture compilation references `android.jar` and `java_runtime.jar` instead. |
| Handwritten `SelfRegistration`, `TestType`, `TestTypeTests`, and the old Java.Interop `CallNonvirtualDerived2` fixture | These were unused or depended on the retired Java-to-managed constructor activation path; the obsolete test class was already excluded by capability guards. Keep the separate live generated-binding class with the same short name and preserve supported constructor/dispatch/exception scenarios. |

The removed managed runtime implementation types are internal. Public `JavaObject`, `JavaException`, `JniPeerMembers`, and `IJavaPeerable` remain. The existing Android throwable and managed-object proxy implementations also remain. The explicit public configuration-property removal below is documented separately.

### Supported construction and registration remain intact

Ordinary managed-to-Java construction does not need `ManagedPeer`: `JavaObject` allocates the Java object, associates the managed peer, then invokes the Java constructor through `StartCreateInstance`/`FinishCreateInstance`.

For Java-to-managed activation and callbacks, supported Android types use generated Android/trimmable dispatch and registration. The trimmable generator registers natives through `TrimmableTypeMap.RegisterNativeMethods()` / `mono.android.Runtime.registerNatives(Class)`, independently of either removed `JavaInterop1` enum value. No reflective compatibility shim is reintroduced.

## Implementation changes

### Generator and build surface

- Remove `CodeGenerationTarget.JavaInterop1`, `JavaPeerStyle.JavaInterop1`, their generator/source-writer/JCW branches, the `javainterop1` CLI selector, and unused SDK configuration selecting that shape.
- Preserve `XAJavaInterop1` output and the independent trimmable pipeline. This is not a rename of the typemap generator to another `AndroidCodegenTarget` value.
- Reject retired `AndroidCodegenTarget` values with actionable **XA4232** diagnostics for application and library builds. Retain the existing **XA4240** rejection for retired `_AndroidJcwCodegenTarget` values, and test rejection rather than silently falling back.
- Remove retired expected-output trees and conditional `JAVA_INTEROP1`/`TODO_JAVA_INTEROP1`/`TryJavaInterop1` scaffolding. Move shared XML inputs/support sources from `expected.ji` into `TestInputs` so supported tests do not depend on a retired baseline directory.
- Update directly related build-property/error documentation and the test catalog.

### Shared Android exception handling

Add a shared internal `AndroidExceptionManager` and make CoreCLR and NativeAOT delegate wrapping/unwrapping to it. `JniEnvironment.Exceptions.Throw(Exception)` dispatches to the active runtime's `RaisePendingException` implementation.

The Android implementation wraps ordinary managed exceptions in the generated Android proxy, recognizes existing Java exception peers, and returns the original managed exception when its proxy returns through JNI or appears as a Java cause. Typed value-manager lookup distinguishes peer from unboxed exception: requests for `Java.Lang.Throwable`, `JavaException`, or `IJavaPeerable` return the Java peer; requests for compatible managed exception/object types return the original managed value.

Shared lookup releases incoming JNI references in an option-aware `finally`, on successful and failing extraction paths. Borrowed references remain valid; transferred local/global references are released exactly once. Permanent regressions cover typed lookup and four extraction failure stages across all three ownership modes.

The base `JniRuntime.RaisePendingException` still throws an existing `JavaException`. Android overrides supply managed-exception wrapping; a runtime without an implementation receives an explicit `NotSupportedException` instead of silently depending on a deleted proxy. The exception contract is documented.

### Finish removing associated scaffolding

- **R8 roots:** remove eight keep entries for the four retired Java helpers from `proguard_typemap.cfg` and `proguard_typemap_coreclr.cfg`, along with their misleading comments. Preserve Android bootstrap/GC roots. Update the existing R8 response tests to assert that neither retained-typemap mode emits retired-helper roots.
- **Registration metadata:** retain `JniAddNativeMethodRegistrationAttribute` with warning-only `[Obsolete]`, explicitly stating that it has no effect. Delete the unused public `JniRuntime.CreationOptions.JniAddNativeMethodRegistrationAttributePresent` property rather than retaining a no-op setting; record its accessor removals with `*REMOVED*` entries in `PublicAPI.Unshipped.txt`. Its unread internal copy and Android assignment are also gone.
- **Dead scanner/diagnostic code:** remove the attribute-specific metadata pre-scan/flag, unused checker and commented rejection block, and unused **XA4251** logger plumbing. Remove XA4251 from the English resource and its designer accessor. Other live metadata matching helpers remain.
- **AOT profile:** delete the unreferenced `custom.aotprofile` ProjectTools fixture containing removed `ManagedPeer.Init`/`.cctor` records. Source searches found no direct or dynamically enumerated profile consumer; the resource wildcard was its remaining inclusion path. Rebuilt-assembly inspection confirms it is no longer embedded. Do not regenerate a profile for retired functionality.

No non-English `.resx` or generated localization files are modified.

### Reconciliation with current main

Preserve #13019's local C# compilation and Java fixture glob under `tests/Mono.Android-Tests/Java.Interop-Tests/`, including its `AndroidJavaSource` exclusion to prevent duplicate compilation. Apply fixture deletions and `IGCUserPeer` conversions at the relocated paths; do not restore the external test source directory/globs. Keep the Android-specific `GetThis` implementation and comments.

Preserve upstream native host startup/logging and assembly-store changes. Preserve #12829's retained-key R8 pipeline; do not reintroduce DGML generation or alter new targets to accommodate the old validation setup.

## Android coverage preserved and added

- **All 23** former `expected.ji` integration scenarios retain XA baselines and active runners. Restore `Java_Lang_Object` against XA and refresh its previously unused snapshot. Shared inputs are migrated, not deleted.
- Retained Common/XA/NRT baselines cover 71 of 72 retired unit-baseline names; the unmatched `WriteInterfaceFields` snapshot already had no test consumer before cleanup.
- Existing Android `ConstructorActivationTests`, generated-binding `BindingTests.VirtualMethodBinding`, and `ExceptionTests.ManagedJavaManaged_FinallyExecuted` retain activation, multi-level dispatch, and managed/Java/managed exceptions with Java `finally` execution.
- Port array-mutation scenarios to a real Java fixture and generated XA bindings: `int[]`, `int[][]`, `int[][][]`, with null/invalid/success results and complete copy-back assertions. These exercise generated `JNIEnv.CopyArray`, not handwritten replacement marshalling.
- Add GC-peer contract coverage for surviving handwritten fixtures and the active managed-object proxy, invoking actual add/clear operations.
- Add/strengthen exception identity, causes, unregistered throwable, Java-visible stack trace, callback identity, typed lookup, and throwable-array coverage.
- Add **17 permanent regressions** for typed/unboxed lookup and transferred-reference failures. All 17 passed on both runtimes after rebase, without skips.
- Require the generated Android throwable in both runtimes' packaging/R8 tests and reject old proxies. Existing R8 response tests now also reject all four obsolete helper roots in both rule modes.

Most deletions are retired generated baselines and duplicate scaffolding, not supported Android runtime scenarios.

## Local validation

### Latest property/scanner/resource/profile cleanup

The following checks ran against the final cleanup sources with a rebuilt Debug Android SDK. These are distinct from the earlier complete post-rebase device runs below.

| Command/check | Result |
|---|---|
| `bin/Debug/dotnet/dotnet build external/Java.Interop/src/Java.Interop/Java.Interop.csproj -c Debug -v quiet -p:JavaCPath=/usr/bin/javac -p:JarPath=/usr/bin/jar` and the same command with `-c Release` | **Passed**, 0 warnings/errors in both configurations; public API removal records accepted. |
| `bin/Debug/dotnet/dotnet build src/Mono.Android/Mono.Android.csproj -c Debug -v quiet` | **Passed**, 0 errors; no remaining source consumer of the deleted option. |
| `bin/Debug/dotnet/dotnet build build-tools/scripts/Prepare.proj -t:BuildDotNet -c Debug -v quiet` with Debug workload roots | **Passed**, 0 errors; existing warnings. An initial overlapping scanner-test build locked a shared intermediate DLL (MSB4018); the SDK retry passed after that build completed, without source workarounds. |
| `bin/Debug/dotnet/dotnet test src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj -c Debug -v quiet --filter 'FullyQualifiedName~TrimmableTypeMap\|FullyQualifiedName~TypeMapProguardTargetsTests'` | **73 passed, 4 existing prerequisite skips, 0 failures**. The filter uses the literal `|` OR operator. |
| `bin/Debug/dotnet/dotnet build src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj -c Debug -v quiet` | **Passed**, 0 errors; rebuilt task/resource and ProjectTools consumers. |
| Metadata inspection of rebuilt Debug/Release `Java.Interop.dll` and `Xamarin.ProjectTools.dll` | **Passed**: option absent from both configurations, attribute retained with warning-only `Obsolete`, deleted profile absent from manifest resources. |
| English resource XML parse, active source/reference checks, `git diff --check` | **Passed**; obsolete roots/diagnostic machinery absent and localization boundaries preserved. |

This combined invocation **passed 36 cases with 0 skips/failures**: all R8 task cases, both retained-rule R8 integration modes, CoreCLR/NativeAOT throwable packaging, and ProGuard builds.

```sh
bin/Debug/dotnet/dotnet test bin/TestDebug/net10.0/Xamarin.Android.Build.Tests.dll \
  --filter 'FullyQualifiedName~R8Tests|Name~RetainedTypeMapRulesDriveR8|Name~TrimmableTypeMap_PackagesAndroidJavaProxyThrowable|Name~BuildProguardEnabledProject' \
  -v quiet
```

### Full post-rebase runtime/device validation

Both configuration-specific SDKs were rebuilt after the rebase using `Prepare.proj -t:BuildDotNet -c Debug/Release`. Set matching `DOTNETSDK_WORKLOAD_MANIFEST_ROOTS="$PWD/bin/<configuration>/lib/sdk-manifests"` and `DOTNETSDK_WORKLOAD_PACK_ROOTS="$PWD/bin/<configuration>/lib"`, with `ANDROID_SERIAL=emulator-5554`. Explicit SDK paths avoid `dotnet-local.sh` preferring an existing Release SDK over Debug.

```sh
# Debug workload roots, from repository root.
bin/Debug/dotnet/dotnet build -t:Install -c Debug \
  tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj \
  -p:AndroidTypeMapImplementation=trimmable -p:AndroidRuntime=CoreCLR \
  -p:RuntimeIdentifier=android-arm64 '-p:AdbTarget=-s emulator-5554' -v quiet
(
  cd tests/Mono.Android-Tests/Mono.Android-Tests
  ../../../bin/Debug/dotnet/dotnet test Mono.Android.NET-Tests.csproj \
    --no-build -c Debug --device emulator-5554 --report-trx \
    --results-directory ../../../bin/TestDebug/RebaseResults \
    -p:AndroidTypeMapImplementation=trimmable -p:AndroidRuntime=CoreCLR \
    -p:RuntimeIdentifier=android-arm64 '-p:AdbTarget=-s emulator-5554'
)
```

**Passed: 897 CoreCLR tests, 7 existing skips, 0 failures**, including relocated JNI tests and all 17 permanent regressions. This full CoreCLR suite also passed again during the subsequent deprecation step (results under `ObsoleteRegistrationResults`), before the latest host-only scanner/root/profile cleanup.

```sh
# Release workload roots, from repository root.
bin/Release/dotnet/dotnet build -t:Install -c Release \
  tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj \
  -m:1 -p:BuildInParallel=false \
  -p:AndroidTypeMapImplementation=trimmable -p:AndroidRuntime=NativeAOT \
  -p:PublishAot=true -p:RuntimeIdentifier=android-arm64 \
  -p:_AndroidEnableTypemapR8Trimming=true -p:_SkipNdkResolution=false \
  '-p:AdbTarget=-s emulator-5554' -v quiet
(
  cd tests/Mono.Android-Tests/Mono.Android-Tests
  ../../../bin/Release/dotnet/dotnet test Mono.Android.NET-Tests.csproj \
    --no-build -c Release --device emulator-5554 --report-trx \
    --results-directory ../../../bin/TestRelease/RebaseResults \
    -p:BuildInParallel=false \
    -p:AndroidTypeMapImplementation=trimmable -p:AndroidRuntime=NativeAOT \
    -p:PublishAot=true -p:RuntimeIdentifier=android-arm64 \
    -p:_AndroidEnableTypemapR8Trimming=true -p:_SkipNdkResolution=false \
    '-p:AdbTarget=-s emulator-5554'
)
```

**Passed: 842 NativeAOT tests, 7 existing skips, 0 failures**, including all 17 regressions. The current retained-key R8 pipeline produced **328 retained keys**, including the Android throwable; `r8.json` confirmed shrinking enabled. No old native-output-path override or DGML workaround was used, and no trimming/R8/AOT was disabled. Build-only `-m:1` is omitted from the test invocation because MTP rejects the forwarded `--m` option.

These complete device suites were not rerun for the latest scanner/resource/profile-only additions; the latest 36-case host integration run builds and verifies both CoreCLR and NativeAOT packages against the updated resources.

### Other post-rebase tooling and generated-XA coverage

| Command/check | Recorded result |
|---|---|
| `bin/Debug/dotnet/dotnet test external/Java.Interop/tests/generator-Tests/generator-Tests.csproj -c Debug -v quiet -p:JavaCPath=/usr/bin/javac -p:JarPath=/usr/bin/jar` | **478 passed**, 0 skipped. |
| Same command shape for `external/Java.Interop/tests/Java.Interop.Tools.JavaCallableWrappers-Tests/Java.Interop.Tools.JavaCallableWrappers-Tests.csproj` | **50 passed**, 0 skipped. |
| Same command shape for `external/Java.Interop/tests/Java.Interop.Tools.Generator-Tests/Java.Interop.Tools.Generator-Tests.csproj` | **18 passed**, 0 skipped. |
| `bin/Debug/dotnet/dotnet test src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj -c Debug -v quiet --filter FullyQualifiedName~GenerateTrimmableTypeMapTests` | **16 passed**, 0 skipped after rebase; superseded by the broader latest 73-case run. |
| `bin/Debug/dotnet/dotnet test bin/TestDebug/net10.0/Xamarin.Android.Build.Tests.dll --filter 'FullyQualifiedName~InvalidConfigTests\|Name~TrimmableTypeMap_PackagesAndroidJavaProxyThrowable\|Name~BuildProguardEnabledProject\|Name~RetainedTypeMapRulesDriveR8' -v quiet` | **58 passed**, 0 skips/failures after rebase; latest related resource/packaging coverage is the 36-case run above. |

Generated-XA JCW device commands used `tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/Xamarin.Android.JcwGen-Tests.csproj` with `build -t:Install`, then matching `test --no-build` from its directory, `--device emulator-5554 --report-trx`, and configuration-specific workload roots:

- **CoreCLR:** `-c Debug -p:AndroidTypeMapImplementation=trimmable -p:AndroidRuntime=CoreCLR -p:AndroidCodegenTarget=XAJavaInterop1 -p:RuntimeIdentifier=android-arm64 '-p:AdbTarget=-s emulator-5554'` — **46 passed, 2 existing explicit skips**, including arrays, dispatch, and managed/Java/finally exceptions.
- **NativeAOT arrays:** `-c Release -p:BuildInParallel=false -p:AndroidTypeMapImplementation=trimmable -p:AndroidRuntime=NativeAOT -p:PublishAot=true -p:AndroidCodegenTarget=XAJavaInterop1 -p:RuntimeIdentifier=android-arm64 -p:IncludeCategories=ArrayMutation -p:_AndroidEnableTypemapR8Trimming=true -p:_SkipNdkResolution=false '-p:AdbTarget=-s emulator-5554'`, plus build-only `-m:1` — **3 passed, 0 skips/failures**, with retained-key R8 trimming enabled.

Post-rebase artifact inspection verified all **10** Debug/Release runtime JARs omit the retired helpers, `java-interop.jar` is absent, the relocated fixture JAR omits deleted fixtures, and both signed runtime-test APKs contain the Android throwable without the retired helper descriptors.

Device coverage is arm64 only, not a complete ABI/device matrix. No CI success is claimed.

## Compatibility and follow-ups

- Old Java wrappers/handwritten code explicitly using the retired experimental `ManagedPeer`/JavaInterop1 contract must be regenerated/migrated. No compatibility shim is retained. [#11635](#11635) tracks that question; #11727 documents the removal direction. Normal .NET for Android/MAUI codegen remains intact.
- The unused public `JniAddNativeMethodRegistrationAttributePresent` configuration property is intentionally removed; the attribute itself remains warning-only obsolete. Existing code setting that property must remove the setting, which no longer controlled any Android runtime behavior.
- Developers should clean old intermediates when changing between pre-/post-removal trees. No permanent build invalidation/cleanup machinery is added solely for this transition.
- Broader single-target generator-plumbing simplification and other legacy public API deprecations/removals are separate follow-ups, not mixed into this PR.
- Successful shared exception lookup could additionally receive borrowed/global-reference success tests, complementing the existing failure matrix; this optional coverage is not claimed as implemented.

## Related issues and PRs

- [#11727](#11727): experimental JavaInterop1 retirement tracker.
- [#11635](#11635): old ManagedPeer bytecode compatibility discussion.
- [#12133](#12133), [#12152](#12152): merged NativeAOT/GC migration and proxy decoupling.
- [#12887](#12887), [#12890](#12890): merged trimmable default and legacy activation/native typemap removal.
- [#13018](#13018): merged reflection-manager removal.
- [#13019](#13019): merged Android test relocation, reconciled here.
- [#12829](#12829): retained-key R8 pipeline replacing DGML, exercised by validation and preserved by this cleanup.
- [#11480](#11480): **closed, unmerged** earlier trimmable-only ManagedPeer removal; useful artifact-check precedent, not a claimed prerequisite. No performance numbers from it are claimed here.
- [dotnet/java-interop#1490](dotnet/java-interop#1490): **closed, unmerged** ManagedPeer registration modernization; unnecessary once those Android consumers are removed.

----

Pull Request
[title](https://github.com/dotnet/android/blob/main/Documentation/workflow/commit-messages.md#commit-summary) and
[description](https://github.com/dotnet/android/blob/main/Documentation/workflow/commit-messages.md#commit-body)
should follow the
[`commit-messages.md` workflow documentation](https://github.com/dotnet/android/blob/main/Documentation/workflow/commit-messages.md), and in particular should include:

- [x] Useful description of *why the change is necessary*.
- [x] Links to issues fixed
- [x] Unit tests
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.

3 participants