NuGet / Home

Repo for NuGet Client issues
Other
1.49k stars 250 forks source link

Grpc.Net.Common .NETStandard is missing "Grpc.Net.Compression.DeflateCompressionProvider" #12084

Closed maksperovpm closed 1 year ago

maksperovpm commented 1 year ago

Impact

It bothers me. A fix would be nice

Describe the bug

I'm using a host application which targets .NET 6.0 with GRPC service developed under windows which references "Grpc.Net.Common". under windows all works great but when the solution is built and packages restore under a debian machine (docker), it restores this library as .NETStandard v2.0 which is not the same one which is restored on my machine (mine is .NETCoreApp v6.0). when i started the service under debian i got the following exception:

---> System.TypeLoadException: Could not load type 'Grpc.Net.Compression.DeflateCompressionProvider' from assembly 'Grpc.Net.Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad'.

when i opened the Grpc.Net.Common under dotPeek from the docker (.NETStandard v2.0) i can see that Grpc.Net.Compression.DeflateCompressionProvider doesn't exist there. it DOES exist on the .NETCoreApp v6.0 version which was restored on my windows machine. why is this class missing in the .NETStandard v2.0 version?

in this image, the package that is being restored is the .NETStandard one - i'm not sure why https://pasteboard.co/PaeZqwwMYcc5.jpg

On the debian env we ARE using .NET 6 - the same solution is being restored & compiled there We restore our project based on mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim docker container, with this command:

RUN nuget restore ./PATH_TO_SOLUTION_FILE

the "nuget" package we are using was installed from Mono repository because the native nuget from debian 11 was causing us issues.

Repro Steps

In this image mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim install cross-platform NuGet from Mono-Project repository and try to restore a project that uses package <PackageReference Include="Grpc.Net.Common" Version="2.41.0" />

Expected Behavior

Restore .NET 6 version of Grpc.Net.Common.

Screenshots

https://pasteboard.co/PaeZqwwMYcc5.jpg

Additional Context and logs

No response

maksperovpm commented 1 year ago

If we use native nuget from Debian image, we get errors even on install just one package. Example

nuget install Autofac

WARNING: Error: TrustFailure (Authentication failed, see inner exception.)
WARNING: An error occurred while loading packages from 'https://www.nuget.org/api/v2/': Error: TrustFailure (Authentication failed, see inner exception.)

Unable to find package 'Autofac'.

=================================

UPD:

We found alternative that solves our project restore issue. If we restore it with dotnet restore command, it works.

dotnet restore ./PATH_TO_SOLUTION_FILE -s MYGET_REPO -s https://api.nuget.org/v3/index.json

So, the problem is definitely somewhere in NuGet.

maksperovpm commented 1 year ago

Hi,

Problem still persists. We still get exactly the same issue we got with nuget command: Grpc.Net.Compression.DeflateCompressionProvider' from assembly 'Grpc.Net.Common, Version=2.0.0.0

We use this command: dotnet restore ./PATH_TO_SOLUTION_FILE -s MYGET_REPO -s https://api.nuget.org/v3/index.json

as a workaround we overrite Grpc.Net.Common.dll from local machine where Grpc.Net.Common is restored for .NETCoreApp v6.0.

heng-liu commented 1 year ago

Hi @maksperovpm , may I know if my understanding below is correct? NuGet.exe restores incorrectly, resolving the wrong version of package Grpc.Net.Common (2.0.0.0). But dotnet restore works correctly, resolving the correct version of package Grpc.Net.Common(2.41.0).

If "yes", may I know which version of the NuGet.exe you're using? Thanks! NuGet inserts into .NET SDK so you'll get newer version of NuGet bits automatically from running dotnet command line on a newer version. While for NuGet.exe, you might have to update to a newer version on your own.

maksperovpm commented 1 year ago

Hi @heng-liu,

Thanks for not leaving me here alone.

We are using this docker image as a base: mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim

If we use native nuget from this image, we get errors even on install just one package. Example

nuget install Autofac

WARNING: Error: TrustFailure (Authentication failed, see inner exception.)
WARNING: An error occurred while loading packages from 'https://www.nuget.org/api/v2/': Error: TrustFailure (Authentication failed, see inner exception.)

Unable to find package 'Autofac'.

If we use dotnet restore command it restores Grpc.Net.Common library as .NETStandard v2.0 not .NETCoreApp v6.0, as it probably suposed to do. dotnet restore ./PATH_TO_SOLUTION_FILE -s MYGET_REPO -s https://api.nuget.org/v3/index.json

heng-liu commented 1 year ago

Thanks @maksperovpm ! Could you run nuget help and see which NuGet.exe version is used in the docker image?

maksperovpm commented 1 year ago

This one

NuGet Version: 2.8.7.0

heng-liu commented 1 year ago

Hi @maksperovpm , thanks for your reply! Unfortunately, this is a very old version of NuGet.exe. Is it possible to upgrade the version to the latest in the docker image? You may refer to https://www.nuget.org/downloads for all the versions. Or, could you use nuget update -self to update the version.

zivkan commented 1 year ago

@maksperovpm Is there a reason you're using nuget.exe restore instead of dotnet restore? Does your solution include Xamarin projects, or others that can only be built with Mono and uses packages.config rather than PackageReference?

You can avoid this nuget.exe version problem by using the dotnet CLI for everything, restore and build. Otherwise, you'll need to keep updating which version of nuget.exe you use each time you update to a newer major version of the .NET SDK. That's just at a minimum, and excludes security fixes, other bug fixes, new features, etc.

My gut feeling is that the problem relates to the fact that the .NET team decided to reuse the net prefix, which used to represent the .NET Framework, to instead mean .NETCoreApp when the version number is 5.0 or higher. However, since this was only designed and implemented in 2020, this means versions of NuGet lower than approximately NuGet 5.11 don't know and will think that net60 is .NET Framework 6.0. nuget.org shows the package contains netstandard1.5, netstandard2.0, netstandard2.1 and net462 dlls. Since old versions of Nuget don't know about the net5+ TFM changes, I expect that nuget.exe will have selected the net462 dll, and the .NET Framework 4.6.2 at a guess might not have the APIs that GRPC uses for Deflate.

Honestly, I'm surprised nuget.exe 2.8 knows about PackageReference and wrote a compatible project.assets.json file. I would have expected much more serious build failures.

maksperovpm commented 1 year ago

UPD

Now we have another issue for another project with Microsoft.Extensions.DependencyModel.

Summary:

Docker image: mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim

Command to restore project: dotnet restore ./PATH_TO_SOLUTION_FILE -s MYGET_REPO -s https://api.nuget.org/v3/index.json

Issues:

1. Could not load type 'Grpc.Net.Compression.DeflateCompressionProvider' from assembly 'Grpc.Net.Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad'
2. Could not load file or assembly 'Microsoft.Extensions.DependencyModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'

While issues are not fixed, workaround is to restore project locally and replace/add dll file from local machine.

maksperovpm commented 1 year ago

Hi @heng-liu

nuget update -self
Checking for updates from https://www.nuget.org/api/v2/.
Currently running NuGet.exe 2.8.7.
Updating NuGet.exe to 6.3.0.
Update successful.

Unfortunately, even with updated nuget we have the same issue :(

=================================================

Hi @zivkan . Thanks for joining us.

For now we are using this command to restore project dotnet restore ./PATH_TO_SOLUTION_FILE -s MYGET_REPO -s https://api.nuget.org/v3/index.json

Related to Xamarin and Mono

erdembayar commented 1 year ago

@maksperovpm Could you be able to repro your restore scenario issues with Github Actions? Most likely if it's happening with Debian docker image then it should be able to repro in Github Actions. If you can create small Github repro repository in Github Actions then it's much easier to reason with.

ghost commented 1 year ago

This issue has been automatically marked as stale because we have not received a response in 14 days. It will be closed if no further activity occurs within another 14 days of this comment.

maksperovpm commented 1 year ago

We investigated the issue with Microsoft.Extensions.DependencyModel.dll We ran restore command with additional flags --verbosity diagnostic and by the log we should have Microsoft.Extensions.DependencyModel 3.0.0 version, but after publishing project we get Microsoft.Extensions.DependencyModel, Version=2.1.0.0 We checked where in the system we can find this dll file after restore and publish and compared SHAs with that one that we get after publish.

/root/.nuget/packages/coverlet.collector/3.1.2/build/netstandard1.0/Microsoft.Extensions.DependencyModel.dll
/root/.nuget/packages/microsoft.extensions.dependencymodel/3.0.0/lib/net451/Microsoft.Extensions.DependencyModel.dll
/root/.nuget/packages/microsoft.extensions.dependencymodel/3.0.0/lib/netstandard1.3/Microsoft.Extensions.DependencyModel.dll
/root/.nuget/packages/microsoft.extensions.dependencymodel/3.0.0/lib/netstandard1.6/Microsoft.Extensions.DependencyModel.dll
/root/.nuget/packages/microsoft.extensions.dependencymodel/3.0.0/lib/netstandard2.0/Microsoft.Extensions.DependencyModel.dll
/src/src/OM2.Webserver.Host/bin/Release/net6.0/Microsoft.Extensions.DependencyModel.dll
/usr/share/dotnet/sdk/6.0.401/Microsoft.Extensions.DependencyModel.dll
/usr/share/dotnet/sdk/6.0.401/Sdks/Microsoft.NET.Sdk/tools/net472/Microsoft.Extensions.DependencyModel.dll

As a result, this 2 files has the same SHA /root/.nuget/packages/coverlet.collector/3.1.2/build/netstandard1.0/Microsoft.Extensions.DependencyModel.dll and out/Microsoft.Extensions.DependencyModel.dll

We found an issue like ours, here -> https://github.com/dotnet/sdk/issues/3886

We tried one suggested way to fix this by specifying csproj file during publish command RUN dotnet publish ./PATH_TO_CSPROJ_FILE -c Release -o out --no-restore

and IT WORKS

In CSPROJ file case we have sme SHA for this files

/root/.nuget/packages/microsoft.extensions.dependencymodel/3.0.0/lib/netstandard2.0/Microsoft.Extensions.DependencyModel.dll
/src/out/Microsoft.Extensions.DependencyModel.dll
/src/src/OM2.Webserver.Host/bin/Release/net6.0/Microsoft.Extensions.DependencyModel.dll

Seems like when you specify solution file on publish, it can't understand which project is the main one and kinda takes probably the latest project packages versions.

I'll try same solution on other project and will update.

But for now, as summary

SOLUTION: On publish specify csproj file, not sln.

nkolev92 commented 1 year ago

Hey @maksperovpm

If I'm interpreting this correctly sounds like you were able to figure out the problem on your end?

Do you think there's anything NuGet specific leftover? Reading through it all, sounds like we don't really have anything actionable for the NuGet team.

maksperovpm commented 1 year ago

Hi @nkolev92

I suppose No. For our case, the problem is in dotnet publish command.

Thanks.