Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: UnityConvertersConfig asset not loaded when running Unity in batch mode #61

Closed
applejag opened this issue Sep 11, 2021 · 8 comments
Assignees
Labels
bug Something isn't working

Comments

@applejag
Copy link
Owner

Discussed in applejag/Newtonsoft.Json-for-Unity#137

Originally posted by jchowdown September 11, 2021
Hi, we created and configured a UnityConvertersConfig instance to not use specific custom converters when deserializing JSONs. This appears to work wonderfully in windowed mode, but when we try to run the same code in a headless editor ("-batchmode"), our converters appear to be added to the global converter list and they get run for every field that we try to deserialize. Is there something we need to do to make the editor load the ScriptableObject while in headless mode?

EDIT: I forgot to point out that this behavior is inconsistent cross machines. It works fine on my laptop but is broken (as described above) on our build machine (running Jenkins)

@applejag applejag added the bug Something isn't working label Sep 11, 2021
@applejag applejag self-assigned this Sep 11, 2021
@applejag
Copy link
Owner Author

I'll do some manual testing to try and reproduce this.

@applejag
Copy link
Owner Author

Was unable to reproduce this.

Steps taken:

  1. New Unity 2020.3.18f1 project

  2. Imported Newtonsoft.Json-for-Unity@13.0.102 & Newtonsoft.Json-for-Unity.Converters@1.2.0

  3. Created a POCO and simple JsonConverter with:

    public class MyJsonConverter : JsonConverter<MyType>
    {
        public override MyType ReadJson(JsonReader reader, Type objectType, MyType existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    
        public override void WriteJson(JsonWriter writer, MyType value, JsonSerializer serializer)
        {
            writer.WriteValue("Written by MyJsonConverter");
        }
    }
  4. Created a simple test assembly with

    [Test]
    public void Serializes()
    {
        var json = JsonConvert.SerializeObject(new MyType());
        Assert.AreEqual("\"Written by MyJsonConverter\"", json);
    }
  5. Created a UnityConvertersConfig with only default settings, which includes the MyJsonConverter

  6. Ran tests via Unity's Test Framework

    path/to/Unity.exe -runTests -batchmode -testPlatform playmode

    Test passed, as expected

  7. Added simple static function to just print the serialized content:

    public static void DoTheThing()
    {
        var json = JsonConvert.SerializeObject(new MyType());
    
        Debug.Log($@"
    #################
    ### JSON RESULTS:
    ### > {json}
    #################
    ");
    }
  8. Ran the method using the -executeMethod argument:

    /path/to/Unity.exe -quit -batchmode -executeMethod MyType.DoTheThing

    The log included the expected result:

    #################
    ### JSON RESULTS:
    ### > "Written by MyJsonConverter"
    #################
    
  9. Updated the UnityConvertersConfig to not include MyJsonConverter. According to the issue, it still used the default config at this point, which would result in the same results as above, while without the converter the test should fail and the log should be different.

  10. Ran the commands from 6. and 8. again, and as expected...

  • The test failed

  • The log included the expected result:

    #################
    ### JSON RESULTS:
    ### > {}
    #################
    

I was unable to reproduce the issue mentioned by @jchowdown in their discussion post. Hey @jchowdown, if you can post a reproducible guide like the one above that would be great. I've not tested the above in other Unity versions.

@jchowdown
Copy link

Thanks in advance for getting back to me so quickly jilleJr, I really appreciate it.

We're running
Unity 2020.3.10.f1
jillejr.newtonsoft.json-for-unity 13.0.102
jillejr.newtonsoft.json-for-unity.Converters 1.1.1
I'm currently rerunning it after adding some logging to CreateJsonSettingsWithFreslyLoadedConfig(), will have some more info soon.

@jchowdown
Copy link

Still trying to narrow this down but looks like this is happening due to some weird order-of-operations issue when opening a newly-downloaded Unity project and having to import assets, including the UnityConvertersConfig instance, for the first time.

@jchowdown
Copy link

jchowdown commented Sep 16, 2021

Yup, I confirmed that this is only a problem while using a cache server and running this for the first time on an yet-to-be-imported project. Basically the sequence of event goes:

  1. static initializer tries to load UnityConvertersConfig instance, fails (because it hasn't been imported yet), creates default instance
  2. asset import runs, causing it to update from cache server
  3. user code runs deserializes stuff with default config

I'm trying to call UnityConverterInitializer.RefreshSettingsFromConfig() manually right before we run the user code but UnityConverterInitializer is marked internal so I can't access it from our code.

@applejag
Copy link
Owner Author

Glad you were able to nail the cause down.

That class is marked as public starting with v1.2.0.

I forgot to merge the PR for that (#59) but have released that in the midst of this issue tracking.

If you get the newly released v1.2.0 and use the UnityConverterInitializer.RefreshSettingsFromConfig() method, does that solve the issue?

@jchowdown
Copy link

That change to 1.2.0 works like a charm, thank you very much!

@applejag
Copy link
Owner Author

Awesome! I'm closing as resolved then :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants