maui icon indicating copy to clipboard operation
maui copied to clipboard

XML Serializer does not work correctly in "net8.0-ios" release mode

Open JeroenBer opened this issue 10 months ago • 2 comments

Description

Under certain conditions XML Serializer does not work correctly in "net8.0-ios" release mode. This means the AOT version on iOS device does not work correctly.

Steps to Reproduce

  1. Create an iOS app
  2. Add the testclass below
    • call the function XmlTests.TestVirtual(), it works perfectly in debug mode but throws an exception in release mode.
    • call the function XmlTests.TestFilledNullableDateTime(), , it works perfectly in debug mode but throws an exception in release mode.
  3. Build & deploy in release mode.
    public class ClassWithVirtual
    {
        public virtual double VirtualDoubleProperty{ get; set; }
    }

    public class ClassWithNullableDateTime : IClassInterface
    {
        public DateTime? DateTime { get; set; }
    }

    public interface IClassInterface
    {
        DateTime? DateTime { get; set; }
    }

    public class XmlTests
    {

        public void TestVirtual()
        {
            var serializer = new XmlSerializer(typeof(ClassWithVirtual));

            var obj = new ClassWithVirtual()
            {
                VirtualDoubleProperty = 123.456,
            };
            using var s = new MemoryStream();
            serializer.Serialize(s, obj);

            s.Position = 0;

            var obj2 = (ClassWithVirtual)serializer.Deserialize(s);
            if (obj2.VirtualDoubleProperty != obj.VirtualDoubleProperty)
                throw new Exception("VirtualDoubleProperty changed");
        }

        public void TestFilledNullableDateTime()
        {
            var serializer = new XmlSerializer(typeof(ClassWithNullableDateTime));

            var obj = new ClassWithNullableDateTime()
            {
                DateTime = DateTime.Now,
            };
            using var s = new MemoryStream();
            serializer.Serialize(s, obj);

            s.Position = 0;

            var obj2 = (ClassWithNullableDateTime)serializer.Deserialize(s);
            if (obj2.DateTime != obj.DateTime)
                throw new Exception("DateTime property changed");
        }
    }

There are at least 2 situations that will make Xml Serializer throw an exception in release mode:

  1. Use properties marked as virtual.
  2. Use properties that are also defined as setter properties in an interface that the class implements.

Link to public reproduction project repository

No response

Version with bug

Unknown/Other

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

iOS

Affected platform versions

No response

Did you find any workaround?

  1. Enable the interpreter but we don't want to do this because of performance (see also https://github.com/dotnet/maui/issues/13019).
  2. remove any virtual properties and interfaces with property setters on classes that are Xml Serialized.

Relevant log output

The following exceptions occur in release mode:

Using virtuals something like this:

System.InvalidOperationException : XmlSerializeErrorDetails,4,3 ---> System.ExecutionEngineException : Attempting to JIT compiled method '(wrapper delegate-invoke) void System.Action `<....SerializationTests.ClassWithVirtual, double>:invoke_callvirt_-void_T1_T2 (...)'while running in aot-only mode See http:.....

Using interfaces with properties setters for class also gives a similar exception.

JeroenBer avatar Apr 12 '24 17:04 JeroenBer

I believe this would be a runtime issue with Mono AOT. It's unrelated to the MAUI UI framework, outside of the fact that it works in debug mode because MAUIs templates enable the Interpreter by default for debug (hence the issue you linked, where people keep writing code that works because the interpreter happens to be on, but fails in Release mode). If you run this code in a .NET iOS app without the MAUI Template, it would fail in debug mode with the same JIT error. That it works in debug here is happenstance.

@rolfbjarne I'm not sure where this issue should go, what do you think?

drasticactions avatar Apr 13 '24 15:04 drasticactions

I understand and agree, this is not MAUI UI. But is "net8.0-ios" part of MAUI ? It felt weird to put it in xamarin-macios, since it's no longer Xamarin. For people without a Xamarin history it's pretty inapprehensible where to report these things, also for finding documentation etc. The term Xamarin is still used in a lot of places. Even for people with Xamarin experience it's sometimes hard to understand.

JeroenBer avatar Apr 13 '24 16:04 JeroenBer

Look related to https://github.com/dotnet/runtime/issues/99548

jfversluis avatar Apr 15 '24 07:04 jfversluis

This issue was moved to dotnet/runtime#101041

jfversluis avatar Apr 15 '24 07:04 jfversluis

@JeroenBer just like as it was with Xamarin and Xamarin.Forms when there was Xamarin.iOS and Xamarin.Android there is now .NET MAUI and .NET for iOS and .NET for Android.

Whenever something is reproducible without .NET MAUI involved, is should not go here. If it only reproduces on iOS, it should probably go into the macios repo, if only on Android it should probably go there. Removing the Xamarin name is being worked on as well as other things to make this all a bit more easier.

But don't worry about it too much, while we appreciate any effort on your part to put it in the right place immediately, we're happy to help you get it routed the right way. It's understandable that from the outside it might not always be super clear.

jfversluis avatar Apr 15 '24 07:04 jfversluis