Skip to content

[release/11.0.1xx-preview6] Bump external/Java.Interop from 7049364 to c24a8e9b#11997

Merged
jonathanpeppers merged 2 commits into
release/11.0.1xx-preview6from
bump-ji-preview6-11633
Jul 6, 2026
Merged

[release/11.0.1xx-preview6] Bump external/Java.Interop from 7049364 to c24a8e9b#11997
jonathanpeppers merged 2 commits into
release/11.0.1xx-preview6from
bump-ji-preview6-11633

Conversation

@jonathanpeppers

@jonathanpeppers jonathanpeppers commented Jul 6, 2026

Copy link
Copy Markdown
Member

Bumps external/Java.Interop from 7049364 to c24a8e9b (tip of dotnet/java-interop/release/11.0.1xx-preview6).

Why

preview.6 Release builds of MAUI apps crash on startup:

System.TypeInitializationException: ... Java.Interop.ManagedPeer
 ---> Java.Lang.IncompatibleClassChangeError: no static or non-static method "Lnet/dot/jni/ManagedPeer;.????"
   at Java.Interop.JniEnvironment.Types._RegisterNatives(...)
   at Java.Interop.JniType.RegisterNativeMethods(...)
   at Java.Interop.ManagedPeer..cctor()

Debug and dotnet new android are unaffected; only MAUI Release (composite ReadyToRun + startup MIBC/PGO) reproduces.

Root cause

The default registration path passed a non-blittable JniNativeMethodRegistration[] (string Name; string Signature; Delegate Marshaler) through a delegate* unmanaged<> call. dotnet/runtime#126911 moved array-of-struct marshalling into a managed StructureMarshaler<T> whose blittable-only fallback is miscompiled by crossgen2 when the marshaller is precompiled hot under composite R2R + MIBC. It emits a raw Memmove that blits a managed string reference straight into the native char* name, so JNI receives garbage method names (????) and registration fails with NoSuchMethodError.

Fix

Picks up dotnet/java-interop#1474Register JNI natives via blittable JniNativeMethod. It reworks the single RegisterNatives chokepoint to marshal names/signatures to UTF-8 ourselves and dispatch through the blittable RegisterNatives(ReadOnlySpan<JniNativeMethod>) overload, so there is no StructureMarshaler<T> involved and it is correct regardless of the crossgen2 bug. This fixes ManagedPeer, AndroidTypeManager, and ManagedTypeManager together.

Submodule fast-forward, exactly one commit, all in Java.Interop:

c24a8e9b Register JNI natives via blittable JniNativeMethod (#1474)

Companion change: suppress new IL3050 warning

#1474 adds [RequiresDynamicCode] to RegisterNatives(.., JniNativeMethodRegistration[], int), which surfaces a new IL3050 AOT analysis warning at ManagedTypeManager.RegisterNativeMembers under NativeAOT and breaks BuildHasNoWarnings(True,False,"apk",NativeAOT) (exact-count assertion, 10 → 12).

This PR adds the same one-line [UnconditionalSuppressMessage("AOT", "IL3050", ...)] that main carries (companion to the JI bump in #11782). The JniNativeMethodRegistration[] path will be migrated to the blittable RegisterNatives(ReadOnlySpan<JniNativeMethod>) overload in a future change.

(main's #11782 also removed the Java.Runtime.Environment project from the solution, but that came from an unrelated upstream PR, dotnet/java-interop#1447, which is not part of this narrow #1474-only bump, so it is intentionally omitted here.)

Fixes #11633

Fixes a Release-mode startup crash in MAUI apps on preview.6:

    System.TypeInitializationException: ... Java.Interop.ManagedPeer
    ---> Java.Lang.IncompatibleClassChangeError: no static or non-static
    method "Lnet/dot/jni/ManagedPeer;.????"

Picks up dotnet/java-interop#1474 "Register JNI natives via blittable
JniNativeMethod", which reworks the RegisterNatives chokepoint to marshal
method names/signatures to UTF-8 ourselves and dispatch through the
blittable RegisterNatives(ReadOnlySpan<JniNativeMethod>) overload.

The old path passed a non-blittable JniNativeMethodRegistration[] through
a delegate* unmanaged<> call. dotnet/runtime#126911 moved array-of-struct
marshalling into a managed StructureMarshaler<T> whose blittable-only
fallback is miscompiled by crossgen2 under composite R2R + startup MIBC,
blitting a managed string reference into the native char* name and
corrupting the registered method names (the "????" above). This only
reproduces in Release (composite R2R + PGO), which is why Debug and
`dotnet new android` were unaffected while MAUI Release crashed.

Refs: #11633

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 6, 2026 17:45

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.

Pull request overview

This PR updates the external/Java.Interop submodule to pick up a fix for a .NET 11 Preview 6 MAUI Release (composite R2R + startup MIBC/PGO) startup crash during JNI native registration, where non-blittable registration data could be miscompiled and corrupt JNI method names.

Changes:

  • Fast-forward external/Java.Interop from 7049364 to c24a8e9b (per PR description: dotnet/java-interop#1474).
  • Moves JNI native registration to a blittable JniNativeMethod-based path to avoid problematic non-blittable struct marshalling under crossgen2.

…veMembers

dotnet/java-interop#1474 (pulled in by the Java.Interop bump in this PR)
adds [RequiresDynamicCode] to
JniEnvironment.Types.RegisterNatives(.., JniNativeMethodRegistration[], int),
surfacing a new IL3050 AOT analysis warning at
ManagedTypeManager.RegisterNativeMembers under NativeAOT. That broke
BuildHasNoWarnings(True,False,"apk",NativeAOT), which asserts an exact
warning count.

Suppress for now; the JniNativeMethodRegistration[] registration path will
be migrated to the blittable RegisterNatives(JniObjectReference,
ReadOnlySpan<JniNativeMethod>) overload in a future change. Mirrors the
companion change made on main in #11782.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

jonathanpeppers commented Jul 6, 2026

Copy link
Copy Markdown
Member Author

This appears to fix it; I did a local build plus install MAUI on top:

.\dotnet-local.cmd build .\Xamarin.Android.sln -t:InstallMaui -p:MauiVersion=11.0.0-preview.6.26351.3 -p:MauiVersionBand=11.0.100-preview.6
image

@jonathanpeppers jonathanpeppers merged commit a2d46b3 into release/11.0.1xx-preview6 Jul 6, 2026
40 checks passed
@jonathanpeppers jonathanpeppers deleted the bump-ji-preview6-11633 branch July 6, 2026 20:55
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