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

XmlSerializer.Serialize doesn't work when using TrimMode=link #41389

Closed
marek-safar opened this issue Aug 26, 2020 · 7 comments · Fixed by #44772
Closed

XmlSerializer.Serialize doesn't work when using TrimMode=link #41389

marek-safar opened this issue Aug 26, 2020 · 7 comments · Fixed by #44772
Assignees
Labels
area-Serialization blocked Issue/PR is blocked on something - see comments linkable-framework Issues associated with delivering a linker friendly framework
Milestone

Comments

@marek-safar
Copy link
Contributor

Repro: consoleapp-bfe9f43.zip

Run make linked to run with TrimMode=link, and make notlinked to run the same command, except without setting TrimMode.

$ make linked
** Executing linked app
bin/Debug/netcoreapp5.0/osx-x64/publish/myproject
❌ failed: System.InvalidOperationException: There was an error reflecting type 'LinkSdk.Serialization.XmlSerializationTest.Response'.
 ---> System.InvalidOperationException: There was an error reflecting property 'DataUpdates'.
 ---> System.InvalidOperationException: There was an error reflecting type 'LinkSdk.Serialization.XmlSerializationTest.DataUpdates'.
 ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at System.RuntimeType.RuntimeTypeCache.GetDefaultMemberName()
   at System.RuntimeType.GetDefaultMemberName()
   at System.RuntimeType.GetDefaultMembers()
   at System.Xml.Serialization.TypeScope.GetDefaultIndexer(Type type, String memberInfo)
   at System.Xml.Serialization.TypeScope.ImportTypeDesc(Type type, MemberInfo memberInfo, Boolean directReference)
   at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference, Boolean throwOnError)
   at System.Xml.Serialization.StructModel.GetPropertyModel(PropertyInfo propertyInfo)
   at System.Xml.Serialization.StructModel.GetFieldModel(MemberInfo memberInfo)
   at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type)
   at LinkSdk.Serialization.XmlSerializationTest.Response.get_Serializer() in /Users/rolf/test/dotnet/consoleapp/Program.cs:line 63
   at LinkSdk.Serialization.XmlSerializationTest.Response.Deserialize(String xml) in /Users/rolf/test/dotnet/consoleapp/Program.cs:line 73
   at LinkSdk.Serialization.XmlSerializationTest.Bug1820_GenericList() in /Users/rolf/test/dotnet/consoleapp/Program.cs:line 188
   at App.Main() in /Users/rolf/test/dotnet/consoleapp/Program.cs:line 27

$ make notlinked
** Executing notlinked app
bin/Debug/netcoreapp5.0/osx-x64/publish/myproject
✅ succeeded: LinkSdk.Serialization.XmlSerializationTest+Response
$ dotnet --version
5.0.100-rc.1.20414.5

*** Moved from dotnet/linker#1454 ***

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-Serialization untriaged New issue has not been triaged by the area owner labels Aug 26, 2020
@marek-safar marek-safar added the linkable-framework Issues associated with delivering a linker friendly framework label Aug 26, 2020
@marek-safar
Copy link
Contributor Author

marek-safar commented Aug 26, 2020

/cc @eerhardt @rolfbjarne

@eerhardt eerhardt added this to the 6.0.0 milestone Aug 26, 2020
@eerhardt eerhardt removed the untriaged New issue has not been triaged by the area owner label Aug 26, 2020
@eerhardt
Copy link
Member

In order to make XmlSerializer serialization work with the ILLinker, we will probably need to address dotnet/linker#1087.

@eerhardt eerhardt added the blocked Issue/PR is blocked on something - see comments label Aug 26, 2020
@rolfbjarne
Copy link
Member

Here is another test case: linkertestcase-d179b60.zip

$ ./test.sh 
+ dotnet --version
5.0.100-rc.1.20426.3
+ dotnet publish -r osx-x64 --self-contained true -p:MonoAOT=true -p:VM=mono -p:PublishTrimmed=true Executable/Executable.csproj /bl:x.binlog
Microsoft (R) Build Engine version 16.8.0-preview-20425-03+384d02a5f for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

/usr/local/share/dotnet/sdk/5.0.100-rc.1.20426.3/MSBuild.dll -distributedlogger:Microsoft.DotNet.Tools.MSBuild.MSBuildLogger,/usr/local/share/dotnet/sdk/5.0.100-rc.1.20426.3/dotnet.dll*Microsoft.DotNet.Tools.MSBuild.MSBuildForwardingLogger,/usr/local/share/dotnet/sdk/5.0.100-rc.1.20426.3/dotnet.dll -maxcpucount -property:RuntimeIdentifier=osx-x64 -property:SelfContained=true -p:MonoAOT=true -p:VM=mono -p:PublishTrimmed=true -restore -target:Publish -verbosity:m /bl:x.binlog Executable/Executable.csproj
  Determining projects to restore...
  Restored /Users/rolf/test/linkertestcase/Executable/Executable.csproj (in 159 ms).
  You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
  Executable -> /Users/rolf/test/linkertestcase/Executable/bin/Debug/net5.0/osx-x64/Executable.dll
  Optimizing assemblies for size, which may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
  Executable -> /Users/rolf/test/linkertestcase/Executable/bin/Debug/net5.0/osx-x64/publish/
+ ./Executable/bin/Debug/net5.0/osx-x64/publish/Executable
Unhandled exception. System.InvalidOperationException: There was an error reflecting type 'XmlResult`1[System.String]'.
 ---> System.InvalidOperationException: There was an error reflecting property 'Result'.
 ---> System.InvalidOperationException: You need to add XmlChoiceIdentifierAttribute to the 'Result' member.
   at System.Xml.Serialization.XmlReflectionImporter.CheckAmbiguousChoice(XmlAttributes a, Type accessorType, String accessorName)
   at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type)
   at XmlSerializationTest.GenericProperty_Bug5543() in /Users/rolf/test/linkertestcase/Executable/Program.cs:line 41
   at C.Main() in /Users/rolf/test/linkertestcase/Executable/Program.cs:line 59
./test.sh: line 6: 97907 Abort trap: 6           ./Executable/bin/Debug/net5.0/osx-x64/publish/Executable

rolfbjarne added a commit to rolfbjarne/xamarin-macios that referenced this issue Sep 1, 2020
…oesn't support Xml serialization yet.

Ref: dotnet/runtime#41389 (comment)

Fixes this test failure:

    LinkAll.Serialization.Xml.XmlSerializationTest
        [FAIL] GenericProperty_Bug5543 : System.InvalidOperationException : There was an error reflecting type 'LinkAll.Serialization.Xml.XmlResult`1[System.String]'.
            ----> System.InvalidOperationException : There was an error reflecting property 'Result'.
            ----> System.InvalidOperationException : You need to add XmlChoiceIdentifierAttribute to the 'Result' member.
            at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
            at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, RecursionLimiter limiter)
            at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
            at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
            at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
            at System.Xml.Serialization.XmlSerializer..ctor(Type type)
            at LinkAll.Serialization.Xml.XmlSerializationTest.GenericProperty_Bug5543() in /Users/rolf/work/maccore/whatever/xamarin-macios/tests/linker/ios/link all/XmlSerializationTest.cs:line 52
            at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
            --InvalidOperationException
            at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
            at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
            at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
            --InvalidOperationException
            at System.Xml.Serialization.XmlReflectionImporter.CheckAmbiguousChoice(XmlAttributes a, Type accessorType, String accessorName)
            at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
            at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
            at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
@eerhardt eerhardt self-assigned this Nov 13, 2020
@vitek-karas
Copy link
Member

If this is for Xamarin only, then we should run the test in what will be a Xamarin-like environment. So most notably, Xamarin only trims framework assemblies (just like Blazor) and not the app. I'm guessing, but the types the tests are failing on are probably from "the app".

Otherwise if the goal is to make XmlSerializer work for any trimmed app - or for Xamarin when trimming is enabled on the app itself, then we need either a source generator (or fix sgen and use that instead, which is basically a source generator as well) or new linker functionality.

@eerhardt
Copy link
Member

My current work here is to make XmlSerializer work by default when TrimMode=link is used in any app. (This is analogous to the Xamarin-like environment referenced above). It is currently broken whenever System.Private.Xml.dll is being link trimmed.

As for my previous comment and the blocked label - these only apply when the whole app is trimmed (or more correctly - XmlSerialize fails when the Type you are serializing is in an assembly that is being link trimmed). I think we should move that to a separate issue, and leave this issue for the scenarios logged above.

@eerhardt
Copy link
Member

@rolfbjarne -

I just tried your repro in #41389 (comment). That test fails even if the app isn't trimmed.

System.InvalidOperationException: You need to add XmlChoiceIdentifierAttribute to the 'Result' member.

This same exception which you mention above occurs for a regular (untrimmed) net5.0 app.

eerhardt added a commit to eerhardt/runtime that referenced this issue Nov 17, 2020
Make XmlSerializer work correctly with ILLinker trimming.

1. Use constant BindingFlags to work around dotnet/linker#1617
2. Annotate CodeGenerator.CreateTypeBuilder correctly to preserve base class members

Fix dotnet#41389
@rolfbjarne
Copy link
Member

@rolfbjarne -

I just tried your repro in #41389 (comment). That test fails even if the app isn't trimmed.

System.InvalidOperationException: You need to add XmlChoiceIdentifierAttribute to the 'Result' member.

This same exception which you mention above occurs for a regular (untrimmed) net5.0 app.

Looks like I diagnosed that test case wrong, it seems to be different than the original issue reported here, so I'll have another look at it.

eerhardt added a commit that referenced this issue Dec 4, 2020
* XmlSerializer.Serialize doesn't work when using TrimMode=link

Make XmlSerializer work correctly with ILLinker trimming.

1. Use constant BindingFlags to work around dotnet/linker#1617
2. Annotate CodeGenerator.CreateTypeBuilder correctly to preserve base class members

Fix #41389

* Update ILLinker suppressions file.

* PR feedback.

Fix ILLinker suppresions.
@ghost ghost locked as resolved and limited conversation to collaborators Jan 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Serialization blocked Issue/PR is blocked on something - see comments linkable-framework Issues associated with delivering a linker friendly framework
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants