Skip to content

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

@mortarroad

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions