Skip to content

"Could not load file or assembly 'System.Runtime.Loader'..." if project attempts to use a type from System.Runtime.Loader NuGet package #3016

@brendanzagaeski

Description

@brendanzagaeski

This is a follow-up to https://developercommunity.visualstudio.com/content/problem/330758/exception-while-loading-assembly.html and the candidate fix #2770. The initial candidate fix by itself doesn't behave quite as expected. It looks the problem might be that the System.Runtime.Loader NuGet package itself is breaking some rules.

That said, this issue might not be too urgent. The current candidate fix from #2770 might still help most users because it will allow building libraries that themselves have a dependency on the System.Runtime.Loader NuGet package, as long as the final application never attempts to call any code paths that depend on the System.Runtime.Loader functionality at run time.

Possible Workaround

The following approach allows me to build and run the test case successfully. Do note though that the System.Runtime.Loader.AssemblyLoadContext class on Xamarin.Android only provides empty method implementations at the moment. So within libraries that depend on System.Runtime.Loader, any individual methods that call the AssemblyLoadContext APIs will not yet be compatible with Xamarin.Android.

Copy the lib\MonoAndroid10 placeholder directory in the NuGet package into the ref directory:

Copy-Item -Recurse "$env:USERPROFILE\.nuget\packages\system.runtime.loader\4.3.0\lib\MonoAndroid10" "$env:USERPROFILE\.nuget\packages\system.runtime.loader\4.3.0\ref\"

(After this change, you'll need to delete obj\project.assets.json from the test case to force a new NuGet restore.)

This causes the generated entry in obj\project.assets.json to change:

 "targets": {
   "MonoAndroid,Version=v8.1": {
     "System.Runtime.Loader/4.3.0": {
       "type": "package",
       "compile": {
-        "ref/netstandard1.5/System.Runtime.Loader.dll": {}
+        "ref/MonoAndroid10/_._": {}
       },
       "runtime": {
         "lib/MonoAndroid10/_._": {}
       }
     }
   }

My suspicion is that it's unintentional that the NuGet package tells the <Csc/> task to compile against the ref/netstandard1.5/System.Runtime.Loader.dll reference assembly (via the compile item) when it also tells the later build steps not to include any copy of System.Runtime.Loader.dll in the output folder at all (via the runtime item). Considering that the System.Runtime.Loader NuGet package was last updated in November 2016, it seems possible that this just an old unintentional hiccup with how the package was built. (For comparison, the way reference assemblies are used in the System.Memory NuGet package has changed three times since May 2018, across versions 4.5.0, 4.5.1, and 4.5.2.)

Steps to Reproduce

Run the attached test case in the Debug configuration, or attempt to build it in the Release configuration.

Expected Behavior

The application builds and runs without error.

Actual Behavior

In the Debug configuration, the application launches on device, but then hits an exception when it attempts to use the System.Runtime.Loader assembly:

UNHANDLED EXCEPTION:
System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime.Loader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
File name: 'System.Runtime.Loader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
  at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x00011] in <f95ee0ae61c542ec8b3977bd76c1c5ab>:0
  at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.3(intptr,intptr,intptr)

In the Release configuration, the <LinkAssemblies/> task catches the problem during the build instead:

The "LinkAssemblies" task failed unexpectedly.
System.IO.FileNotFoundException: Could not load assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Perhaps it doesn't exist in the Mono for Android profile?
File name: 'System.Runtime.dll'
   at Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(AssemblyNameReference reference, ReaderParameters parameters)
   at Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(AssemblyNameReference reference)
   at Mono.Cecil.MetadataResolver.Resolve(TypeReference type)
   at Mono.Cecil.ModuleDefinition.Resolve(TypeReference type)
   at Mono.Cecil.TypeReference.Resolve()
   at Mono.Cecil.Mixin.CheckedResolve(TypeReference self)
   at Mono.Cecil.SignatureReader.ReadCustomAttributeEnum(TypeReference enum_type)
   at Mono.Cecil.SignatureReader.ReadCustomAttributeElementValue(TypeReference type)
   at Mono.Cecil.SignatureReader.ReadCustomAttributeElement(TypeReference type)
   at Mono.Cecil.SignatureReader.ReadCustomAttributeFixedArgument(TypeReference type)
   at Mono.Cecil.SignatureReader.ReadCustomAttributeConstructorArguments(CustomAttribute attribute, Collection`1 parameters)
   at Mono.Cecil.MetadataReader.ReadCustomAttributeSignature(CustomAttribute attribute)
   at Mono.Cecil.CustomAttribute.<Resolve>b__35_0(CustomAttribute attribute, MetadataReader reader)
   at Mono.Cecil.ModuleDefinition.Read[TItem](TItem item, Action`2 read)
   at Mono.Cecil.CustomAttribute.Resolve()
   at Mono.Cecil.CustomAttribute.get_HasConstructorArguments()
   at Mono.Tuner.CustomizeActions.IsPreservedAttribute(CustomAttribute attribute)
   at Mono.Tuner.CustomizeActions.IsSkipped(AssemblyDefinition assembly)
   at Mono.Tuner.CustomizeActions.ProcessAssembly(AssemblyDefinition assembly)
   at Mono.Linker.Steps.BaseStep.Process(LinkContext context)
   at Mono.Linker.Pipeline.Process(LinkContext context)
   at MonoDroid.Tuner.Linker.Process(LinkerOptions options, ILogger logger, LinkContext& context)
   at Xamarin.Android.Tasks.LinkAssemblies.Execute(DirectoryAssemblyResolver res)
   at Xamarin.Android.Tasks.LinkAssemblies.Execute()
   at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
   at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext()

Version Information

Xamarin.Android SDK 9.3.0.14 (HEAD/f3f2aeb7a)

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions