Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XARRA7028 AssemblyResolutionException in Android App Release Build #9629

Closed
uholeschak opened this issue Dec 18, 2024 · 15 comments · Fixed by #9803
Closed

XARRA7028 AssemblyResolutionException in Android App Release Build #9629

uholeschak opened this issue Dec 18, 2024 · 15 comments · Fixed by #9803
Assignees
Labels
Area: App+Library Build Issues when building Library projects or Application projects. need-attention A xamarin-android contributor needs to review

Comments

@uholeschak
Copy link

uholeschak commented Dec 18, 2024

Android framework version

net9.0-android

Affected platform version

VS2022 17.12.3

Description

When building and publishing an Android app in Release mode the build always fails with the following error message, but the missing System.Private.CoreLib Version=9.0.0.0 is present.
The problem is the MSBuild target _RemoveRegisterAttribute, which is run after AOT. Is seems that in this state the assembly dependencies are not accessible any more.

XARRA7028: Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'

Steps to Reproduce

  1. Create and build an Android NET9 app in release mode with the default settings:
    <AndroidPackageFormat>apk</AndroidPackageFormat>
    <AndroidLinkTool>r8</AndroidLinkTool>
    <AndroidEnableMultiDex>True</AndroidEnableMultiDex>
  1. Publish the app to the target. In this step the error occurs.

Did you find any workaround?

Disable the _RemoveRegisterAttribute target by setting in Directory.Build.Props:

<Project>
  <Target Name="PatchRemoveRegisterAttributeBefore" BeforeTargets="_RemoveRegisterAttribute">
    <PropertyGroup>
      <AndroidIncludeDebugSymbolsStd>$(AndroidIncludeDebugSymbols)</AndroidIncludeDebugSymbolsStd>
      <AndroidIncludeDebugSymbols Condition=" '$(EmbedAssembliesIntoApk)' == 'True' ">True</AndroidIncludeDebugSymbols>
    </PropertyGroup>
  </Target>
  <Target Name="PatchRemoveRegisterAttributeAfter" AfterTargets="_RemoveRegisterAttribute">
    <PropertyGroup>
      <AndroidIncludeDebugSymbols Condition=" '$(EmbedAssembliesIntoApk)' == 'True' ">$(AndroidIncludeDebugSymbolsStd)</AndroidIncludeDebugSymbols>
    </PropertyGroup>
  </Target>
</Project>

Relevant log output

XARRA7028: Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'
   bei Mono.Cecil.BaseAssemblyResolver.Resolve(AssemblyNameReference name, ReaderParameters parameters)
   bei Mono.Cecil.DefaultAssemblyResolver.Resolve(AssemblyNameReference name)
   bei Mono.Cecil.MetadataResolver.Resolve(TypeReference type)
   bei Mono.Cecil.TypeReference.Resolve()
   bei Mono.Cecil.Mixin.CheckedResolve(TypeReference self)
   bei Mono.Cecil.MetadataBuilder.GetConstantType(TypeReference constant_type, Object constant)
   bei Mono.Cecil.MetadataBuilder.AddConstant(IConstantProvider owner, TypeReference type)
   bei Mono.Cecil.MetadataBuilder.AddField(FieldDefinition field)
   bei Mono.Cecil.MetadataBuilder.AddFields(TypeDefinition type)
   bei Mono.Cecil.MetadataBuilder.AddType(TypeDefinition type)
   bei Mono.Cecil.MetadataBuilder.AddTypes()
   bei Mono.Cecil.MetadataBuilder.BuildTypes()
   bei Mono.Cecil.MetadataBuilder.BuildModule()
   bei Mono.Cecil.MetadataBuilder.BuildMetadata()
   bei Mono.Cecil.ModuleWriter.<>c.<BuildMetadata>b__2_0(MetadataBuilder builder, MetadataReader _)
   bei Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TItem item, Func`3 read)
   bei Mono.Cecil.ModuleWriter.Write(ModuleDefinition module, Disposable`1 stream, WriterParameters parameters)
   bei Mono.Cecil.ModuleWriter.WriteModule(ModuleDefinition module, Disposable`1 stream, WriterParameters parameters)
   bei Mono.Cecil.ModuleDefinition.Write(Stream stream, WriterParameters parameters)
   bei Xamarin.Android.Tasks.RemoveRegisterAttribute.RunTask() in /Users/runner/work/1/s/xamarin-android/src/Xamarin.Android.Build.Tasks/Tasks/RemoveRegisterAttribute.cs:Zeile 33.
   bei Microsoft.Android.Build.Tasks.AndroidTask.Execute() in /Users/runner/work/1/s/xamarin-android/external/xamarin-android-tools/src/Microsoft.Android.Build.BaseTasks/AndroidTask.cs:Zeile 25.
@uholeschak uholeschak added Area: App+Library Build Issues when building Library projects or Application projects. needs-triage Issues that need to be assigned. labels Dec 18, 2024
@jonathanpeppers
Copy link
Member

Can you attach a .binlog of the failure? https://aka.ms/binlog

You should be able to remove $(AndroidEnableMultiDex) completely as both d8 and r8 automatically do this for you.

@jonathanpeppers jonathanpeppers added need-info Issues that need more information from the author. and removed needs-triage Issues that need to be assigned. labels Dec 18, 2024
@jonathanpeppers jonathanpeppers added this to the Under Consideration milestone Dec 18, 2024
@uholeschak
Copy link
Author

I have created the logs when execution the publish operation in VS (when the error occurs).
The complete build logs before are not included to reduce the size.
MSBuildReproLogs.zip

@dotnet-policy-service dotnet-policy-service bot added need-attention A xamarin-android contributor needs to review and removed need-info Issues that need more information from the author. labels Dec 18, 2024
@jonathanpeppers
Copy link
Member

@uholeschak do you know how to cause this issue in a small sample?

My best guess is the code here:

using (var assembly = AssemblyDefinition.ReadAssembly (mono_android, new ReaderParameters { ReadWrite = true })) {

It doesn't setup SearchDirectories for Mono.Cecil, so if System.Private.CoreLib.dll needed to be loaded this is the error you would get.

But what type of code in your app would trigger this problem? We'd probably want to write a test to know it solves the problem and it doesn't return.

@jonathanpeppers jonathanpeppers added need-info Issues that need more information from the author. and removed need-attention A xamarin-android contributor needs to review labels Jan 21, 2025
@uholeschak
Copy link
Author

The problem is, that this is really a large application with many NuGet packages.
You could try to compile it yourself if you want (but the workaround above is applied, so the code is not executed during build):
https://github.com/uholeschak/ediabaslib/tree/master/BmwDeepObd
Basically I think RemoveRegisterAttribute is more or less optional. Would it be an option to simply ignore the error or convert it to a warning and continue?

@dotnet-policy-service dotnet-policy-service bot added need-attention A xamarin-android contributor needs to review and removed need-info Issues that need more information from the author. labels Jan 21, 2025
@jonmdev
Copy link

jonmdev commented Feb 17, 2025

I am now getting this error for unknown reasons. Suddenly I can no longer build to Release mode in Android for my project. I believe this happened now after I just updated Visual Studio 2022 in the past few days. Nothing in my project has changed to explain it. I was already on .NET 9 and everything was fine (don't know now what version), but then updating to the most recent version a few days ago seems to have broken it.

In any case, @uholeschak thank you so much for sharing your workaround and this thread. I made a Directory.Build.Props in the same folder as my sln file with your text content and I can at least build Release again in Android.

So thanks again. I spent hours trying to figure out the problem but got nowhere before I found your thread. Hopefully there will be some more formal solution but for now I can at least verify this worked for me temporarily as well. 👍

@uholeschak
Copy link
Author

This could be also cause by an NuGet update.
The problem is, that this is an error, but it has no real relevance. Converting it to a warning would be also a solution.

@dellis1972
Copy link
Contributor

@uholeschak

I tried building your app locally and I get

 CSC : error CS1566: Error reading resource 'BmwDeepObd.HexFiles.Type16.CanAdapterElm.X.production.hex' 

I assume there are some additional steps to generate these files?

@dellis1972 dellis1972 added need-info Issues that need more information from the author. and removed need-attention A xamarin-android contributor needs to review labels Feb 18, 2025
@uholeschak
Copy link
Author

uholeschak commented Feb 18, 2025

Basically you have to compile the binaries with a different tool first, but this is complicated.
Either extract the files from the binaries: https://github.com/uholeschak/ediabaslib/releases
or simply remove them from the solution. Thy are not needed to start the app.
I you want to add the Asset you could download it here:
https://holeschak.de/BmwDeepObd/Ecu.bin

@dotnet-policy-service dotnet-policy-service bot added need-attention A xamarin-android contributor needs to review and removed need-info Issues that need more information from the author. labels Feb 18, 2025
@dellis1972
Copy link
Contributor

I can repo the issue, I commented out all the EmbeddedResource entires in the csproj. As well as the PostBuild target, and the "patched" targets in Directory.Build.targets.

Then did dotnet build -c Release and it built fine.

can you do a dotnet --list-sdks so we can compare installed sdks.

@dellis1972 dellis1972 added need-info Issues that need more information from the author. and removed need-attention A xamarin-android contributor needs to review labels Feb 18, 2025
@uholeschak
Copy link
Author

As I have written in the into, the problem only occurs only if you publish the app.
The release build itself is not the problem.
You could either use an up to date emulator or smartphone for this.
The same problem occurs if you create an archive in Visual Studio.

@dotnet-policy-service dotnet-policy-service bot added need-attention A xamarin-android contributor needs to review and removed need-info Issues that need more information from the author. labels Feb 18, 2025
@dellis1972
Copy link
Contributor

So I tried

dotnet build -c Release
dotnet publish 

Also tried

dotnet build -c Release -t:Install`

and building the following from a clean tree.

dotnet publish 

Nothing, no errors. I have a PR which might fix the issue (#9803), but we can't merge that until I have a solid way to repo this outside of the IDE. I'll see if I can repo on a Windows VM, because on MacOS it seems fine.

@uholeschak
Copy link
Author

I did a dotnet workload update but the problem still persists.
I have only removed the patch targets but kept the upper property groups in the target file.

Output of dotnet --list-sdks:

1.0.0-preview1-002702 [C:\Program Files\dotnet\sdk]
1.0.0-preview2-003121 [C:\Program Files\dotnet\sdk]
1.0.0-preview2-003131 [C:\Program Files\dotnet\sdk]
2.1.2 [C:\Program Files\dotnet\sdk]
2.1.4 [C:\Program Files\dotnet\sdk]
2.1.100 [C:\Program Files\dotnet\sdk]
2.1.101 [C:\Program Files\dotnet\sdk]
2.1.102 [C:\Program Files\dotnet\sdk]
2.1.103 [C:\Program Files\dotnet\sdk]
2.1.104 [C:\Program Files\dotnet\sdk]
2.1.200 [C:\Program Files\dotnet\sdk]
2.1.201 [C:\Program Files\dotnet\sdk]
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.526 [C:\Program Files\dotnet\sdk]
2.1.617 [C:\Program Files\dotnet\sdk]
2.1.700 [C:\Program Files\dotnet\sdk]
2.1.701 [C:\Program Files\dotnet\sdk]
2.1.818 [C:\Program Files\dotnet\sdk]
3.0.102 [C:\Program Files\dotnet\sdk]
3.1.100 [C:\Program Files\dotnet\sdk]
3.1.120 [C:\Program Files\dotnet\sdk]
3.1.426 [C:\Program Files\dotnet\sdk]
5.0.104 [C:\Program Files\dotnet\sdk]
5.0.214 [C:\Program Files\dotnet\sdk]
5.0.303 [C:\Program Files\dotnet\sdk]
5.0.403 [C:\Program Files\dotnet\sdk]
5.0.406 [C:\Program Files\dotnet\sdk]
5.0.408 [C:\Program Files\dotnet\sdk]
6.0.302 [C:\Program Files\dotnet\sdk]
6.0.321 [C:\Program Files\dotnet\sdk]
7.0.100 [C:\Program Files\dotnet\sdk]
7.0.306 [C:\Program Files\dotnet\sdk]
9.0.103 [C:\Program Files\dotnet\sdk]

@jonpryor
Copy link
Member

My conjecture as to what's going on is that something is using a Cecil-based IL rewriter tool as a post-build step "somewhere", that rewriter calls ….ImportReference() on a type from System.Runtime.dll or some other facade assembly, but the type actually resides within System.Private.CoreLib.dll. If this were the end of it, it would be fine, as System.Private.CoreLib.dll exists at runtime. If that's not the end of it -- if the output of this IL rewriter is used as input to something that processes assemblies -- then things are not fine. System.Private.CoreLib.dll is not a public assembly, so it will not be found when looking for it in the "normal" set of directories that are checked.

Funnily enough, the relationship between the trimmer and the <RemoveRegisterAttribute/> is exactly as described above: the trimmer is a Cecil-based tool which updates assemblies, and the resulting assemblies reference System.Private.CoreLib. The <RemoveRegisterAttribute/> task operates on post-trimmed output, and thus will see System.Private.CoreLib references!

% dotnet new android
% dotnet build -c Release
% for a in obj/Release/net9.0-android/android-arm64/linked/shrunk/*.dll ; do \
  echo "## $a" ; \
  monodis --assemblyref $a | grep System.Private.CoreLib ; \
  done
## obj/Release/net9.0-android/android-arm64/linked/shrunk/Java.Interop.dll
	Name=System.Private.CoreLib
## obj/Release/net9.0-android/android-arm64/linked/shrunk/Mono.Android.Runtime.dll
	Name=System.Private.CoreLib
## obj/Release/net9.0-android/android-arm64/linked/shrunk/Mono.Android.dll
	Name=System.Private.CoreLib
## obj/Release/net9.0-android/android-arm64/linked/shrunk/System.Console.dll
	Name=System.Private.CoreLib
## obj/Release/net9.0-android/android-arm64/linked/shrunk/System.Linq.dll
	Name=System.Private.CoreLib
## obj/Release/net9.0-android/android-arm64/linked/shrunk/System.Private.CoreLib.dll
## obj/Release/net9.0-android/android-arm64/linked/shrunk/System.Runtime.InteropServices.dll
	Name=System.Private.CoreLib
## obj/Release/net9.0-android/android-arm64/linked/shrunk/System.Runtime.dll
	Name=System.Private.CoreLib
## obj/Release/net9.0-android/android-arm64/linked/shrunk/_Microsoft.Android.Resource.Designer.dll
	Name=System.Private.CoreLib
## obj/Release/net9.0-android/android-arm64/linked/shrunk/net9-android.dll
	Name=System.Private.CoreLib

which is to say, nearly every trimmed assembly contains a reference to System.Private.CoreLib.dll!

Yet this build is successful.

The approach in #9803 should improve matters, but I don't know if it would be a fix.

jonpryor pushed a commit that referenced this issue Feb 19, 2025
…9803)

Fixes? #9629

In #9629 the customer reports a build failure:

	XARRA7028: Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'
	   bei Mono.Cecil.BaseAssemblyResolver.Resolve(AssemblyNameReference name, ReaderParameters parameters)
	   bei Mono.Cecil.DefaultAssemblyResolver.Resolve(AssemblyNameReference name)
	   bei Mono.Cecil.MetadataResolver.Resolve(TypeReference type)
	   bei Mono.Cecil.TypeReference.Resolve()
	   bei Mono.Cecil.Mixin.CheckedResolve(TypeReference self)
	   bei Mono.Cecil.MetadataBuilder.GetConstantType(TypeReference constant_type, Object constant)
	   bei Mono.Cecil.MetadataBuilder.AddConstant(IConstantProvider owner, TypeReference type)
	   bei Mono.Cecil.MetadataBuilder.AddField(FieldDefinition field)
	   bei Mono.Cecil.MetadataBuilder.AddFields(TypeDefinition type)
	   bei Mono.Cecil.MetadataBuilder.AddType(TypeDefinition type)
	   bei Mono.Cecil.MetadataBuilder.AddTypes()
	   bei Mono.Cecil.MetadataBuilder.BuildTypes()
	   bei Mono.Cecil.MetadataBuilder.BuildModule()
	   bei Mono.Cecil.MetadataBuilder.BuildMetadata()
	   bei Mono.Cecil.ModuleWriter.<>c.<BuildMetadata>b__2_0(MetadataBuilder builder, MetadataReader _)
	   bei Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TItem item, Func`3 read)
	   bei Mono.Cecil.ModuleWriter.Write(ModuleDefinition module, Disposable`1 stream, WriterParameters parameters)
	   bei Mono.Cecil.ModuleWriter.WriteModule(ModuleDefinition module, Disposable`1 stream, WriterParameters parameters)
	   bei Mono.Cecil.ModuleDefinition.Write(Stream stream, WriterParameters parameters)
	   bei Xamarin.Android.Tasks.RemoveRegisterAttribute.RunTask() in /Users/runner/work/1/s/xamarin-android/src/Xamarin.Android.Build.Tasks/Tasks/RemoveRegisterAttribute.cs:Zeile 33.
	   bei Microsoft.Android.Build.Tasks.AndroidTask.Execute() in /Users/runner/work/1/s/xamarin-android/external/xamarin-android-tools/src/Microsoft.Android.Build.BaseTasks/AndroidTask.cs:Zeile 25.

We are unable to reproduce this, and the scenario doesn't quite make
sense to us: the `<RemoveRegisterAttribute/>` task operates on post-
trimmed assemblies, *nearly all of which* will contain a reference to
`System.Private.CorLib.dll` [^1].  Why does this work of us (and CI!
and most other customers!) and fail in this instance?

¯\\_(ツ)_/¯

Meanwhile, we do know of a plausible "fix"/"workaround": add the use
of a `DirectoryAssemblyResolver` which contains the directory
containing the assembly we're processing.
The `$(IntermediateOutputPath)android-*/linked/shrunk` should also
contain a `System.Private.CoreLib.dll` [^1], which will allow it to
be resolved, thus avoiding the `AssemblyResolutionException`.

[^1]: Consider:
      ```
      for a in obj/Release/net9.0-android/android-arm64/linked/shrunk/*.dll ; do \
        echo "Assembly: $a" ; \
        monodis --assemblyref $a | grep System.Private.CoreLib ; \
        done
      Assembly: obj/Release/net9.0-android/android-arm64/linked/shrunk/Java.Interop.dll
        Name=System.Private.CoreLib
      Assembly: obj/Release/net9.0-android/android-arm64/linked/shrunk/Mono.Android.Runtime.dll
        Name=System.Private.CoreLib
      Assembly: obj/Release/net9.0-android/android-arm64/linked/shrunk/Mono.Android.dll
        Name=System.Private.CoreLib
      Assembly: obj/Release/net9.0-android/android-arm64/linked/shrunk/System.Console.dll
        Name=System.Private.CoreLib
      Assembly: obj/Release/net9.0-android/android-arm64/linked/shrunk/System.Linq.dll
        Name=System.Private.CoreLib
      Assembly: obj/Release/net9.0-android/android-arm64/linked/shrunk/System.Private.CoreLib.dll
      Assembly: obj/Release/net9.0-android/android-arm64/linked/shrunk/System.Runtime.InteropServices.dll
        Name=System.Private.CoreLib
      Assembly: obj/Release/net9.0-android/android-arm64/linked/shrunk/System.Runtime.dll
        Name=System.Private.CoreLib
      Assembly: obj/Release/net9.0-android/android-arm64/linked/shrunk/_Microsoft.Android.Resource.Designer.dll
        Name=System.Private.CoreLib
      Assembly: obj/Release/net9.0-android/android-arm64/linked/shrunk/net9-android.dll
        Name=System.Private.CoreLib
      ```
@uholeschak
Copy link
Author

When will this be this published? Then I could try again ...

@jonpryor
Copy link
Member

@uholeschak asked:

When will this be this published? Then I could try again ...

It should be published as part of .NET 10 Preview 2, sometime in March.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: App+Library Build Issues when building Library projects or Application projects. need-attention A xamarin-android contributor needs to review
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants