dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.64k stars 4.57k forks source link

System.Runtime.Caching is not AOT compatible and isn't annotated #102341

Open eerhardt opened 2 months ago

eerhardt commented 2 months ago

Using the following project:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PublishAot>true</PublishAot>
    <InvariantGlobalization>true</InvariantGlobalization>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="System.Runtime.Caching" Version="8.0.0" />
  </ItemGroup>
</Project>
using System.Runtime.Caching;

MemoryCache memoryCache = new MemoryCache("MyCache");

memoryCache.Add("key", "value", DateTime.UtcNow.AddMinutes(1440.0));

Console.WriteLine(memoryCache.Get("key"));

When you dotnet build you don't get any warnings that MemoryCache isn't going to work in a trimmed or AOT'd application.

However, when you dotnet publish the project, you do get a warning:

.nuget\packages\system.configuration.configurationmanager\8.0.0\lib\net8.0\System.Configuration.ConfigurationManager.dll : warning IL2104: Assembly 'System.Configuration.ConfigurationManager' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries [C:\Users\eerhardt\source\repos\ConsoleApp123\ConsoleApp123\ConsoleApp123.csproj]

Then when you run the resulting .exe it fails with:

Unhandled Exception: System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize
 ---> System.MissingMethodException: No parameterless constructor defined for type 'System.Configuration.ClientConfigurationHost'.
   at System.ActivatorImplementation.CreateInstance(Type, Boolean) + 0x119
   at System.Configuration.Internal.ConfigSystem.System.Configuration.Internal.IConfigSystem.Init(Type, Object[]) + 0x43
   at System.Configuration.ClientConfigurationSystem..ctor() + 0x47
   at System.Configuration.ConfigurationManager.EnsureConfigurationSystem() + 0x56
   --- End of inner exception stack trace ---
   at System.Configuration.ConfigurationManager.EnsureConfigurationSystem() + 0xea
   at System.Configuration.ConfigurationManager.PrepareConfigSystem() + 0x12
   at System.Configuration.ConfigurationManager.GetSection(String) + 0x18
   at System.Runtime.Caching.MemoryCacheStatistics.InitializeConfiguration(NameValueCollection) + 0x2c
   at System.Runtime.Caching.MemoryCacheStatistics..ctor(MemoryCache, NameValueCollection) + 0x4a
   at System.Runtime.Caching.MemoryCache.InitDisposableMembers(NameValueCollection) + 0xf1
   at Program.<Main>$(String[] args) + 0x26
   at ConsoleApp123!<BaseAddress>+0x3dc723

We should either make System.Runtime.Caching work with trimming/native AOT, or annotate it as incompatible with trimming.

This is related to https://github.com/dotnet/runtime/issues/75480, but I didn't see System.Runtime.Caching in the list on that issue.

cc @agocke @LakshanF @MichalStrehovsky

MichalStrehovsky commented 2 months ago

This looks like a trimming issue, not AOT issue.

The exception is in ConfigurationManager. Looks like we didn't annotate it as such, and closed the underlying issue as by design :(.

https://github.com/dotnet/runtime/blob/efde0061d4fadce140d9c9bd78bfc2aa7df7d9eb/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj#L6-L8