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

System.Text.Json source generator doesn't work with native AOT IlcDisableReflection #68093

Closed
cfbao opened this issue Apr 15, 2022 · 4 comments
Closed

Comments

@cfbao
Copy link

cfbao commented Apr 15, 2022

Description

System.Text.Json source generator generates code (that calls code) that uses reflection, hence incompatible with the IlcDisableReflection native AOT option.

Was expecting that source generator can eliminate reflection and work with IlcDisableReflection.

offending line seems to be this:

IsInternalConverter = GetType().Assembly == typeof(JsonConverter).Assembly;

Reproduction Steps

using System.Text.Json;
using System.Text.Json.Serialization;

MyClass stuff = new() { Prop = "value" };
string json = JsonSerializer.Serialize( stuff, MyJsonContext.Default.MyClass );
Console.WriteLine( json );

internal record MyClass {
	public string? Prop { get; set; }
}

[JsonSerializable( typeof( MyClass ) )]
internal partial class MyJsonContext : JsonSerializerContext { }
  • add <IlcDisableReflection>true</IlcDisableReflection> to csproj file
  • run dotnet publish -r <RID>
  • run the produced exe

Expected behavior

program prints {"Prop":"value"} on the console

Actual behavior

the following error shows up

Unhandled Exception: EETypeRva:0x002EFD88: Reflection_Disabled
   at Internal.Reflection.RuntimeTypeInfo.get_Assembly() + 0x59
   at System.Text.Json.Serialization.JsonConverter`1..ctor() + 0xc8
   at System.Text.Json.Serialization.JsonResumableConverter`1..ctor() + 0x18
   at System.Text.Json.Serialization.Converters.JsonMetadataServicesConverter`1..ctor(Func`1, ConverterStrategy) + 0x30
   at System.Text.Json.Serialization.Metadata.SourceGenJsonTypeInfo`1.GetConverter(JsonObjectInfoValues`1) + 0x194
   at System.Text.Json.Serialization.Metadata.SourceGenJsonTypeInfo`1..ctor(JsonSerializerOptions, JsonObjectInfoValues`1) + 0x78
   at System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateObjectInfo[T](JsonSerializerOptions, JsonObjectInfoValues`1) + 0x67
   at MyJsonContext.get_Stuff() + 0x2cd
   at Program.<Main>$(String[]) + 0x73

Regression?

No response

Known Workarounds

No response

Configuration

.NET SDK 7.0.100-preview.3.22179.4, commit c48f2c30ee
Windows 10.0.18363, RID: win10-x64
Host version: 7.0.0-preview.3.22175.4, commit 162f836

Other information

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Apr 15, 2022
@ghost
Copy link

ghost commented Apr 15, 2022

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

System.Text.Json source generator generates code (that calls code) that uses reflection, hence incompatible with the IlcDisableReflection native AOT option.

Was expecting that source generator can eliminate reflection and work with IlcDisableReflection.

offending line seems to be this:

IsInternalConverter = GetType().Assembly == typeof(JsonConverter).Assembly;

Reproduction Steps

using System.Text.Json;
using System.Text.Json.Serialization;

MyClass stuff = new() { Prop = "value" };
string json = JsonSerializer.Serialize( stuff, MyJsonContext.Default.MyClass );
Console.WriteLine( json );

internal record MyClass {
	public string? Prop { get; set; }
}

[JsonSerializable( typeof( MyClass ) )]
internal partial class MyJsonContext : JsonSerializerContext { }
  • add <IlcDisableReflection>true</IlcDisableReflection> to csproj file
  • run dotnet publish -r <RID>
  • run the produced exe

Expected behavior

program prints {"Prop":"value"} on the console

Actual behavior

the following error shows up

Unhandled Exception: EETypeRva:0x002EFD88: Reflection_Disabled
   at Internal.Reflection.RuntimeTypeInfo.get_Assembly() + 0x59
   at System.Text.Json.Serialization.JsonConverter`1..ctor() + 0xc8
   at System.Text.Json.Serialization.JsonResumableConverter`1..ctor() + 0x18
   at System.Text.Json.Serialization.Converters.JsonMetadataServicesConverter`1..ctor(Func`1, ConverterStrategy) + 0x30
   at System.Text.Json.Serialization.Metadata.SourceGenJsonTypeInfo`1.GetConverter(JsonObjectInfoValues`1) + 0x194
   at System.Text.Json.Serialization.Metadata.SourceGenJsonTypeInfo`1..ctor(JsonSerializerOptions, JsonObjectInfoValues`1) + 0x78
   at System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateObjectInfo[T](JsonSerializerOptions, JsonObjectInfoValues`1) + 0x67
   at MyJsonContext.get_Stuff() + 0x2cd
   at Program.<Main>$(String[]) + 0x73

Regression?

No response

Known Workarounds

No response

Configuration

.NET SDK 7.0.100-preview.3.22179.4, commit c48f2c30ee
Windows 10.0.18363, RID: win10-x64
Host version: 7.0.0-preview.3.22175.4, commit 162f836

Other information

No response

Author: cfbao
Assignees: -
Labels:

area-System.Text.Json, untriaged

Milestone: -

@jkotas
Copy link
Member

jkotas commented Apr 16, 2022

IlcDisableReflection mode is very restrictive. It disables majority of the reflection APIs, even the ones that are generally ok with AOT. We do not plan support it in its current form.

#67193
dotnet/runtimelab#635 (comment)

@layomia
Copy link
Contributor

layomia commented May 17, 2022

Current work to support JsonSerialzier's conformance with AOT analysis: #68464, #68878.

@layomia layomia removed the untriaged New issue has not been triaged by the area owner label May 17, 2022
@layomia layomia added this to the Future milestone May 17, 2022
@eiriktsarpalis
Copy link
Member

I think we can close this as wontfix. Most of the System.Text.Json.Serialization infrastructure depends on some degree of reflection, even in source generated scenaria. We likely won't be able to change this in the future.

That being said, fast-path serialization in source gen should not require any reflection in principle, however fast-path deserialization is not yet implemented (#55043) and it is still missing features compared to the metadata-based serializer.

@ghost ghost locked as resolved and limited conversation to collaborators Jun 17, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants