Runtime: System.Runtime.CompilerServices.Unsafe causing issues with ASP.NET Core 2.0.0 and netcoreapp2.1

Created on 12 Sep 2017  路  10Comments  路  Source: dotnet/runtime

I'm getting assembly load failures like the following trying to use ASP.NET Core 2.0.0 with netcoreapp2.1

System.IO.FileLoadException: Could not load file or assembly 'System.R untime.CompilerServices.Unsafe, Version=4.0.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly 's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

I'm not sure if this is the right place for this issue, but the System.Runtime.CompilerServices.Unsafe assembly recently moved from a package (netcoreapp2.0) into the shared runtime (netcoreapp2.1) and it appears to not be working gracefully with bits that were compiled against it in 2.0.0 (which ASP.NET Core does).

Repro
git clone aspnet/JitBench
git checkout rel/2.0.0

Follow steps 1-4 https://github.com/aspnet/JitBench/blob/rel/2.0.0/README.md
dotnet run

At this point you'll see a bunch of exception messages as it can't load the System.Runtime.CompilerServices.Unsafe assembly

/cc @eerhardt @ericstj

area-Infrastructure-libraries bug

Most helpful comment

FYI, I've recently been doing some work around these overlapping packages that have recently been added to core.app in 2.1: https://github.com/dotnet/corefx/pull/23719

A simpler workaround here is to just do the following in the app:

<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.4.0" ExcludeAssets="all" />

All 10 comments

The issue appears to be that the System.Runtime.CompilerServices.Unsafe.dll runtime assembly is not getting removed from the .deps.json file.

      "System.Runtime.CompilerServices.Unsafe/4.4.0": {
        "runtime": {
          "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll": {}
        }
      },

Thus, the host is loading the 4.4.0 NuGet version (which is AssemblyVersion 4.0.3.0 from the "store" (i.e. the version that ASP.NET references).

However, later some code in the runtime (System.Memory.dll System.SpanExtensions) needs to load the newer version (AssemblyVersion 4.0.4.0) and it is failing to load.

If I remove the "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll": {} line from the .deps.json file, the app runs successfully.

I think the PlatformManifest.txt file that ships in Microsoft.NETCore.App should be telling the tooling to conflict resolve System.Runtime.CompilerServices.Unsafe.dll, but that doesn't appear to be the case.

Investigating why the tooling is leaving this entry in the .deps.json file.

From the build log:

Encountered conflict between 'Platform:System.Runtime.CompilerServices.Unsafe.dll' and 'Runtime:C:\Users\eerhardt\.nuget\packages\system.runtime.compilerservices.unsafe\4.4.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll'. Could not determine a winner because 'Platform:System.Runtime.CompilerServices.Unsafe.dll' is not an assembly. (TaskId:15).

/cc @dsplaisted

The reason conflict resolution thinks it is "not an assembly" is because it doesn't have an assembly version. Looking at the PlatformManifest.txt file:

System.Resources.Writer.dll|Microsoft.NETCore.App|4.1.1.0|4.6.25610.2
System.Runtime.CompilerServices.Unsafe.dll|Microsoft.NETCore.App||0.0.0.0
System.Runtime.CompilerServices.VisualC.dll|Microsoft.NETCore.App|4.1.1.0|4.6.25610.2

where the columns are fileName | packageId | assemblyVersion | fileVersion.

We will need to put an assembly version in for CompilerServices.Unsafe. I'll see if I can get a change prepared for this.

Thanks Eric! Is there anything we can do to work around this temporarily other than hacking files we're not supposed to touch?

2 workarounds I can think of:

  1. Changing the .nuget\packages\microsoft.netcore.app\2.1.0-preview2-25616-02\build\netcoreapp2.1\Microsoft.NETCore.App.PlatformManifest.txt
  2. Changing the outputted .\bin\Debug\netcoreapp2.1\MusicStore.deps.json

In general, both of those files shouldn't be touched....

I could imagine some MSBuild Target could be injected into your .csproj to modify the .deps.json file, which would be less of a hack. How bad do you want a temporary fix?

FYI, I've recently been doing some work around these overlapping packages that have recently been added to core.app in 2.1: https://github.com/dotnet/corefx/pull/23719

A simpler workaround here is to just do the following in the app:

<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.4.0" ExcludeAssets="all" />

If this can be addressed in the next few days I don't think I need a workaround. It sounds like the fix is known/easy on your side so I can wait for a build to come out.

Looks like my comment happened concurrent with @ericstj 's suggestion. I'll give that a try.

Yep, ExcludeAssets="all" does the trick. Thanks!

More info on the issue:

It appears that we aren't writing the AssemblyVersion and FileVersion for this assembly because of 2 issues.

  1. This assembly doesn't have a FileVersion.
    image
    @mellinoe is going to log a separate bug on this.
  2. There is a bug in our custom MSBuild task that is writing the PlatformManifest file. It doesn't update the entry when there isn't a FileVersion.
    https://github.com/dotnet/core-setup/blob/master/tools-local/tasks/GenerateFileVersionProps.cs#L61-L79
    The way the logic works, the first entry goes in with AssemblyVersion=null, FileVersion=0.0.0.0. On subsequent iterations, we have a valid AssemblyVersion, but since the existing.AssemblyVersion entry is null, it isn't getting updated. For all the other assemblies, they have valid FileVersions, and existing.FileVersion is 0.0.0.0 instead of null. So the 2nd if check kicks in and updates the entry. However, since this assembly doesn't have a FileVersion, it is failing to get updated.

I'll use this issue to fix the 2nd issue above. We will have a separate issue to deal with the 1st.

Was this page helpful?
0 / 5 - 0 ratings