Skip to content

XARRA7028 AssemblyResolutionException in Android App Release Build #9803

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

Merged
merged 1 commit into from
Feb 19, 2025

Conversation

dellis1972
Copy link
Contributor

Fixes #9629

Add the use of the DirectoryAssemblyResolver to make sure we can handle issues such as

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.

Comment on lines +29 to +30
using var resolver = new DirectoryAssemblyResolver (this.CreateTaskLogger (), loadDebugSymbols: false, loadReaderParameters: new ReaderParameters { ReadWrite = true });
resolver.SearchDirectories.Add (path);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did they share a project or a repro? I was wondering if a specific NuGet package causes this problem, which would let us add a test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They didn't

@jonpryor
Copy link
Contributor

[Xamarin.Android.Build.Tasks] Cecil should use an assembly resolver (#9803)

Fixes? https://github.com/dotnet/android/issues/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
      ```

@jonpryor
Copy link
Contributor

@dellis1972: please review the draft commit message, above.

Additionally, this change makes me think we should review our use of AssemblyDefinition.ReadAssembly:

% git grep AssemblyDefinition.ReadAssembly src/Xamarin.Android.Build.Tasks | grep -v Tests/src/Xamarin.Android.Build.Tasks/Linker/External/Linker/LinkContext.cs:					return AssemblyDefinition.ReadAssembly (name, _readerParameters);
src/Xamarin.Android.Build.Tasks/Tasks/GenerateManagedAidlProxies.cs:				var ret = tool.Run (opts, assemblyFile => AssemblyDefinition.ReadAssembly (assemblyFile), (dir, file) => {
src/Xamarin.Android.Build.Tasks/Tasks/RemoveRegisterAttribute.cs:			using (var assembly = AssemblyDefinition.ReadAssembly (mono_android, new ReaderParameters { ReadWrite = true })) {
src/Xamarin.Android.Build.Tasks/Utilities/XAAssemblyResolver.cs:	AssemblyDefinition ReadAssembly (string filePath, ReaderParameters? readerParametersOverride = null)
src/Xamarin.Android.Build.Tasks/Utilities/XAAssemblyResolver.cs:			return AssemblyDefinition.ReadAssembly (file, options);

Which raises some questions:

  1. Should we instead use XAAssemblyResolver instead of DirectoryAssemblyResolver? (I forget why we have two of these running around…)
  2. Should <GenerateManagedAidlProxies/> be updated to use an IAssemblyResolver as well?
  3. I'm giving a side-eye to LinkContext.cs, and wonder if that should be updated as well.

@dellis1972
Copy link
Contributor Author

@jonpryor

The commit messages looks good.

I think we should review the usage, but lets do that in a different PR.

@jonpryor jonpryor merged commit d012fb8 into main Feb 19, 2025
58 checks passed
@jonpryor jonpryor deleted the dev/dellis1972/Issue9629 branch February 19, 2025 18:07
grendello added a commit that referenced this pull request Feb 20, 2025
* main:
  [Xamarin.Android.Build.Tasks] RemoveRegisterAttr IAssemblyResolver (#9803)
@github-actions github-actions bot locked and limited conversation to collaborators Mar 22, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

XARRA7028 AssemblyResolutionException in Android App Release Build
3 participants