Skip to content

XALNS7015: Writing mixed-mode assemblies is not supported when FixAbstractMethodsStep patches an R2R-compiled Java binding assembly (CoreCLR, .NET 11) #11025

@simonrozsival

Description

@simonrozsival

Description

Building a .NET Android / MAUI Android app with CoreCLR (the default runtime in .NET 11) in Release configuration fails with:

error XALNS7015: System.NotSupportedException: Writing mixed-mode assemblies is not supported
   at Mono.Cecil.ModuleWriter.Write(...)
   at Mono.Cecil.AssemblyDefinition.Write(...)
   at Xamarin.Android.Tasks.SaveChangedAssemblyStep.ProcessAssembly(...)
   at Xamarin.Android.Tasks.AssemblyModifierPipeline.RunPipeline(...)
   at Xamarin.Android.Tasks.AssemblyModifierPipeline.RunTask()
   at Microsoft.Android.Build.Tasks.AndroidTask.Execute()

This failure is already documented in the test suite but suppressed:

// BuildTest.cs - SimilarAndroidXAssemblyNames
Assert.Ignore("CoreCLR: fails because of a Mono.Cecil lack of support");

CoreCLR is the default Android runtime starting in .NET 11, so this is now a first-class failure for Release builds.

Steps to Reproduce

  1. Create a .NET MAUI Android app targeting net11.0-android
  2. Reference a NuGet package containing a Java binding assembly that has a concrete Java.Lang.Object subclass missing an abstract interface method implementation — for example:
    <PackageReference Include="Microsoft.Intune.Maui.Essentials.android" Version="11.5.1" />
  3. Build Release for android-arm64:
    dotnet build -c Release -r android-arm64
    

Expected Behavior

Build succeeds.

Actual Behavior

Build fails with XALNS7015.

Root Cause

The pipeline in _LinkAssembliesNoShrink has two steps relevant here:

1. FixAbstractMethodsStep — inspects each Java.Lang.Object subclass in binding assemblies and injects stub methods (throwing AbstractMethodError) for any abstract interface methods that are not yet implemented. It sets context.IsAssemblyModified = true when it does so.

2. SaveChangedAssemblyStep — if IsAssemblyModified, calls assembly.Write(destination, writerParameters) via Mono.Cecil.

With MonoVM, the SourceFiles passed to _LinkAssembliesNoShrink are plain IL assemblies. With CoreCLR (new in .NET 11), _LinkAssembliesNoShrinkInputs feeds R2R-compiled assemblies from obj/…/R2R/ as SourceFiles. When FixAbstractMethodsStep needs to patch such an assembly, SaveChangedAssemblyStep fails because Mono.Cecil cannot write R2R assemblies (the ILONLY PE flag is cleared; the file contains embedded native ARM64 code).

Most binding assemblies (e.g. MSAL) already have all abstract methods implemented and pass through unmodified (IsAssemblyModified = false), hitting the safe CopyIfChanged path. The failure only surfaces for assemblies where FixAbstractMethods actually finds and injects a stub — in this case, IMAMServiceAuthenticationCallbackExtendedInvoker in MAMSDKBinding.dll was missing its AcquireToken implementation.

Environment

  • .NET SDK: 11.0.100-preview.2.26159.112
  • Microsoft.Android.Sdk.Darwin: 36.1.99-preview.2.154
  • Reproducer NuGet: Microsoft.Intune.Maui.Essentials.android 11.5.1
  • Configuration: Release, android-arm64, CoreCLR
  • macOS

Metadata

Metadata

Assignees

Labels

Area: CoreCLRIssues that only occur when using CoreCLR.copilot`copilot-cli` or other AIs were used to author this

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions