Newtonsoft.Json icon indicating copy to clipboard operation
Newtonsoft.Json copied to clipboard

13.0.1 causes file not found exception when assembly gets implicitly loaded when used in a visual studio extension

Open gfs opened this issue 3 years ago • 11 comments

I have a project for a Visual Studio Extension that uses Newtonsoft.Json. When using 12.0.3 I have no issues. When I updated to 13.0.1 I get a FileNotFoundException on this [1] constructor as .NET attempts to load the Newtonsoft.Json dll. The message states cannot find an assembly with version 13.0.0.0, which is what is noted in the deps.json. But the actual version in the csproj is 13.0.1 and the "FileVersion" noted in deps.json is different as well.

image

[1] https://github.com/microsoft/DevSkim/blob/cae3f5b8d1b94ab4eb9929552f0dfe10df0decfb/DevSkim-DotNet/Microsoft.DevSkim/Language.cs#L158

This reproduces in this commit: https://github.com/microsoft/DevSkim/tree/d721125ebe0c0b27f6fc274b004c85c1e666e3c4 And does not once I downgraded to 12.0.3 in this PR: https://github.com/microsoft/DevSkim/pull/286

gfs avatar May 19 '21 15:05 gfs

Downgrading to 12.0.3 fixed this issue for me

gpgreenleaf avatar Sep 20 '21 23:09 gpgreenleaf

I'm having exactly the same problem, it's causing big issues for me. Any other fix?

mcmillab avatar Nov 04 '21 23:11 mcmillab

I believe that this issue is caused because Visual Studio itself usesa version of newtonsoft identifying as 13.0.0.0. I noticed a similar problem if I switched to System.Text.Json and use 5.0.2. I'm not sure what the work around is but it seems to be related to the specific versions that visual studio is using.

gfs avatar Nov 05 '21 01:11 gfs

ok so any suggestions on how to fix?

mcmillab avatar Nov 05 '21 07:11 mcmillab

same, problem here, any suggestions?

DanielSanin avatar Jan 21 '22 15:01 DanielSanin

Same here. In our case the issues raises an "InvalidCastException" in combination with JsonSubtypes. We assume that casting the JsonSubtypes converter (wich implements the JsonConverter interface) crashes because the dependency is suggested to be 13.0.1 but the "class loader" only finds 13.0.0 and is thus throwing an exception.

LouBen3010 avatar Mar 23 '22 10:03 LouBen3010

After further experimentation with this I believe in my case it is due specifically due to the use as a Visual Studio extension.

It appears that if you are using the same major version of a dependency as visual studio uses itself you must use the same exact version. I see the same issue when using System.Text.Json if it doesn't match the version that Visual Studio "expects".

Unfortunately there does not appear to be any mechanism (at least in Visual Studio itself) for detecting if updating your dependencies is going to work or not.

This makes working with json in visual studio extensions super irritating and I'm not sure what the fix is.

gfs avatar Mar 23 '22 16:03 gfs

Hi @gfs, what Visual Studio extension were you using that leads to the problem?

hcyang avatar Jun 03 '22 01:06 hcyang

This is for the Microsoft DevSkim extension in particular - I linked the commit in the repo that reproduces it in the initial report.

The problem isn't in the latest published version - only the linked commit - as I reverted back to 12 to avoid the issue.

gfs avatar Jun 03 '22 05:06 gfs

As Newtonsoft.JSON has become ever popular, it has been used internally in Microsoft services and products. My suspicion is that the services and products have loaded the Newtonsoft.JSON assembly previously with an older version and that can cause problems for user code loading a newer one. For that reason, one can instrument and list the assemblies (and their versions) before the exception point (if possible) and check what Newtonsoft.JSON version has already been loaded. Downgrade the Newtonsoft version in user project accordingly and maybe sent an ask for the services/products to upgrade their Newtonsoft. This is a curse of Newtonsoft's popularity, I guess.

Below is a code snippet for listing assemblies and their version (from https://makolyte.com/csharp-get-list-of-assemblies-currently-loaded-and-output-metadata/#:~:text=C%23%20%E2%80%93%20Get%20list%20of%20assemblies%20currently%20loaded,Console.WriteLine%20%28%24%22Name%3D%7Bname.Name%7D%20Version%3D%7Bname.Version%7D%20Location%3D%7Bassembly.Location%7D%22%20%29%3B%20Console.WriteLine%20%28%29%3B%20%7D)

foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { Console.WriteLine(assembly.FullName);

foreach (var attribute in assembly.GetCustomAttributesData())
{
	Console.WriteLine(attribute);
}
Console.WriteLine();

}

hcyang avatar Jun 03 '22 18:06 hcyang

Thanks for the pointer. I’m working on a major refactor of the devskim extension soon so this may help.

My guess too is that something else is holding an older version with the same assembly version - it may even be visual studio itself.

Unfortunately when developing an extension it’s hard to know a priori what that secret version number is but this trick might help!

On Fri, Jun 3, 2022 at 11:28 AM, Hung-chih Yang @.***> wrote:

As Newtonsoft.JSON has become ever popular, it has been used internally in Microsoft services and products. My suspicion is that the services and products have loaded the Newtonsoft.JSON assembly previously with an older version and that can cause problems for user code loading a newer one. For that reason, one can instrument and list the assemblies (and their versions) before the exception point (if possible) and check what Newtonsoft.JSON version has already been loaded. Downgrade the Newtonsoft version in user project accordingly and maybe sent an ask for the services/products to upgrade their Newtonsoft. This is a curse of Newtonsoft's popularity, I guess.

Below is a code snippet for listing assemblies and their version (from https://makolyte.com/csharp-get-list-of-assemblies-currently-loaded-and-output-metadata/#:~:text=C%23%20%E2%80%93%20Get%20list%20of%20assemblies%20currently%20loaded,Console.WriteLine%20%28%24%22Name%3D%7Bname.Name%7D%20Version%3D%7Bname.Version%7D%20Location%3D%7Bassembly.Location%7D%22%20%29%3B%20Console.WriteLine%20%28%29%3B%20%7D)

foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { Console.WriteLine(assembly.FullName);

foreach (var attribute in assembly.GetCustomAttributesData()) { Console.WriteLine(attribute); } Console.WriteLine();

}

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

gfs avatar Jun 03 '22 22:06 gfs