JamesNK / Newtonsoft.Json

Json.NET is a popular high-performance JSON framework for .NET
https://www.newtonsoft.com/json
MIT License
10.76k stars 3.25k forks source link

Assembly version is incorrectly set to 13.0.0.0 from 13.0.0.1 #2662

Open linsongyang opened 2 years ago

linsongyang commented 2 years ago

Expected behavior

version 13.0.0.1 expected to have the same assembly version

Actual behavior

version 13.0.0.1 have the same assembly version incorrectly set to 13.0.0.0 and caused the file not found error from msbuild

C:\Program Files\dotnet\sdk\6.0.103\Microsoft.Common.CurrentVersion.targets(2304,5): warning MSB3277: "Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed" was chosen because it was primary and "Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed" was not.

Steps to reproduce

PS C:\> $dll = "N:\newtonsoft.json\13.0.1\lib\net45\Newtonsoft.Json.dll"
PS C:\> [Reflection.Assembly]::LoadFile($dll).GetName()

Version        Name
-------        ----
13.0.0.0       Newtonsoft.Json
jan-drozen commented 2 years ago

I just want to add that I agree with @linsongyang . The only difference for me (perhaps it's a typo in his report) is that the affected package version is 13.0.1. I spent/wasted quite some time tuning existing binding redirects until I found out that the package version 13.0.1 has actually an assembly version 13.0.0.0. I would expect the assembly version matches the package version as well as the DLL file version (the first three components).

sungam3r commented 2 years ago

Package version is not required to be equal to assembly version. These things are completely different. Package is a "stuff-wrapper" with its own versioning. It may contain anything you can imagine. .NET dll is just a one option. And of course .NET has its own versioning - assembly version. Plus remember about file version (not .NET specific thing). Look for example for https://www.nuget.org/packages/System.Net.Http/ : изображение

Package version = 4.3.4 Assembly version = 4.1.1.3

bcalco commented 2 years ago

I don't know if this is the root cause of what I'm seeing, but it's driving be bonkers. I keep getting this warning:

6>C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets(2301,5): warning MSB3277: Found conflicts between different versions of "Newtonsoft.Json" that could not be resolved.
6>C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets(2301,5): warning MSB3277: There was a conflict between "Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed" and "Newtonsoft.Json, Version=13.0.0.1, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed".
6>C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets(2301,5): warning MSB3277:     "Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed" was chosen because it was primary and "Newtonsoft.Json, Version=13.0.0.1, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed" was not.

What follows are listings of what is dependent on what version, and the only thing listed that depends on 13.0.0.0 is the nuget cache of 13.0.0.1! All my other projects in the solution either explicitly require 13.0.0.1, or a dependency says ">= 12.0.3". not a single dependency that I can see in my project explicitly requests 13.0.0.0 and yet that's what I get in my target directory, though it describes itself as 13.0.1:

image

When the app tries to deserialize data from LiteDB, I get an exception:

{"Could not load file or assembly 'Newtonsoft.Json, Version=13.0.0.1, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)":"Newtonsoft.Json, Version=13.0.0.1, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed"}

I have the following binding redirects in the two exe's that are part of my solution:

      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.1" />
      </dependentAssembly>

But this is not solving the issue.

I came here now to log this as an issue but seeing this issue, it occurred to me first to see if the issue described here isn't the root cause of the problem?

If this problem has a solution described in any previous current or archived issue, please direct me to how to solve it!

Otherwise I post it as possible evidence that the issue described here that the version confusion described here may be the root of it.

bcalco commented 2 years ago

I should also like to add that the very same DLL being called by the very same code I wrote that is shared by two of my EXE's works in one but does not work in the other. Same code calling the same actual version of Newtonsoft.Json.dll (copied in two different directories) - one works, the other blows up. Anyone have any idea how to sleuth or fix this, I'm all ears.

bcalco commented 2 years ago

And just to second what @linsongyang reports, here is proof the two DLLs are the same:


PS C:\projects\dotnet\apex-build\build\Accelerate\bin\Debug\net480> cd \
PS C:\> $dll1 = "C:\projects\dotnet\apex-build\build\Accelerate\bin\Debug\net480\Newtonsoft.Json.dll"
PS C:\> $dll2 = "C:\projects\dotnet\apex-build\build\Apex.UserExperience\bin\Debug\net480\Newtonsoft.Json.dll"
PS C:\> [Reflection.Assembly]::LoadFile($dll1).GetName()

Version        Name
-------        ----
13.0.0.0       Newtonsoft.Json

PS C:\> [Reflection.Assembly]::LoadFile($dll2).GetName()

Version        Name
-------        ----
13.0.0.0       Newtonsoft.Json

PS C:\>

All my projects explicitly require 13.0.0.0 but this is what they're getting. Why it works for one EXE and not the other has me trapped in this rabbit hole I can't seem to get out of. And no, I can't go to a previous version as most of my dependencies that do require Newtonsoft.Json.dll require 13.0.0.1 or higher; a few require 12.0.3 or higher.

So again - any help with this appreciated, and needed urgently as this is showstopping some important work on my project.

bcalco commented 2 years ago

OK Update: I removed most explicit requirements for the 13.0.0.1 version from my projects, and deleted all binding redirects that were generated by the tooling, and now my stuff compiles without dependency warnings. This whole murky area off DLL He---er, I suppose we should call it "DLL Purgatory" since we can know with Hawking-level certainty that DLL Hell does not exist on .NET, amiright?--is such a time-consuming rabbit hole filled with quicksand...

github-anurag commented 2 years ago

I see the same issue for our PS module project that is based off a .NET project that upgraded to Newtonsoft.Json v13.0.1

joshunter commented 2 years ago

Adding to last post, we tried updating the .NET project to Newtonsoft.Json v13.0.1 and it caused a failure in the PowerShell project that depends on it. The error says that it can't find the assembly with version 13.0.1.0 and indeed it brings in 13.0.0.0.

However, even going back down to Newtonsoft.Json v12.0.3 the issue persists. I removed all references to 13.0.1 in the .nuget cache, cleaned the project, and uninstalled everything in PS before rebuilding and reinstalling the PS project and still saw this error. The only way I was able to resolve the issue was to update my PowerShell version to 7.1, but that's not ideal because I'm still on 12.0.3 and unable to update - I fear it'll break this PS version as well.

@bcalco do you have any suggestions or workarounds for this issue on PowerShell? I don't have any direct references to 13.0.1 in any project, but ideally I'd like to be able to use Newtonsoft v13.0.1 with PowerShell 6 and 7.

alvaro-vantis-pt commented 2 years ago

I have the same problem. It runs ok when running in DEBUG or RELEASE mode, but it throws the exception "not found for version 13.0.0.0" when I run from published directory, when the publish runs with the following options: Deployment Mode: Self-Contained Target Framework: .NET 6.0-Windows Target-Runtime: win-x64 Produce Single FIle Enable ReadytoRun compilation

I've monitored with sysinternals filemon and it shows no explicit activity on file named newtonsoft.json.dll. Probably it's trying to find it inside the singlefile that was generated on publish.

kdss-ja commented 2 years ago
 <dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
    <bindingRedirect oldVersion="0.0.0.0-12.9.0.0" newVersion="13.0.0.0"/>
</dependentAssembly>

Worked for me after trying every possible combination

musicalmathmind commented 2 years ago

So just to add to some weirdness to all of this, the behavior is only happening when I build the project in a docker file using mcr.microsoft.com/dotnet/sdk:6.0 as a base. If I build/run on Windows, I don't see this error at all.

One thing I learned from this post is that you could inspect the 'project.assets.json' file in the 'obj/' directory to figure out which package depends on Newtonsoft. Doing this I found that 'Microsoft.Extensions.DependencyModel' was the only library that had the dependency on any version of Newtonsoft.Json with a major version of 9.

image

So I updated that dependency to v6.0.0. Now I no longer have any dependencies on version 9 in my 'projects.assets.json' file.

However, I still got the "file not found" error when building and running in docker. So I decided to connect a terminal to the docker container to see exactly which version of the Newtsonft.Json dll was put in the directory beside my Project.Dll file.

image

It is indeed STILL 9.0.0.0.

So I decided top open the 'projects.assets.json' file in the 'obj/' directory on the docker container where the project was built. I confirmed that there is no reference to any Newtonsoft.Json dependency with a major version of 9. However, this is still the version that gets put in the final build directory.

So at this point I'm kind of at a loss. It only seems like I can get this to repro in docker.

packwoodm commented 1 year ago

Are there any plans to look at this? I needed to upgrade to 13.0.1 or 13.0.2 because of a vulnerability. I can't because runtime fails that it can't find version 13.0.0. There is no version 13.0.0 to try.

bartelink commented 1 year ago

@packwoodm per the above, both those versions internally will be AssemblyVersion 13.0.0, which means any message about 'not being able to find' does not mean there is an AssemblyVersionmismatch; you can verify by reading the above and using the viewer tools to inspect My money is on there being another issue with loading the DLL in your context - i.e. the file may be missing, or in the wrong directory

logan1155 commented 1 year ago

I ran into this with seemingly no fix. I was trying to use a local dll file I haven't had issues with before. Using nuget manager and selecting an older build worked for me. Used 11.0.2

readyjoseph commented 7 months ago

@kdss-ja - It did not work for me @bcalco - Are you still having this issue?

github-anurag commented 5 months ago

Any updates on this issue?