Open
Description
Description
When publishing a test application which uses XML serialization, vi code generated via xscgen
(see here) along with PublishAot
, the application crashes because the serialization code relies heavily upon reflection.
The stack trace is, then:
bin/Debug/net8.0/linux-x64/publish/XmlSerializationTest
Unhandled Exception: System.InvalidOperationException: There is an error in the XML document.
---> System.InvalidOperationException: There was an error reflecting type 'ACME.Package.Xml.Schema.PackageACL'.
---> System.InvalidOperationException: You must implement a default accessor on System.Collections.ObjectModel.Collection`1[[ACME.Package.Xml.Schema.Package, XmlSerializationTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] because it inherits from ICollection.
at System.Xml.Serialization.TypeScope.GetDefaultIndexer(Type, String) + 0x4e9
at System.Xml.Serialization.TypeScope.GetCollectionElementType(Type, String) + 0x44
at System.Xml.Serialization.TypeScope.ImportTypeDesc(Type, MemberInfo, Boolean) + 0x732
at System.Xml.Serialization.TypeScope.GetTypeDesc(Type, MemberInfo, Boolean, Boolean) + 0x172
at System.Xml.Serialization.StructModel.GetPropertyModel(PropertyInfo) + 0xf6
at System.Xml.Serialization.StructModel.GetFieldModel(MemberInfo) + 0xb0
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping, StructModel, Boolean, String, RecursionLimiter) + 0x777
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel, String, Boolean, XmlAttributes, RecursionLimiter) + 0x57f
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel, String, XmlReflectionImporter.ImportContext, String, XmlAttributes, Boolean, Boolean, RecursionLimiter) + 0x90d
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel, String, XmlReflectionImporter.ImportContext, String, XmlAttributes, Boolean, Boolean, RecursionLimiter) + 0xb9f
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel, String, XmlReflectionImporter.ImportContext, String, XmlAttributes, RecursionLimiter) + 0x57
at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel, XmlRootAttribute, String, RecursionLimiter) + 0x15e
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type, XmlRootAttribute, String) + 0xa5
at System.Xml.Serialization.XmlSerializer.GenerateXmlTypeMapping(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, String defaultNamespace) + 0xba
at System.Xml.Serialization.XmlSerializer.GetMapping() + 0x5e
at System.Xml.Serialization.XmlSerializer.DeserializeUsingReflection(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) + 0x33
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) + 0x1e9
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) + 0x4ed
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle) + 0x83
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader) + 0x27
at ACME.Xml.XmlExtensions.<ParseTag>d__0`1.MoveNext() + 0x222
at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1, Boolean&) + 0x16d
at System.Linq.Enumerable.Single[TSource](IEnumerable`1) + 0x4c
at ACME.XmlSerializationTest.Program.Main(String[] args) + 0x125
at XmlSerializationTest!<BaseAddress>+0x9e6cc7
at XmlSerializationTest!<BaseAddress>+0x9e6d4d
[1] 500757 IOT instruction (core dumped) bin/Debug/net8.0/linux-x64/publish/XmlSerializationTest
However, I have (in the real application) also seen the following stack:
---> System.NotSupportedException: 'System.Xml.Serialization.ReflectionXmlSerializationReaderHelper.GetSetMemberValueDelegateWithType[ACME.Package.Xml.Schema.PackageACL,System.DateTime](System.Reflection.MemberInfo)' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility
at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x61
at System.Reflection.Runtime.MethodInfos.RuntimeConstructedGenericMethodInfo.get_UncachedMethodInvoker() + 0x3b
at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.get_MethodInvoker() + 0x60
at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.MakeGenericMethod(Type[]) + 0x363
at System.Xml.Serialization.ReflectionXmlSerializationReader.GetSetMemberValueDelegate(Object, String) + 0x40a
at System.Xml.Serialization.ReflectionXmlSerializationReader.SetOrAddValueToMember(Object, Object, MemberInfo) + 0xc5
at System.Xml.Serialization.ReflectionXmlSerializationReader.<>c__DisplayClass53_1.<WriteLiteralStructMethod>g__Wrapper|1(Object value) + 0x61
at System.Xml.Serialization.ReflectionXmlSerializationReader.WriteAttribute(ReflectionXmlSerializationReader.Member, Object) + 0x4be
at System.Xml.Serialization.ReflectionXmlSerializationReader.WriteAttributes(ReflectionXmlSerializationReader.Member[], ReflectionXmlSerializationReader.Member, UnknownNodeAction, Object&) + 0x35b
at System.Xml.Serialization.ReflectionXmlSerializationReader.WriteLiteralStructMethod(StructMapping, Boolean, Boolean, String) + 0x13dc
at System.Xml.Serialization.ReflectionXmlSerializationReader.WriteStructMethod(StructMapping, Boolean, Boolean, String) + 0x72
at System.Xml.Serialization.ReflectionXmlSerializationReader.WriteElement(ElementAccessor, Boolean, Boolean, String, Int32, XmlSerializationReader.Fixup, ReflectionXmlSerializationReader.Member) + 0xc34
at System.Xml.Serialization.ReflectionXmlSerializationReader.WriteMemberElementsIf(ReflectionXmlSerializationReader.Member[], ReflectionXmlSerializationReader.Member, UnknownNodeAction, XmlSerializationReader.Fixup, ReflectionXmlSerializationReader.CheckTypeSource) + 0x718
at System.Xml.Serialization.ReflectionXmlSerializationReader.WriteMemberElements(ReflectionXmlSerializationReader.Member[], UnknownNodeAction, UnknownNodeAction, ReflectionXmlSerializationReader.Member, ReflectionXmlSerializationReader.Member, XmlSerializationReader.Fixup, List`1) + 0x116
at System.Xml.Serialization.ReflectionXmlSerializationReader.GenerateTypeElement(XmlTypeMapping) + 0x3f7
at System.Xml.Serialization.ReflectionXmlSerializationReader.ReadObject() + 0xd4
at System.Xml.Serialization.XmlSerializer.DeserializeUsingReflection(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) + 0xc6
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) + 0x1e9
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) + 0x4ed
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle) + 0x83
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader) + 0x27
The test project, which I have tried to prune as much as possible, can be found here: XmlSerializationTest.zip
- Can the linker be forced to instantiate the pruned functions? (private/internal classes and methods, with generic types)
- Is it generally preferable to use ILLink Descriptor Format or the Rd.xml File Format (marked as internal)?
- In the test project. does it matter what flags are used for
xscgen
, and what attributes are finally used to mark the generated classes and fields, and- what collections are eventually used (default is
System.Collections.ObjectModel.Collection`1
)
- what collections are eventually used (default is
- Are there any plans to support this scenario? (I could only find issue Annotate remaining runtime libraries for NativeAOT #75480)
- How can
System.Private.Xml
be modified (to support this scenario)?- Is this just a question of addressing all linker warnings (IL3050) that are printed during the link phase (when
TrimmerSingleWarn
is true), or are other warnings/issues (perhaps being masked)? - Occurrences of IL3050 are:
src/libraries/System.Private.Xml/src/System/Xml/Serialization/Types.cs
: 25 hitssrc/libraries/System.Private.Xml/src/System/Xml/Serialization/CodeGenerator.cs
: 1 hitsrc/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs
: 6 hitssrc/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs
: 1 hitsrc/libraries/System.Private.Xml/src/System/Xml/Serialization/NameTable.cs
: 1 hit
- Is this just a question of addressing all linker warnings (IL3050) that are printed during the link phase (when
- Would the support ever be available in .Net 8, or just .Net 9? (could the solution be back-ported if we get to that point?)
Reproduction Steps
Compile and run attached project:
dotnet publish -c Debug
bin/Debug/net8.0/linux-x64/publish/XmlSerializationTest
Expected behavior
The test program should successfully serialize and deserialize a basic data structure to and from XML.
Actual behavior
See stack trace of crash in the description.
Regression?
No.
Known Workarounds
No response
Configuration
dotnet --info
.NET SDK:
Version: 8.0.303
Commit: 29ab8e3268
Workload version: 8.0.300-manifests.c915c39d
MSBuild version: 17.10.4+10fbfbf2e
Runtime Environment:
OS Name: ubuntu
OS Version: 24.04
OS Platform: Linux
RID: linux-x64
Base Path: /home/user/.dotnet/sdk/8.0.303/
.NET workloads installed:
There are no installed workloads to display.
Host:
Version: 8.0.7
Architecture: x64
Commit: 2aade6beb0
.NET SDKs installed:
6.0.424 [/home/user/.dotnet/sdk]
7.0.410 [/home/user/.dotnet/sdk]
8.0.303 [/home/user/.dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.32 [/home/user/.dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.20 [/home/user/.dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.7 [/home/user/.dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.32 [/home/user/.dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.20 [/home/user/.dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.7 [/home/user/.dotnet/shared/Microsoft.NETCore.App]
Other architectures found:
None
Environment variables:
DOTNET_ROOT [/home/user/.dotnet]
global.json file:
/home/user/Unity/licensing.entitlement4/global.json
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
Other information
See also this issue in xscgen