Skip to content

NewtonsoftJson DLL Hell (especially for modding Unity games) #696

Description

@mortarroad

General Problem

A lot of apps and libraries use NewtonsoftJson. So does buttplug-csharp

But there are a few problems:

  • buttplug-csharp brings its own version of NewtonsoftJson (currently 13.0.4)
  • a lot of .NET apps already bring their own version of NewtonsoftJson
  • NewtonsoftJson does not seem to be forward compatible in some cases (see below)
  • as far as I know, only one version of the library can be loaded

This is a problem for modding. The version conflict can lead to errors at runtime, even if the DLL is loaded fine at first.

My Specific Problem

The latest buttplug-csharp version (5.0.1-beta2, 08b2928) does not work with the game I'm trying to mod.

I'm getting the following error when calling ConnectAsync():

MissingMethodException: Method not found: string Newtonsoft.Json.Linq.JToken.ToString(Newtonsoft.Json.Formatting)
Stack trace:
Buttplug.Client.ButtplugConnectorJSONParser.Serialize (Buttplug.Core.Messages.ButtplugMessage msg) (at Buttplug/Client/ButtplugConnectorJSONParser.cs:29)
Buttplug.Client.ButtplugRemoteJSONConnector.PrepareMessage (Buttplug.Core.Messages.ButtplugMessage msg, System.Threading.CancellationToken token) (at Buttplug/Client/ButtplugRemoteJSONConnector.cs:41)
Buttplug.Client.ButtplugWebsocketConnector.SendAsync (Buttplug.Core.Messages.ButtplugMessage msg, System.Threading.CancellationToken cancellationToken) (at Buttplug/Client/ButtplugWebsocketConnector.cs:103)
Buttplug.Client.ButtplugClientMessageHandler.SendMessageAsync (Buttplug.Core.Messages.ButtplugMessage msg, System.Threading.CancellationToken token) (at Buttplug/Client/ButtplugClientMessageHandler.cs:35)
Buttplug.Client.ButtplugClient.ConnectAsync (Buttplug.Client.IButtplugClientConnector connector, System.Threading.CancellationToken token) (at Buttplug/Client/ButtplugClient.cs:133)

The issue is, that an overload of JToken.ToString() has been added between NewtonsoftJson release 13.0.4 and 13.0.2:

  • in 13.0.2, there is:
    • ToString()
    • ToString(Formatting formatting, params JsonConverter[] converters)
  • in 13.0.4, there is:
    • ToString()
    • ToString(Formatting formatting) <-- this overload is new
    • ToString(Formatting formatting, params JsonConverter[] converters)

While I believe that this is a bug in NewtonsoftJson (because it breaks compatibility in a patch release), I think we have to deal with it now. The versions are already released and used in games.

Solution?

Is there a recommended way to deal with this?

I can see the following possible solutions:

  • ensure buttplug-csharp is compatible with a wide range of versions of NewtonsoftJson (how?)
  • vendor NewtonsoftJson / rename the dependency to avoid conflicts
  • use a different / custom JSON library

In my case, I was able to "fix" it by compiling buttplug-csharp myself and setting the NewtonsoftJson version to exactly the same version that the game uses when compiling. But that means I have to use a custom build.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions