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

"FileNotFoundException: Could not load assembly 'System.Runtime..." during LinkAssemblies for projects that depend indirectly on System.Runtime.CompilerServices #3045

Closed
brendanzagaeski opened this issue Apr 30, 2019 · 5 comments · Fixed by #3053
Assignees
Labels
Area: App+Library Build Issues when building Library projects or Application projects. bug Component does not function as intended. vs-sync For internal use only; creates a VSTS "mirror" issue.
Milestone

Comments

@brendanzagaeski
Copy link
Contributor

brendanzagaeski commented Apr 30, 2019

Motivating Developer Community item: https://developercommunity.visualstudio.com/content/problem/551186/android-build-failed-on-linker-systemruntime-even.html

That report is based on the project in https://github.com/jamesmontemagno/AllExtensions-DI-IoC

This is a change in behavior between xamarin-android-9.2.3.0 and xamarin-android.9.3.0.14. I noticed a difference in the output of the <ResolveAssemblies/> task between those two versions, so I tested the commits between those versions that modified ResolveAssemblies.cs and found that this problem started with the switch to System.Reflection.Metadata in xamarin-android/master@c22475d7. I'm not sure yet if this is revealing a different problem that was in the build process for longer or if the new behavior of ResolveAssemblies is slightly incorrect.

Steps to Reproduce

Attempt to build the attached test case in the Debug configuration. This is just an empty Xamarin.Android project with the Microsoft.Extensions.Http NuGet package added.

Expected Behavior, as seen with xamarin-android/master@974cf7d

The project builds without error. The build logs show that the <ResolveAssemblies/> task adds System.Runtime for System.Runtime.CompilerServices:

Adding assembly reference for System.Runtime.CompilerServices.Unsafe, Version=4.0.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, recursively... (TaskId:173)
  Adding assembly reference for System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, recursively... (TaskId:173)
Adding assembly reference for System.Xml, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, recursively... (TaskId:173)

Actual Behavior in Visual Studio 2019 version 16.1 Preview 2 and xamarin-android/master@c22475d7

The <LinkAssemblies/> task fails because it fails to locate the System.Runtime assembly:

C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2146,5): error MSB4018: The "LinkAssemblies" task failed unexpectedly.
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2146,5): error MSB4018: 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?

The build log shows that <ResolveAssemblies/> task does not add System.Runtime for System.Runtime.CompilerServices:

Adding assembly reference for System.Runtime.CompilerServices.Unsafe, recursively... (TaskId:173)
Adding assembly reference for System.Xml, recursively... (TaskId:173)

Log File

buildlogs.zip

VS bug #859946

@brendanzagaeski brendanzagaeski added bug Component does not function as intended. Area: App+Library Build Issues when building Library projects or Application projects. regression labels Apr 30, 2019
@brendanzagaeski brendanzagaeski added this to the d16-1 milestone Apr 30, 2019
@brendanzagaeski brendanzagaeski added the vs-sync For internal use only; creates a VSTS "mirror" issue. label Apr 30, 2019
@jonathanpeppers
Copy link
Member

jonathanpeppers commented Apr 30, 2019

@brendanzagaeski was the test case working for you with latest xamarin-android/master (or 16.2)? It worked for me.

I'm afraid that it might be mono-2019-02 that is fixing the problem here...

Binlog using xamarin-android/master: msbuild.zip

@BrennanConroy
Copy link
Member

We're hitting this issue while trying to test SignalR bits against Xamarin. Is there a temporary workaround for this locally so we can continue with testing?

@brendanzagaeski
Copy link
Contributor Author

was the test case working for you with latest xamarin-android/master (or 16.2)?

Innnteresting. I hadn't tried with master or d16-2 yet. I'll try that now to help confirm that I get the same improved behavior on those versions. At first glance, it looks like it is indeed being fixed a different way in master because the line about adding System.Runtime in your log file from master is now its own "top-level" line instead of being indented under System.Runtime.CompilerServices.Unsafe:

    Adding assembly reference for System.Runtime.CompilerServices.Unsafe, recursively... (TaskId:211)
    Adding assembly reference for System.Runtime, recursively... (TaskId:211)
    Adding assembly reference for System.Xml, recursively... (TaskId:211)

@brendanzagaeski
Copy link
Contributor Author

brendanzagaeski commented Apr 30, 2019

Is there a temporary workaround for this

One quick-and-dirty idea that let me stop the error in local experiments (partly just to help me double-check the role of the <ResolveAssemblies/> task) was to add an explicit @(FilteredAssemblies) item for the System.Runtime.dll facade assembly in the .csproj file:

when working on Windows

<ItemGroup>
    <FilteredAssemblies Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v1.0\Facades\System.Runtime.dll" />
</ItemGroup>

when on macOS

  <ItemGroup>
    <FilteredAssemblies Include="/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/Facades/System.Runtime.dll" />
  </ItemGroup>

As a caution, until the investigation is complete for this issue, I'd be hesitant to say this is necessarily a correct fix, but I suspect it would be OK to use for temporary testing purposes.

@jonathanpeppers
Copy link
Member

I think master is working, because it's just "lucky", here is a comparison: https://www.diffchecker.com/4lcQRLiN

I have a local build of 16.1, and it seems that <ResolveAssemblies/> sees netstandard as a reference of System.Runtime.CompilerServices.Unsafe when it should be seeing System.Runtime. Somehow it is looking at the reference assembly instead of the real assembly.

jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue May 1, 2019
Fixes: dotnet#3045

In VS 2019 16.1 Preview, a project using `Microsoft.Extensions.Http`
fails to build with:

    C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2146,5): error MSB4018: 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 Java.Interop.Tools.Cecil.TypeDefinitionRocks.<GetTypeAndBaseTypes>d__1.MoveNext()
        at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
        at Java.Interop.Tools.Cecil.TypeDefinitionRocks.IsSubclassOf(TypeDefinition type, String typeName)
        at MonoDroid.Tuner.FixAbstractMethodsStep.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() [C:\Temp\ResolveAssembliesSystemRuntime\AndroidApp1\AndroidApp1.csproj]

The problem being, that the `<ResolveAssemblies/>` MSBuild task didn't
return `System.Runtime.dll` in `@(ResolvedAssemblies)`.

What further complicated matters, was that the same project was
working with latest xamarin-android/master (16.2)? I was only able to
reproduce the problem in a test after some work to create a project
that only has a `<PackageReference/>` to ``Microsoft.Extensions.Http`
with no other references *at all*. I had to do some MSBuild trickery
to remove `Java.Interop` and `System.Runtime` references.

Looking at the dependency tree in the failing test,
`System.Runtime.CompilerServices.Unsafe.dll` should be reporting a
reference to `System.Runtime.dll`. Through debugging, I saw it only
had a reference to `netstandard.dll`?

Then I realized there were two assemblies:

    ~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\ref\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
    ~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll

The "ref" assembly, references `netstandard.dll` and the "lib"
assembly (that we should be using) references `System.Runtime.dll`.

Through further debugging, I found two bugs here:

* We shouldn't call `resolver.AddSearchDirectory` until *after* we've
  checked if the top-level assembly is a reference assembly. We don't
  want a reference assembly in the search paths!
* `MetadataResolver` should key its cache on the resolved path to the
  assembly. This allows `<ResolveAssemblies/>` to open two *different*
  instances of `System.Runtime.CompilerServices.Unsafe`.
dellis1972 pushed a commit that referenced this issue May 1, 2019
…#3053)

Fixes: #3045

In VS 2019 16.1 Preview, a project using `Microsoft.Extensions.Http`
fails to build with:

    C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2146,5): error MSB4018: 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 Java.Interop.Tools.Cecil.TypeDefinitionRocks.<GetTypeAndBaseTypes>d__1.MoveNext()
        at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
        at Java.Interop.Tools.Cecil.TypeDefinitionRocks.IsSubclassOf(TypeDefinition type, String typeName)
        at MonoDroid.Tuner.FixAbstractMethodsStep.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() [C:\Temp\ResolveAssembliesSystemRuntime\AndroidApp1\AndroidApp1.csproj]

The problem being, that the `<ResolveAssemblies/>` MSBuild task didn't
return `System.Runtime.dll` in `@(ResolvedAssemblies)`.

What further complicated matters, was that the same project was
working with latest xamarin-android/master (16.2)? I was only able to
reproduce the problem in a test after some work to create a project
that only has a `<PackageReference/>` to ``Microsoft.Extensions.Http`
with no other references *at all*. I had to do some MSBuild trickery
to remove `Java.Interop` and `System.Runtime` references.

Looking at the dependency tree in the failing test,
`System.Runtime.CompilerServices.Unsafe.dll` should be reporting a
reference to `System.Runtime.dll`. Through debugging, I saw it only
had a reference to `netstandard.dll`?

Then I realized there were two assemblies:

    ~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\ref\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
    ~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll

The "ref" assembly, references `netstandard.dll` and the "lib"
assembly (that we should be using) references `System.Runtime.dll`.

Through further debugging, I found two bugs here:

* We shouldn't call `resolver.AddSearchDirectory` until *after* we've
  checked if the top-level assembly is a reference assembly. We don't
  want a reference assembly in the search paths!
* `MetadataResolver` should key its cache on the resolved path to the
  assembly. This allows `<ResolveAssemblies/>` to open two *different*
  instances of `System.Runtime.CompilerServices.Unsafe`.
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue May 2, 2019
…dotnet#3053)

Fixes: dotnet#3045

In VS 2019 16.1 Preview, a project using `Microsoft.Extensions.Http`
fails to build with:

    C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2146,5): error MSB4018: 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 Java.Interop.Tools.Cecil.TypeDefinitionRocks.<GetTypeAndBaseTypes>d__1.MoveNext()
        at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
        at Java.Interop.Tools.Cecil.TypeDefinitionRocks.IsSubclassOf(TypeDefinition type, String typeName)
        at MonoDroid.Tuner.FixAbstractMethodsStep.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() [C:\Temp\ResolveAssembliesSystemRuntime\AndroidApp1\AndroidApp1.csproj]

The problem being, that the `<ResolveAssemblies/>` MSBuild task didn't
return `System.Runtime.dll` in `@(ResolvedAssemblies)`.

What further complicated matters, was that the same project was
working with latest xamarin-android/master (16.2)? I was only able to
reproduce the problem in a test after some work to create a project
that only has a `<PackageReference/>` to ``Microsoft.Extensions.Http`
with no other references *at all*. I had to do some MSBuild trickery
to remove `Java.Interop` and `System.Runtime` references.

Looking at the dependency tree in the failing test,
`System.Runtime.CompilerServices.Unsafe.dll` should be reporting a
reference to `System.Runtime.dll`. Through debugging, I saw it only
had a reference to `netstandard.dll`?

Then I realized there were two assemblies:

    ~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\ref\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
    ~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll

The "ref" assembly, references `netstandard.dll` and the "lib"
assembly (that we should be using) references `System.Runtime.dll`.

Through further debugging, I found two bugs here:

* We shouldn't call `resolver.AddSearchDirectory` until *after* we've
  checked if the top-level assembly is a reference assembly. We don't
  want a reference assembly in the search paths!
* `MetadataResolver` should key its cache on the resolved path to the
  assembly. This allows `<ResolveAssemblies/>` to open two *different*
  instances of `System.Runtime.CompilerServices.Unsafe`.
jonpryor pushed a commit that referenced this issue May 2, 2019
…#3053) (#3062)

Fixes: #3045

In VS 2019 16.1 Preview, a project using `Microsoft.Extensions.Http`
fails to build with:

	C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2146,5): error MSB4018: 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 Java.Interop.Tools.Cecil.TypeDefinitionRocks.<GetTypeAndBaseTypes>d__1.MoveNext()
	    at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
	    at Java.Interop.Tools.Cecil.TypeDefinitionRocks.IsSubclassOf(TypeDefinition type, String typeName)
	    at MonoDroid.Tuner.FixAbstractMethodsStep.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() [C:\Temp\ResolveAssembliesSystemRuntime\AndroidApp1\AndroidApp1.csproj]

The problem being that the `<ResolveAssemblies/>` MSBuild task didn't
return `System.Runtime.dll` in `@(ResolvedAssemblies)`.

What further complicated matters, was that the same project was
working with latest xamarin-android/master (16.2)? I was only able to
reproduce the problem in a test after some work to create a project
that only has a `<PackageReference/>` to `Microsoft.Extensions.Http`
with no other references *at all*. I had to do some MSBuild trickery
to remove `Java.Interop` and `System.Runtime` references.

Looking at the dependency tree in the failing test,
`System.Runtime.CompilerServices.Unsafe.dll` should be reporting a
reference to `System.Runtime.dll`. Through debugging, I saw it only
had a reference to `netstandard.dll`?

Then I realized there were two assemblies:

	~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\ref\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
	~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll

The "ref" assembly, references `netstandard.dll` and the "lib"
assembly (that we should be using) references `System.Runtime.dll`.

Through further debugging, I found two bugs here:

  * We shouldn't call `resolver.AddSearchDirectory()` until *after*
    we've checked if the top-level assembly is a reference assembly.
    We don't want a reference assembly in the search paths!
  * `MetadataResolver` should key its cache on the resolved path to
    the assembly.  This allows `<ResolveAssemblies/>` to open two
    *different* instances of `System.Runtime.CompilerServices.Unsafe`.
jonathanpeppers added a commit that referenced this issue May 3, 2019
…#3053)

Fixes: #3045

In VS 2019 16.1 Preview, a project using `Microsoft.Extensions.Http`
fails to build with:

    C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2146,5): error MSB4018: 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 Java.Interop.Tools.Cecil.TypeDefinitionRocks.<GetTypeAndBaseTypes>d__1.MoveNext()
        at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
        at Java.Interop.Tools.Cecil.TypeDefinitionRocks.IsSubclassOf(TypeDefinition type, String typeName)
        at MonoDroid.Tuner.FixAbstractMethodsStep.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() [C:\Temp\ResolveAssembliesSystemRuntime\AndroidApp1\AndroidApp1.csproj]

The problem being, that the `<ResolveAssemblies/>` MSBuild task didn't
return `System.Runtime.dll` in `@(ResolvedAssemblies)`.

What further complicated matters, was that the same project was
working with latest xamarin-android/master (16.2)? I was only able to
reproduce the problem in a test after some work to create a project
that only has a `<PackageReference/>` to ``Microsoft.Extensions.Http`
with no other references *at all*. I had to do some MSBuild trickery
to remove `Java.Interop` and `System.Runtime` references.

Looking at the dependency tree in the failing test,
`System.Runtime.CompilerServices.Unsafe.dll` should be reporting a
reference to `System.Runtime.dll`. Through debugging, I saw it only
had a reference to `netstandard.dll`?

Then I realized there were two assemblies:

    ~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\ref\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
    ~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll

The "ref" assembly, references `netstandard.dll` and the "lib"
assembly (that we should be using) references `System.Runtime.dll`.

Through further debugging, I found two bugs here:

* We shouldn't call `resolver.AddSearchDirectory` until *after* we've
  checked if the top-level assembly is a reference assembly. We don't
  want a reference assembly in the search paths!
* `MetadataResolver` should key its cache on the resolved path to the
  assembly. This allows `<ResolveAssemblies/>` to open two *different*
  instances of `System.Runtime.CompilerServices.Unsafe`.
jonpryor pushed a commit that referenced this issue May 3, 2019
…#3053)

Fixes: #3045

In VS 2019 16.1 Preview, a project using `Microsoft.Extensions.Http`
fails to build with:

    C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2146,5): error MSB4018: 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 Java.Interop.Tools.Cecil.TypeDefinitionRocks.<GetTypeAndBaseTypes>d__1.MoveNext()
        at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
        at Java.Interop.Tools.Cecil.TypeDefinitionRocks.IsSubclassOf(TypeDefinition type, String typeName)
        at MonoDroid.Tuner.FixAbstractMethodsStep.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() [C:\Temp\ResolveAssembliesSystemRuntime\AndroidApp1\AndroidApp1.csproj]

The problem being, that the `<ResolveAssemblies/>` MSBuild task didn't
return `System.Runtime.dll` in `@(ResolvedAssemblies)`.

What further complicated matters, was that the same project was
working with latest xamarin-android/master (16.2)? I was only able to
reproduce the problem in a test after some work to create a project
that only has a `<PackageReference/>` to ``Microsoft.Extensions.Http`
with no other references *at all*. I had to do some MSBuild trickery
to remove `Java.Interop` and `System.Runtime` references.

Looking at the dependency tree in the failing test,
`System.Runtime.CompilerServices.Unsafe.dll` should be reporting a
reference to `System.Runtime.dll`. Through debugging, I saw it only
had a reference to `netstandard.dll`?

Then I realized there were two assemblies:

    ~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\ref\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
    ~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll

The "ref" assembly, references `netstandard.dll` and the "lib"
assembly (that we should be using) references `System.Runtime.dll`.

Through further debugging, I found two bugs here:

* We shouldn't call `resolver.AddSearchDirectory` until *after* we've
  checked if the top-level assembly is a reference assembly. We don't
  want a reference assembly in the search paths!
* `MetadataResolver` should key its cache on the resolved path to the
  assembly. This allows `<ResolveAssemblies/>` to open two *different*
  instances of `System.Runtime.CompilerServices.Unsafe`.
@ghost ghost locked as resolved and limited conversation to collaborators Jun 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: App+Library Build Issues when building Library projects or Application projects. bug Component does not function as intended. vs-sync For internal use only; creates a VSTS "mirror" issue.
Projects
None yet
4 participants