Bug: UnityConvertersConfig asset not loaded when running Unity in batch mode
applejag opened this issue · 8 comments
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)
I'll do some manual testing to try and reproduce this.
Was unable to reproduce this.
Steps taken:
-
New Unity 2020.3.18f1 project
-
Imported Newtonsoft.Json-for-Unity@13.0.102 & Newtonsoft.Json-for-Unity.Converters@1.2.0
-
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"); } }
-
Created a simple test assembly with
[Test] public void Serializes() { var json = JsonConvert.SerializeObject(new MyType()); Assert.AreEqual("\"Written by MyJsonConverter\"", json); }
-
Created a UnityConvertersConfig with only default settings, which includes the
MyJsonConverter
-
Ran tests via Unity's Test Framework
path/to/Unity.exe -runTests -batchmode -testPlatform playmode
Test passed, as expected
-
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} ################# "); }
-
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" #################
-
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.
-
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.
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.
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.
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:
- static initializer tries to load UnityConvertersConfig instance, fails (because it hasn't been imported yet), creates default instance
- asset import runs, causing it to update from cache server
- 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.
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?
That change to 1.2.0 works like a charm, thank you very much!
Awesome! I'm closing as resolved then :)