Skip to content

[Java.Interop] Retire obsolete Java wrapper scaffolding - #13080

Open
simonrozsival wants to merge 1 commit into
mainfrom
simonrozsival-generated-java-cleanup-analysis
Open

simonrozsival wants to merge 1 commit into
mainfrom
simonrozsival-generated-java-cleanup-analysis

Conversation

@simonrozsival

Copy link
Copy Markdown
Member

Summary

Retire the remaining legacy Java callable wrapper emitter and obsolete Java bootstrap artifacts for the .NET 12 cleanup. Current applications already use the trimmable typemap's separate Java generator; the old emitter still produced __md_methods, Runtime.register, and TypeManager.Activate references whose runtime consumers were removed.

  • Remove the legacy CallableWrapper* model/writers, reader/writer options, classifier/style selector, Cecil/XML adapters, standalone jcw-gen, and their obsolete golden-output tests. Preserve the shared naming/scanning/hash/type-name mapping utilities and supported XAJavaInterop1 C# binding generation.
  • Remove abstract Java constructor bridges, deferred constructor bridges together with their unused managed UCO bodies/native-table rows, and uncalled deferred-registration helpers. Preserve Java constructor/super sequencing, callback registrations, and managed CreateInstance activation.
  • Ship only the retained trimmable runtime JAR/DEX pair. Retire alternate artifacts, unused DebugRuntime/BuildConfig/environment scaffolding, old context-management JNI declarations, vestigial bootstrap APIs, and the unused embedded registration template.
  • Move the actual JNI header producer to the retained output, wire the Java fixture compiler to the retained JAR, and rebuild runtime JAR contents without stale removed classes.

Compatibility and scope

The public legacy tooling/bootstrap removals are intentional compatibility breaks, explicitly authorized for this cleanup. Custom tooling that used the retired emitter/CLI or old Java runtime APIs/artifacts must migrate to the current pipeline. The tooling assembly's still-live utilities remain shipped.

Nonempty registerNatives/UCO tables, callback-format/connector metadata, concrete constructor guards, GC peers/reference edges, shared Context, runtime providers, real environment configuration, and both runtimes' conservative field-name retention remain intact. The unproven IntentService shim and conditional empty-registration/alias-retention candidates are excluded.

The intended release is .NET 12; actual configured TFMs and SDK/package pins are unchanged. This branch is based on main, not sibling cleanup branches. It deletes emitter files touched by open #13060, so that PR needs explicit ordering/reconciliation rather than a claim of conflict-free composition. #13062 remains a separate field-lookup correctness change.

Validation

Builds used the repository's MSBUILD_ARGS=-m:2 mechanism and a session-local NinjaPath override that executes the prepared real Ninja with -j2. The wrapper is not a repository change.

Command / coverage Actual result
make prepare CONFIGURATION=Release MSBUILD_ARGS='-m:2' Passed, zero warnings/errors.
make all CONFIGURATION=Release MSBUILD_ARGS='-m:2 -p:NinjaPath=/Users/simon/.copilot/session-state/209b09d7-6866-4a15-a7a5-610402d16ce9/files/bounded-ninja.sh' Solution compilation/API gate passed; initial local workload setup failed because the default build lacked API 37.1 references.
./dotnet-local.sh build build-tools/scripts/Prepare.proj -t:BuildExtraApiLevels -c Release -v minimal -m:2 -p:NinjaPath=/Users/simon/.copilot/session-state/209b09d7-6866-4a15-a7a5-610402d16ce9/files/bounded-ninja.sh Passed; produced this worktree's API 37.1/37.2 references and ran compatibility gates.
Same bounded make all command after extra-API build Passed, including local workload setup; final setup zero warnings/errors.
dotnet test external/Java.Interop/tests/Java.Interop.Tools.JavaCallableWrappers-Tests/Java.Interop.Tools.JavaCallableWrappers-Tests.csproj -c Release -m:2 -v minimal Passed: 22 naming/scanning tests, no skips.
JAVA_HOME=/Users/simon/android-toolchain/jdk-25 dotnet test external/Java.Interop/tests/generator-Tests/generator-Tests.csproj -c Release -m:2 -v minimal Passed: 478 supported binding-generator tests, no skips.
JAVA_HOME=/Users/simon/android-toolchain/jdk-25 dotnet test src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj -c Release -m:2 -v minimal --filter 'FullyQualifiedName~TrimmableTypeMap|FullyQualifiedName~TypeMapProguard|FullyQualifiedName~NativeAotBootstrap|FullyQualifiedName~ResourcesTests' Passed: 156 tests; four LLVM-dependent cases initially skipped.
JAVA_HOME=/Users/simon/android-toolchain/jdk-25 dotnet test src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj -c Release -m:2 -v minimal -p:_NativeAotLlvmReadObjPath=/Users/simon/android-toolchain/ndk/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-readobj --filter 'FullyQualifiedName~NativeObjectTargetUnionsRidsAndHonorsDisabledTrimming|FullyQualifiedName~NativeAotModeRoundTripsCannotReuseWrongRules|FullyQualifiedName~UnoptimizedNativeAotReadsObjectWithoutGraphs' Passed: all four formerly skipped cases, no skips.
./dotnet-local.sh test bin/TestRelease/net10.0/Xamarin.Android.Build.Tests.dll --filter 'FullyQualifiedName~TrimmableTypeMapBuildTests|FullyQualifiedName~GenerateCoreClrRuntimeProviderSourcesTests|FullyQualifiedName~CopyResourceTests|FullyQualifiedName~GeneratePackageManagerJava|FullyQualifiedName~R8Tests' Passed: 217 host integration tests, no skips.
./dotnet-local.sh build tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj -c Release -m:2 -p:RuntimeIdentifier=android-arm64 -p:PublishAot=false -p:NinjaPath=/Users/simon/.copilot/session-state/209b09d7-6866-4a15-a7a5-610402d16ce9/files/bounded-ninja.sh Passed: CoreCLR fixture, 38 warnings/zero errors.
Same fixture build with -p:PublishAot=true -p:IlcSingleThreaded=true Passed: NativeAOT fixture, 11 warnings/zero errors.
./dotnet-local.sh build src/java-runtime/java-runtime.csproj -c Release -m:2 -v normal Passed; unchanged Java JAR/header and D8 generation skipped correctly.

The eight-case regression covers abstract/concrete, deferred/eager, and callback/no-callback combinations, asserting both emitted Java calls/declarations and generated managed UCO/native registration output. A separate session-only comparison compiled the original main emitters against the same model and saved eight pairs of actual Java/managed PE outputs: ordinary concrete registrations are unchanged, deferred constructor rows disappear, and abstract callback tables remain unchanged.

Actual retained JAR contents and generated JNI header were inspected. Runtime/GC/package-manager classes remain, removed classes/APIs are absent, and the JNI header contains the live initInternal/registerNatives declarations.

On-device runtime validation

Both full suites ran on the exclusively selected API 36 arm64 emulator emulator-5554, with no physical-device operations. CoreCLR passed 933, skipped 8, failed 0 (941 total); NativeAOT passed 879, skipped 7, failed 0 (886 total). Skips are existing test/runtime limitations or unavailable network access; NativeAOT intentionally skips the CoreCLR GC event-emission test.

TRX inspection confirms these relevant checks passed in each runtime: constructor activation 38, virtual constructor/reentrancy 3, direct callbacks 2, exports 9, trimmable runtime coverage 10, manifest startup 1, GC bridge 11, peer identity 5, managed-object proxies 10, and application 4. No unrelated ownership/GC baseline failures occurred. Only the owned test package was uninstalled afterward and the device lease was released.

Exact CoreCLR commands:

ANDROID_SERIAL=emulator-5554 ./dotnet-local.sh build -t:Install -c Release -m:2 -p:RuntimeIdentifier=android-arm64 -p:PublishAot=false '-p:AdbTarget=-s emulator-5554' tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj
(
  cd tests/Mono.Android-Tests/Mono.Android-Tests
  ANDROID_SERIAL=emulator-5554 ../../../dotnet-local.sh test Mono.Android.NET-Tests.csproj --no-build -c Release -p:RuntimeIdentifier=android-arm64 -p:PublishAot=false '-p:AdbTarget=-s emulator-5554' --device emulator-5554 --report-trx --results-directory /Users/simon/.copilot/session-state/209b09d7-6866-4a15-a7a5-610402d16ce9/files/device-results/coreclr
)

Exact NativeAOT commands:

ANDROID_SERIAL=emulator-5554 ./dotnet-local.sh build -t:Install -c Release -m:2 -p:RuntimeIdentifier=android-arm64 -p:PublishAot=true -p:IlcSingleThreaded=true '-p:AdbTarget=-s emulator-5554' tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj
(
  cd tests/Mono.Android-Tests/Mono.Android-Tests
  ANDROID_SERIAL=emulator-5554 ../../../dotnet-local.sh test Mono.Android.NET-Tests.csproj --no-build -c Release -p:RuntimeIdentifier=android-arm64 -p:PublishAot=true -p:IlcSingleThreaded=true '-p:AdbTarget=-s emulator-5554' --device emulator-5554 --report-trx --results-directory /Users/simon/.copilot/session-state/209b09d7-6866-4a15-a7a5-610402d16ce9/files/device-results/nativeaot
)

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

Remove the legacy JCW emitter and standalone tool whose output still
references retired registration and activation APIs.  Preserve the
shared naming utilities and current trimmable registration pipeline.

Remove unused abstract/deferred constructor bridges and bootstrap
artifacts, wire the retained runtime JAR/header producer, and document
intentional tooling compatibility removals.  Validate output/native
table agreement, SDK/API gates, host coverage, and both runtime suites.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 12, 2026 09:19

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.

🟡 Changes recommended

Retired artifacts can survive incremental builds, and the error catalog retains an obsolete XA4217 entry.

2 open findings
What changed in this PR

Retires the obsolete Java callable-wrapper pipeline and consolidates runtime generation around the trimmable typemap implementation.

Changes:

  • Removes legacy JCW tooling, models, adapters, tests, and bootstrap APIs.
  • Eliminates unused abstract/deferred constructor bridges with regression coverage.
  • Ships only the trimmable runtime JAR/DEX and updates consumers and documentation.
File Description
src/​Xamarin.Android.Build.Tasks/​Xamarin.Android.Common.targets Removes the obsolete debug-runtime property.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​TrimmableTypeMapBuildTests.cs Verifies retained and retired runtime artifacts.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​Tasks/​CopyResourceTests.cs Verifies the removed registration template is unavailable.
src/​Xamarin.Android.Build.Tasks/​Resources/​MonoRuntimeProvider.Bundled.java Removes a stale legacy-generator comment.
src/​Xamarin.Android.Build.Tasks/​Resources/​ApplicationRegistration.java Deletes the obsolete embedded template.
src/​Mono.Android/​Mono.Android.slnf Removes jcw-gen.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​TrimmableTypeMapTypes.cs Updates provider-generation documentation.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Scanner/​JavaPeerScanner.cs Removes legacy-emitter references.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Generator/​ModelBuilder.cs Omits unused constructor UCOs.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Generator/​ManifestGenerator.cs Updates provider documentation.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Generator/​JcwJavaSourceGenerator.cs Omits invalid constructor bridges and empty helpers.
src/​Microsoft.Android.Build.Tasks/​Tests/​Microsoft.Android.Build.Tasks.Tests/​GenerateTrimmableTypeMapTests.cs Adds constructor/registration regression coverage.
src/​java-runtime/​java/​mono/​android/​Runtime.java Removes obsolete JNI declarations.
src/​java-runtime/​java/​mono/​android/​release/​BuildConfig.java Deletes obsolete runtime configuration.
src/​java-runtime/​java/​mono/​android/​release-net6/​BuildConfig.java Deletes obsolete runtime configuration.
src/​java-runtime/​java/​mono/​android/​MonoPackageManager.java Removes the legacy package manager.
src/​java-runtime/​java/​mono/​android/​MonoPackageManager_Resources.java Removes unused dependency metadata.
src/​java-runtime/​java/​mono/​android/​DebugRuntime.java Removes obsolete debug bootstrap APIs.
src/​java-runtime/​java/​mono/​android/​debug/​BuildConfig.java Deletes obsolete runtime configuration.
src/​java-runtime/​java/​mono/​android/​debug-net6/​BuildConfig.java Deletes obsolete runtime configuration.
src/​java-runtime/​java/​mono/​android/​clr/​MonoPackageManager.java Removes vestigial APIs and imports.
src/​java-runtime/​java/​mono/​android/​app/​XamarinAndroidEnvironmentVariables.java Deletes the unused environment placeholder.
src/​java-runtime/​java-runtime.targets Builds only the trimmable runtime artifacts.
Microsoft.Android.slnx Removes jcw-gen.
external/​Java.Interop/​tools/​jcw-gen/​jcw-gen.slnf Deletes the retired tool solution filter.
external/​Java.Interop/​tools/​jcw-gen/​jcw-gen.csproj Deletes the retired tool project.
external/​Java.Interop/​tools/​jcw-gen/​App.cs Deletes the retired CLI.
external/​Java.Interop/​tests/​Java.Interop.Tools.JavaCallableWrappers-Tests/​Java.Interop.Tools.JavaCallableWrappers/​XmlImporterTests.cs Removes obsolete adapter tests.
external/​Java.Interop/​tests/​Java.Interop.Tools.JavaCallableWrappers-Tests/​Java.Interop.Tools.JavaCallableWrappers/​JavaCallableWrapperGeneratorTests.cs Removes obsolete emitter tests.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers/​JavaPeerStyle.cs Removes the retired style selector.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers/​JavaCallableMethodClassifier.cs Removes the legacy classifier.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers/​CallableWrapperWriterOptions.cs Removes obsolete writer options.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers/​CallableWrapperReaderOptions.cs Removes obsolete reader options.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers.CallableWrapperMembers/​CallableWrapperTypeAnnotation.cs Removes legacy annotation emission.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers.CallableWrapperMembers/​CallableWrapperType.cs Removes the legacy wrapper model/writer.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers.CallableWrapperMembers/​CallableWrapperMethod.cs Removes legacy method emission.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers.CallableWrapperMembers/​CallableWrapperField.cs Removes legacy field emission.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers.CallableWrapperMembers/​CallableWrapperConstructor.cs Removes legacy constructor emission.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers.CallableWrapperMembers/​CallableWrapperApplicationConstructor.cs Removes legacy application constructors.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers.Adapters/​XmlImporter.cs Removes the obsolete XML importer.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers.Adapters/​XmlExporter.cs Removes the obsolete XML exporter.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Java.Interop.Tools.JavaCallableWrappers.Adapters/​CecilImporter.cs Removes the obsolete Cecil adapter.
external/​Java.Interop/​src/​Java.Interop.Tools.JavaCallableWrappers/​Extensions/​XmlExtensions.cs Removes adapter-only XML helpers.
external/​Java.Interop/​src/​Java.Interop.Tools.Diagnostics/​Java.Interop.Tools.Diagnostics/​Diagnostic.cs Removes retired diagnostic references.
external/​Java.Interop/​src/​Java.Interop.Localization/​Resources.resx Removes retired emitter diagnostics.
external/​Java.Interop/​src/​Java.Interop.Localization/​Resources.Designer.cs Removes corresponding generated accessors.
external/​Java.Interop/​Java.Interop.slnx Removes jcw-gen.
external/​Java.Interop/​Directory.Build.targets Updates dependency-collision commentary.
Documentation/​guides/​internals/​JavaJNI_Interop.md Documents the supported pipeline and removals.
build-tools/​scripts/​Jar.targets Uses the retained runtime JAR for fixtures.
build-tools/​installers/​create-installers.targets Packages only retained runtime artifacts.
.github/​skills/​tests/​references/​test-catalog.md Reclassifies the remaining Java.Interop tests.
.github/​instructions/​java-interop.instructions.md Points JCW generation to the trimmable pipeline.
Files not reviewed (1)
  • external/Java.Interop/src/Java.Interop.Localization/Resources.Designer.cs: Generated file

🧠 Review effort: Balanced

"java_runtime_fastdev_clr.dex",
}) {
FileAssert.Exists (Path.Combine (toolsDir, file), $"{file} should exist in the SDK pack.");
FileAssert.DoesNotExist (Path.Combine (toolsDir, file), $"{file} should not exist in the SDK pack.");
Comment on lines +85 to +88
The .NET 12 cleanup retires the standalone `jcw-gen` tool and the legacy public
JCW emitter in `Java.Interop.Tools.JavaCallableWrappers`: its `CallableWrapper*`
model/writers, reader/writer options, `JavaPeerStyle`, method classifier, and
Cecil/XML import/export adapters. That emitter produced `__md_methods`,

This branch has not been deployed

No deployments
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.

2 participants