Sdk: PublishTrimmed trims too much (Could not load type 'System.Text.Json.JsonSerializer')

Created on 25 Sep 2019  路  6Comments  路  Source: dotnet/sdk

Steps to reproduce

Expected behavior

The program starts successfully.

Actual behavior

grafik

Note that this window only appears if you run the binary from a console - if I doubleclick it in an explorer window, the process exits without displaying that error window. Is that intended or a seperate bug? Shouldn't it be the other way round?

Environment data

dotnet --info output:

PS C:\Users\Benni\repositories\VncMatrix\VncMatrix> dotnet --info                                                                                                                                                                                                               .NET Core SDK (gem盲脽 "global.json"):                                                                                                                                                                                                                                             Version:   3.0.100
 Commit:    04339c3a26

Laufzeitumgebung:
 OS Name:     Windows
 OS Version:  10.0.18362
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.0.100\

Host (useful for support):
  Version: 3.0.0
  Commit:  7d57652f33

.NET Core SDKs installed:
  2.1.505 [C:\Program Files\dotnet\sdk]
  2.1.801 [C:\Program Files\dotnet\sdk]
  2.2.105 [C:\Program Files\dotnet\sdk]
  3.0.100-preview9-014004 [C:\Program Files\dotnet\sdk]
  3.0.100-rc1-014190 [C:\Program Files\dotnet\sdk]
  3.0.100 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.0-preview9.19424.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.0-rc1.19457.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.0-preview9-19423-09 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.0-rc1-19456-20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.0.0-preview9-19423-09 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.0.0-rc1-19456-20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download

Most helpful comment

I'm having basically the same problem, but with the issue that I have no idea how to find what roots I need to include, since the failure is deep inside private WPF code.

The top of a ~90 line stack trace is:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.TypeInitializationException: The type initializer for 'MS.Internal.SystemXmlLinqExtension' threw an exception.
 ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at MS.Internal.SystemXmlLinqExtension..cctor()
   --- End of inner exception stack trace ---
   at MS.Internal.SystemXmlLinqExtension..ctor()
   --- End of inner exception stack trace ---
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& hasNoDefaultCtor)
   at System.RuntimeType.CreateInstanceDefaultCtorSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean fillCache)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type)
   at MS.Internal.AssemblyHelper.LoadExtensionFor(String name)
   at MS.Internal.AssemblyHelper.ExtensionsForSystemXmlLinq(Boolean force)
   at MS.Internal.SystemXmlLinqHelper.IsXElement(Object item)

This is also an open issue in the Mono tracker (https://github.com/mono/linker/issues/712), which directed me at adding:

  <ItemGroup>
    <TrimmerRootAssembly Include="System" />
    <TrimmerRootAssembly Include="PresentationFramework-SystemXmlLinq" />
  </ItemGroup>

However that has no effect. The untrimmed version of the PresentationFramework-SystemXmlLinq.dll file is 18 KB, while the trimmed version (with or without the above directive) is 6 KB. Using dnSpy to look at the class constructor only sees GetType() reflection as anything likely to cause this problem, but making sure System.dll was included didn't help.

Everything works fine with PublishTrimmed set to false.

Overall, between this and other bugs I've encountered, PublishTrimmed has been quite a headache.

All 6 comments

@jeffschwMSFT @sbomer

@Trolldemorted thanks for the feedback. The Linker emits a warning with a link to this site: https://aka.ms/dotnet-illink. Linking code that is reliant on reflection will require specific roots. In this case you may be back to a working case with the following:

<ItemGroup>
  <TrimmerRootAssembly Include="System.Text.Json" />
</ItemGroup>

cc @sbomer @tlakollo

I'm having basically the same problem, but with the issue that I have no idea how to find what roots I need to include, since the failure is deep inside private WPF code.

The top of a ~90 line stack trace is:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.TypeInitializationException: The type initializer for 'MS.Internal.SystemXmlLinqExtension' threw an exception.
 ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at MS.Internal.SystemXmlLinqExtension..cctor()
   --- End of inner exception stack trace ---
   at MS.Internal.SystemXmlLinqExtension..ctor()
   --- End of inner exception stack trace ---
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& hasNoDefaultCtor)
   at System.RuntimeType.CreateInstanceDefaultCtorSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean fillCache)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type)
   at MS.Internal.AssemblyHelper.LoadExtensionFor(String name)
   at MS.Internal.AssemblyHelper.ExtensionsForSystemXmlLinq(Boolean force)
   at MS.Internal.SystemXmlLinqHelper.IsXElement(Object item)

This is also an open issue in the Mono tracker (https://github.com/mono/linker/issues/712), which directed me at adding:

  <ItemGroup>
    <TrimmerRootAssembly Include="System" />
    <TrimmerRootAssembly Include="PresentationFramework-SystemXmlLinq" />
  </ItemGroup>

However that has no effect. The untrimmed version of the PresentationFramework-SystemXmlLinq.dll file is 18 KB, while the trimmed version (with or without the above directive) is 6 KB. Using dnSpy to look at the class constructor only sees GetType() reflection as anything likely to cause this problem, but making sure System.dll was included didn't help.

Everything works fine with PublishTrimmed set to false.

Overall, between this and other bugs I've encountered, PublishTrimmed has been quite a headache.

Same problem. Glad this came up first on search or would never have figured the trimmer was the reason!

I haven't debugged this, but have an idea from looking at SystemXmlLinqExtension..cctor. This reflects over properties of XElement that were probably removed by the linker, causing the NRE. You may be able to work around this by telling the linker to keep this type:

<linker>
  <assembly fullname="System.Xml.Linq">
    <type fullname="System.Xml.Linq.XElement" />
  </assembly>
</linker>

Even if this works, you are likely to come across more reflection patterns causing trouble for the linker. Currently working through all such problems may require looking at WPF internals. We are working on longer-term solutions and are happy to look at issues like this one in the meantime (they provide useful information about reflection patterns we need to handle or mitigate).

I'm running into a similar issue with a .NET Core 3.1 single file .exe that is using the PublishTrimmed option. When running it on a Windows 2008 R2 server (6.1.7601) I get the following error:

The type initializer for 'MS.Internal.SystemXmlLinqExtension' threw an exception.

The error does not occur when running the .exe locally on Windows 10 (Version 1909, OS build 18363.900)

Was this page helpful?
0 / 5 - 0 ratings