Open blmiles opened 9 months ago
"Not working" is not an adequate description of the problem you are observing. It's just merely stating the result of the problem you observed. If you did not observe anything (i.e., the "actual behavior") besides being able to state "not working", then you you need to do more debugging and troubleshooting to gather more relevant information about your problem.
licensing issue
The Newtonsoft.Json library has no mechanism or features imposing or enforcing licensing restrictions. If there is anything on your end indicating a licensing issue, it's not related to the Newtonsoft.Json library itself.
Just a shot from my hip and the only one speculation i am willing to do here given the scarce problem description: Often, the default build settings for mobile targets include code trimming and perhaps even Native AOT compiling. Newtonsoft.Json, being a library whose functionality mostly depends on reflection, does not gel well with code trimming or Native AOT compiling. Therefore, i'd suggest to verify your build settings and try explicitly disabling code trimming and Native AOT compiling. If this is not possible/feasible or does not resolve the problem, i'd suggest you give System.Text.Json a try, since System.Text.Json is much less dependent on reflection and therefore a better and more natural fit for projects involving code trimming and/or native AOT compiling.
@elgonzo - well, being in release I'm not seeing actual error generated. AND this all works in Debug mode.
All I can say is that the call: DeserializeObject<List<Player>>(Drill.PlayersJson);
does NOT return any objects in Release build but does so in Debug mode.
You have however pointed me in a good direction to investigate and linking and AOT are highly likely the problem. Thanks for your insight. Matches what others have posted elsewhere. I'm just experimenting with various build options to fix this.
Thx
does NOT return any objects in Release build but does so in Debug mode
I assume "not returing any objects" means that DeserializeObject
returns null
. While this is not conclusive evidence in itself, it would fit my speculation that code trimming / native AOT compiling might be contributing to the problem. It might be that for the debug build, code trimming / NativeAOT might be disabled by default for the step debugger to work properly and meaningfully, possibly explaining the difference in behavior between debug and release build. But again, this is only my "blind" speculation, so please don't take it as authoritative gospel.
I don't know enough about the linker and trimming directives for the csproj. and the VS UI gives limited control on the project. Removing all linking, the app won't even run on iOS. Might need to do as you suggest, use System.Text.Json but it has other limitations ... not looking pretty right now.
Are there any directives similar to this to negate the issue effecting .Json?
<ItemGroup>
<TrimmerRootAssembly Include="System.Collections.Immutable" />
</ItemGroup>
Thx
<TrimmerRootAssembly>
is the correct setting to exclude an assembly from trimming. Note however, that the System.Collections.Immutable assembly is not providing the List<T>
used in the code example in your report. It might perhaps also be necessary to exclude your program assembly from trimming -- or perhaps not; it depends entirely on how your program operates with the instances of the types involved in the (de)serialization (it entirely depends on whether the trimming logic can detect the used types and members from the reachable code in your program assembly).
Disabling NativeAOT for iOS might be a bit trickier, and i unfortunately have no experience regarding .NET stuff on iOS. I don't know if .NET's iOS targets still rely on Xamarin.iOS under the hood and supports the mono interpreter. However, as it seems, disabling native AOT compiling for iOS targets requires enabling the mono interpreter. See here for details: https://learn.microsoft.com/en-us/dotnet/maui/macios/interpreter
If this is too difficult to setup correctly (don't ask me how), perhaps switching to System.Text.Json
using code generation is an alternative. See here for how to configure code generation for System.Text.Json: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/source-generation. System.Text.Json's code generation will not rely on reflection, thus it should avoid issues related to trimming and NativeAOT as far as Json (de)serialization is concerned. It however comes with the restriction of not being able to (de)serialize private/protected members (obviously, as access to those members would again require reflection which in turn would nullify the benefits of STJ code generation and also reintroduce trimming/NativeAOT issues).
You help and advice is excellent! Thanks for pointing me in good directions! Will mess with it over weekend, Might ask a couple more questions if I may. I will also post my findings if successful!
@elgonzo - update.
I tried every permutation I could to exclude various libraries from linking... to no avail.
Finally swapped out the DeserializeObject<List<Player>>(Drill.PlayersJson);
and similar calls for something like this:
Byte[] playersbytes = Encoding.ASCII.GetBytes(Drill.PlayersJson);
Stream playerstream = new MemoryStream(playersbytes);
Players = System.Text.Json.JsonSerializer.Deserialize<LinkedList<Player>>(playerstream);
Had to deal with the Serialize too. Drill.PlayersJson = System.Text.Json.JsonSerializer.Serialize(Players);
So all is good for now. And it all works! I learned a bit about linking and AOT !!
Thanks for your responses, insight and guidance!
I have a Maui app project targeting Android and iOS. The Android version using latest Json libraries is live and running. All works in both debug and release mode.
VS 2022 (latest version), NewtonSoft.Json version 13.0.3, Maui targeting .Net7
The iOS version works in Debug mode but won't serialize/deserialise objects when compiled in Release mode.
I'm not sure if this is a bug or a licensing issue for the iOS platform but this all works in the Android targeted app, both in Build and Release mode. Exactly same codebase AND the Android version is also obfuscated in Release mode.
Expected behavior
Serialize/Deserialize objects in Release build.
Actual behavior
Steps to reproduce