Bump external/Java.Interop from b881d21 to 6820a9cb#11622
Merged
jonathanpeppers merged 19 commits intoJun 16, 2026
Conversation
Bumps [external/Java.Interop](https://github.com/dotnet/java-interop) from `b881d21` to `d7dbad5`. - [Commits](dotnet/java-interop@b881d21...d7dbad5) --- updated-dependencies: - dependency-name: external/Java.Interop dependency-version: d7dbad5e30a8f03743a508a95c4e9159fe1f6607 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
Use the new ReflectionJniTypeManager and ReflectionJniValueManager bases introduced by the Java.Interop submodule update, while preserving Android's legacy peer activation path for value managers. Also keep Java.Interop built-in native registrations out of the trimmable typemap XA4251 path and remove the stale GenericMarshaler source include from Android Java.Interop tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Keep reflection-manager analyzer suppressions local to Mono.Android build compilation so NativeAOT app warning tests still observe the expected warnings. Isolate post-trim trimmable typemap Java output per inner build to avoid concurrent linked-java cleanup races, and update the MonoVM APK size baseline for the Java.Interop bump. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
/azp run |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
Member
|
/azp run |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
Resolve the Java.Interop test project conflict by keeping the NUnit package reference from main while dropping the stale GenericMarshaler source include removed for the Java.Interop update. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Keep the Java.Interop reflection-manager compatibility suppressions limited to trim analysis warnings so AOT warning-count tests still observe expected IL3050/IL3053 output. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Account for the additional temporary reflection-manager trim warnings emitted by the Java.Interop update while preserving AOT warning visibility. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
5a6cb51 to
6a34c90
Compare
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
b881d21 to d7dbad5b881d21 to cfca8ad
…bump After bumping external/Java.Interop to cfca8ad, the apkdiff regression test BuildReleaseArm64(False,MonoVM) fails because lib_System.Private.CoreLib.dll.so grew ~10% and lib_Java.Interop.dll.so grew ~5.5%, both exceeding the 5% content regression threshold. Refresh the reference apkdesc with the actual sizes captured by the CI run (build 1462159). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
Author
|
A newer version of external/Java.Interop exists, but since this PR has been edited by someone other than Dependabot I haven't updated it. You'll get a PR for the updated version as normal once this PR is merged. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
simonrozsival
added a commit
to dotnet/java-interop
that referenced
this pull request
Jun 15, 2026
#1441 added `JniRuntime.JniTypeManager.TryRegisterBuiltInNativeMembers ()` -- a reflection-free direct call to `JavaProxyObject.RegisterNativeMembers` -- and bumped that method to `internal` so the call would compile. That method is dead code: nothing in Java.Interop (or dotnet/android) ever calls it, and the base `JniTypeManager.RegisterNativeMembers` is a no-op. `JavaProxyObject`'s native members are -- and were before #1441 -- registered purely via reflection in `ReflectionJniTypeManager` (`FindAndCallRegisterMethod` discovering the `[JniAddNativeMethodRegistrationAttribute]`-annotated method), which finds private methods just fine via `GetRuntimeMethods ()`. Remove the unused `TryRegisterBuiltInNativeMembers` and restore `RegisterNativeMembers` to `private` (its state before #1441). Making it private again also strips the attribute-bearing method from the reference assembly, which fixes dotnet/android's trimmable typemap scanner falsely rejecting the built-in `JavaProxyObject` with XA4251 (dotnet/android#11622). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers
pushed a commit
to dotnet/java-interop
that referenced
this pull request
Jun 16, 2026
…in (#1468) #1441 changed `JavaProxyObject.RegisterNativeMembers` from `private` to `internal` so the new reflection-free `JniRuntime.JniTypeManager.TryRegisterBuiltInNativeMembers ()` could call it directly. A side effect is that the `[JniAddNativeMethodRegistrationAttribute]`- annotated method now appears in Java.Interop's *reference* assembly. dotnet/android's trimmable typemap scanner reads reference assemblies and rejects any type carrying that attribute (XA4251), so every trimmable typemap build now fails on the built-in `JavaProxyObject` (see dotnet/android#11622). Restore the method to `private` (so it is stripped from the reference assembly) and expose a small attribute-free `internal` entry point, `RegisterBuiltInNativeMembers (JniType)`, for the built-in registration path to call. Runtime behavior is unchanged. ### [Java.Interop] Restore pure-reflection registration for JavaProxyObject #1441 added `JniRuntime.JniTypeManager.TryRegisterBuiltInNativeMembers ()` -- a reflection-free direct call to `JavaProxyObject.RegisterNativeMembers` -- and bumped that method to `internal` so the call would compile. That method is dead code: nothing in Java.Interop (or dotnet/android) ever calls it, and the base `JniTypeManager.RegisterNativeMembers` is a no-op. `JavaProxyObject`'s native members are -- and were before #1441 -- registered purely via reflection in `ReflectionJniTypeManager` (`FindAndCallRegisterMethod` discovering the `[JniAddNativeMethodRegistrationAttribute]`-annotated method), which finds private methods just fine via `GetRuntimeMethods ()`. Remove the unused `TryRegisterBuiltInNativeMembers` and restore `RegisterNativeMembers` to `private` (its state before #1441). Making it private again also strips the attribute-bearing method from the reference assembly, which fixes dotnet/android's trimmable typemap scanner falsely rejecting the built-in `JavaProxyObject` with XA4251 (dotnet/android#11622). ### Address review: restore TryRegisterBuiltInNativeMembers (not dead code) The previous commit deleted JniRuntime.JniTypeManager.TryRegisterBuiltInNativeMembers claiming it was unused. That was wrong: it has two live callers in the NativeAOT samples (samples/Hello-NativeAOTFromJNI/NativeAotTypeManager.cs and samples/Hello-NativeAOTFromAndroid/NativeAotTypeManager.cs), both JniTypeManager subclasses. Deleting it broke them (CS0103) and removed the only path that registers JavaProxyObject's equals/hashCode/toString natives for NativeAOT type managers (which don't use the reflection-based FindAndCallRegisterMethod path). The breakage was hidden in CI only because the NativeAOT sample steps use continueOnError: true. Keep the XA4251 fix (RegisterNativeMembers stays private, so the [JniAddNativeMethodRegistrationAttribute] is stripped from the reference assembly) and restore TryRegisterBuiltInNativeMembers by extracting the registration logic into a new attribute-free internal helper, JavaProxyObject.AddBuiltInRegistrations. Both the private attributed RegisterNativeMembers (reflection path) and TryRegisterBuiltInNativeMembers (NativeAOT path) call it. Restore the PublicAPI.Unshipped.txt entry as well. Verified: Java.Interop.dll builds clean; the reference assembly contains no method carrying [JniAddNativeMethodRegistration]; the sample's call to TryRegisterBuiltInNativeMembers resolves (no CS0103). ### Keep built-in registration in the samples via ReflectionJniTypeManager Replaces the production TryRegisterBuiltInNativeMembers helper with a samples-only solution, restoring the pre-#1441 behavior for the NativeAOT type managers. Background: making JavaProxyObject.RegisterNativeMembers private (the XA4251 fix) is sufficient for the default Android runtime, which discovers and invokes it via reflection (FindAndCallRegisterMethod -> GetRuntimeMethods(), which returns private methods). The only thing that needed JavaProxyObject's registration via a non-reflection path was the two NativeAOT samples, which #1441 had rewritten to derive from the reflection-free JniRuntime.JniTypeManager base. That is why #1441 introduced TryRegisterBuiltInNativeMembers. Instead of carrying that helper in production, have the sample type managers derive from JniRuntime.ReflectionJniTypeManager again - exactly what the base JniRuntime.JniTypeManager provided before #1441. Built-in types such as JavaProxyObject/JavaProxyThrowable are then registered automatically via reflection, and the samples no longer need any custom registration code. Changes: - JavaProxyObject.RegisterNativeMembers: internal -> private. The marshalers stay (the default reflection runtime registers them by reflecting over this type); only the visibility changes, which strips the attribute from the reference assembly and fixes the dotnet/android XA4251 scanner failure. - Delete JniRuntime.JniTypeManager.TryRegisterBuiltInNativeMembers (+ its PublicAPI.Unshipped.txt entry); no longer needed. - Hello-NativeAOTFromJNI / Hello-NativeAOTFromAndroid: derive from JniRuntime.ReflectionJniTypeManager and drop the reflection-free overrides and hand-written JavaProxyObject registration. ReflectionJniTypeManager is [RequiresDynamicCode]/[RequiresUnreferencedCode], so the constructor suppresses IL2026/IL3050 with [UnconditionalSuppressMessage]. A #pragma is insufficient here: it silences the Roslyn analyzer but not the ILLink/ILC publish passes, which only honor the attribute (verified with a trim-publish of the real type manager against Java.Interop.dll). Net: production loses code (1-line visibility change + deletions) and the samples shrink substantially. ### Drop verbose explanatory comments from the NativeAOT sample type managers The [UnconditionalSuppressMessage] Justification strings already convey the necessary context. ### Fix NativeAOT sample type resolution: override GetTypeForSimpleReference Build 1465402's "run Hello-NativeAOTFromJNI" step failed at runtime: System.NotSupportedException: Could not find System.Type corresponding to Java type JniTypeSignature(TypeName=example/ManagedType ...) at Java.Interop.ManagedPeer.RegisterNativeMembers(...) at example.ManagedType.<clinit>(ManagedType.java:15) Root cause: after #1441, JniRuntime.JniTypeManager.GetType() dispatches through GetTypeForSimpleReference (singular), not GetTypesForSimpleReference (plural). The previous sample rewrite only overrode the plural method, so app types like example/ManagedType were never resolved (the base ReflectionJniTypeManager's GetTypeForSimpleReference only knows built-in types), and ManagedPeer registration threw before it could register the type. Fix: override GetTypeForSimpleReference (singular) in both NativeAOT sample type managers to resolve the sample's own managed types, falling back to the base for built-ins. Registration and the reverse Type->JNI mapping continue to be handled by the reflection base (the pre-#1441 behavior). The override carries the same [return: DynamicallyAccessedMembers(...)] as the base to satisfy IL2093. ### Address review: drop unreachable null guard in FromAndroid sample `typeMappings` is assigned in its field initializer and never set to null, so the `if (typeMappings == null) yield break;` guard in CreateSimpleReferencesEnumerator was unreachable dead code. Remove it. ### Document why the NativeAOT sample trim/AOT suppressions are acceptable Add a class-level comment to both NativeAOT sample type managers explaining the rationale for the [UnconditionalSuppressMessage] IL2026/IL3050 suppressions: - These are *samples*, not product code. .NET for Android (what we ship) does not pair ReflectionJniTypeManager with NativeAOT, so it isn't worth the effort to make these samples fully trim/AOT-clean right now. - The reflection paths were always trim/AOT-unsafe. Before #1441 the equivalent suppressions lived inside JniTypeManager itself (justified "NotUsedInAndroid"); #1441 simply moved that responsibility to callers via [RequiresDynamicCode]/[RequiresUnreferencedCode]. ### Reword NativeAOT sample suppression justifications to describe why it's safe The previous IL2026/IL3050 justifications ("does not require unreferenced code / runtime code generation") read as the opposite of reality, since ReflectionJniTypeManager is exactly [RequiresUnreferencedCode]/[RequiresDynamicCode]. Reword to describe why the suppression is correct for this sample: - IL2026: the assembly is rooted via TrimmerRootAssembly and the reflected registration members are preserved by the [DynamicallyAccessedMembers] annotations on the RegisterNativeMembers(Type) -> FindAndCallRegisterMethod path. - IL3050: registration uses CreateDelegate on compile-time-known static methods (no MakeGenericType / expression compilation), so no runtime codegen is required. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Includes upstream fix dotnet/java-interop#1468 to make JavaProxyObject.RegisterNativeMembers private again, which fixes the XA4251 trimmable typemap failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
b881d21 to cfca8adb881d21 to 6820a9cb
…/external/Java.Interop-d7dbad5 # Conflicts: # src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.targets
…Reference The Java.Interop bump (external/Java.Interop -> 6820a9cb) shifted the trim-analysis warning on `ManagedTypeManager.GetTypeForSimpleReference`: its return value flows from the un-annotated `out` parameter of `ManagedTypeMapping.TryGetType (string, out Type)`, so it no longer satisfies the method's `[return: DynamicallyAccessedMembers]` and the trimmer now reports IL2068 (previously IL2063). This unsuppressed warning inflates the trim warning count and breaks the `BuildHasTrimmerWarnings` expectations. Mirror the existing IL2063 suppression on the sibling `TrimmableTypeMapTypeManager.GetTypeForSimpleReference`. `ManagedTypeManager` is removed in #11643. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
/azp run |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
…/external/Java.Interop-d7dbad5 # Conflicts: # src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.MonoVM.apkdesc
Regenerate the MonoVM size-regression baseline against the merged build (external/Java.Interop @ 6820a9cb + main). Java.Interop 6820a9cb adds a System.IO.Hashing dependency to the framework (referenced by both Mono.Android.dll and Java.Interop.dll), so the app now packages lib_System.IO.Hashing.dll.so; assembly and CoreLib sizes also shifted. Resolves the merge conflict on this apkdesc. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Per Documentation/project-docs/ApkSizeRegressionChecks.md, apkdesc reference
files must be produced from a Release-configuration SDK build — Debug-SDK apps
are larger and trim differently.
The earlier SimpleDotNet.MonoVM apkdesc was generated with a Debug SDK and
wrongly included `lib_System.IO.Hashing.dll.so` and inflated assembly sizes.
Under a Release build the managed typemap's XxHash3 path is trimmed away, so
System.IO.Hashing is not packaged. The stale entry also crashed apkdiff
(KeyNotFoundException for the missing entry, exit 134).
Regenerate SimpleDotNet.{MonoVM,CoreCLR,NativeAOT} via
`make all CONFIGURATION=Release` + the BuildReleaseArm64 tests
(build-tools/scripts/UpdateApkSizeReference.sh). The XForms variants pass
within threshold and are left unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
The Java.Interop bump in this PR reduces the number of trim/AOT warnings produced by `Mono.Android`, which made several warning-count assertions fail (always with lower-than-expected counts). NativeAOT-only `SupportedOSPlatformVersion` and `CheckSignApk` tests previously asserted exactly `4 Warning(s)` (2x IL3053 + 2x IL2104). The IL2104 (trim) warnings no longer appear, so the build now reports `2 Warning(s)`. Loosen these to `AssertHasAtMostWarnings (2)` so future improvements don''t regress the suite, via a new helper in `AssertionExtensions`. `BuildHasTrimmerWarnings` data also drops by one warning across all runtimes: SuppressTrimAnalysisWarnings=false 3→2, TrimMode=full(true) non-NativeAOT 3→2 (unifies with NativeAOT''s 2), and IsAotCompatible=true non-NativeAOT 4→3. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
`uint.Parse (string)` without a format provider trips CA1305 (TreatWarningsAsErrors), which broke the macOS build and skipped all test stages. Parse with CultureInfo.InvariantCulture. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
jonathanpeppers
approved these changes
Jun 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps external/Java.Interop from
b881d21to6820a9cb.Java.Interop changes pulled in
6820a9c[Java.Interop] Make JavaProxyObject.RegisterNativeMembers private again (#1468)a2159d7Remove NuGet dependency grouping from Dependabot config (#1459)a0ca676[ci] Update agentic workflows to claude-opus-4.8 (#1461)6d8aef7Bump to dotnet/android-tools@1fb68b6 (#1457)cfca8adUpgrade gh-aw to v0.79.6 and recompile workflows (#1460)0104236[JniValueManager] Make TryConstructPeer virtual (#1456)d7dbad5Remove Java.Interop.Dynamic (#1449)0244c10Split reflection-based JniTypeManager and JniValueManager behavior (#1441)9ca7064[Java.Interop] Remove legacyNETpreprocessor paths (#1451)cd2fc12Remove Java.Interop.GenericMarshaler (#1450)See full diff in compare view.
Changes in this PR (beyond the submodule bump)
The Java.Interop bump — particularly #1441 (split reflection-based
JniTypeManagerandJniValueManager) and #1449 (removal ofJava.Interop.Dynamic) — required a number of follow-on changes indotnet/android:Runtime /
Mono.AndroidJavaInteropTypeManager/JavaInteropValueManagerhierarchy to the new reflection-based base types and update type/value manager construction to match.ManagedTypeManager.GetTypeForSimpleReference— annotate the entry point that legitimately requires reflection so trim analysis is satisfied.Tests / apkdescs
BuildReleaseArm64SimpleDotNet.MonoVM.apkdescto track size changes from the Java.Interop bump.BuildReleaseArm64apkdescs (MonoVM+NativeAOT) from aReleaseSDK so they match what CI produces.Mono.Androidnow produces fewer trim/AOT warnings, so loosen the strict4 Warning(s)checks inSupportedOSPlatformVersionandCheckSignApktoAssertHasAtMostWarnings (2)(new helper inAssertionExtensions) and drop theBuildHasTrimmerWarningsdata counts (3 → 2,4 → 3) accordingly.Merges
origin/mainto keep the branch current and resolve a conflict inMicrosoft.Android.Sdk.TypeMap.Trimmable.targets.