Open rac146 opened 1 year ago
Hi @rac146,
Good afternoon.
Thanks for opening the issue. Just wanted to check if you referred the blog post Building serverless .NET applications on AWS Lambda using .NET 7 for the Native AOT support. As mentioned, currently, the AWSSDK.Core
library used by all the .NET AWS SDKs must also be excluded from trimming. I guess this is also the case with AWSSDK.*
assemblies. Could you please try adding AWSSDK.DynamoDBv2
in rd.xml
and see if it works. We have the internal backlog item to support trimming for AWS SDK for .NET assemblies, however, do not have the concrete timeline by which it would be supported.
Thanks, Ashish
Hey Ashish,
Even excluding AWSSDK.DynamoDBv2 from trimming, the error still occurs. This error will present itself with or without trimming - this is flagged as an AOT analysis warning, not a trimming warning when running dotnet publish.
Here are the detailed errors when running dotnet publish
with <TrimmerSingleWarn>false</TrimmerSingleWarn>
D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Services\DynamoDBv2\Custom\Conversion\DynamoDBEntryConversion.cs(652): AOT analysis warning IL3050: Amazon.DynamoDBv2.Converter`1.
D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Services\DynamoDBv2\Custom\Conversion\SchemaV1.cs(379): AOT analysis warning IL3050: Amazon.DynamoDBv2.CollectionConverter.
D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Services\DynamoDBv2\Custom\Conversion\SchemaV1.cs(382): AOT analysis warning IL3050: Amazon.DynamoDBv2.CollectionConverter.
D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Services\DynamoDBv2\Custom\Conversion\SchemaV1.cs(384): AOT analysis warning IL3050: Amazon.DynamoDBv2.CollectionConverter.
I've got the current version of the AWSSDK working for now with DynamoDB if I add the following to the rd.xml
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<Assembly Name="AWSSDK.Core" Dynamic="Required All"></Assembly>
<Assembly Name="AWSSDK.DynamoDBv2" Dynamic="Required All"></Assembly>
<Assembly Name="System.Collections">
<Type Name="System.Collections.Generic.HashSet`1[[System.Boolean,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Byte,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Byte[],System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Char,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.DateTime,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Decimal,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Double,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Guid,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Int16,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Int32,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Int64,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.UInt16,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.UInt32,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.UInt64,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.SByte,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Single,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.String,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Boolean,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Byte,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Byte[],System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Char,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.DateTime,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Decimal,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Double,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Guid,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Int16,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Int32,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Int64,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.UInt16,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.UInt32,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.UInt64,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.SByte,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Single,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.String,System.Runtime]]" Dynamic="Required All" />
</Assembly>
</Application>
</Directives>
Hope this helps other for now.
Adding to @jesmiatka. I needed these lines additionally to make it work:
<Type Name="System.Nullable`1[System.Byte]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.SByte]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.UInt16]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Int32]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.UInt32]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Int16]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Int64]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.UInt64]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Single]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Double]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Decimal]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Char]" Dynamic="Required All"/>'
<Type Name="System.Nullable`1[System.DateTime]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Guid]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Enum]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Boolean]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.IO.MemoryStream]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.String]" Dynamic="Required All"/>
@MrZoidberg In which assembly is System.Nullable? Can you share the whole Assembly entry in rd.xml
?
In System.Runtime. Here the whole rd.xml:
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<Assembly Name="AWSSDK.Core" Dynamic="Required All"></Assembly>
<Assembly Name="AWSSDK.DynamoDBv2" Dynamic="Required All"></Assembly>
<Assembly Name="System.Collections">
<Type Name="System.Collections.Generic.HashSet`1[[System.Boolean,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Byte,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Byte[],System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Char,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.DateTime,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Decimal,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Double,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Guid,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Int16,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Int32,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Int64,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.UInt16,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.UInt32,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.UInt64,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.SByte,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Single,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.String,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Boolean,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Byte,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Byte[],System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Char,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.DateTime,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Decimal,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Double,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Guid,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Int16,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Int32,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Int64,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.UInt16,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.UInt32,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.UInt64,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.SByte,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Single,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.String,System.Runtime]]" Dynamic="Required All" />
</Assembly>
<Assembly Name="System.Runtime">
<Type Name="System.Nullable`1[System.Byte]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.SByte]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.UInt16]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Int32]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.UInt32]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Int16]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Int64]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.UInt64]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Single]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Double]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Decimal]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Char]" Dynamic="Required All"/>'
<Type Name="System.Nullable`1[System.DateTime]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Guid]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Enum]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Boolean]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.IO.MemoryStream]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.String]" Dynamic="Required All"/>
</Assembly>
</Application>
</Directives>
Any updates on this one? Or maybe with regard to .NET 8?
In my scenario (dotnet8, managed runtime) I've used @branog68 modifications, but had to exclude these three lines due to compilation errors:
<Type Name="System.Nullable`1[System.Enum]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.IO.MemoryStream]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.String]" Dynamic="Required All"/>
After this fix, DynamoDbContext
started working.
Although it doesn't fix the issue, this PR marked these as not compatible and has some explanation of what it would take to fix.
Also, Microsoft recommends moving away from rd.xml
files as they are no longer support and instead using the trimming options here: https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options?pivots=dotnet-8-0
Hey @Beau-Gosse-dev , I may be missing it but can you point to where Microsoft are moving away from rd.xml
? I can only see that it is not listed on that site at all, not that they recommend not using it.
@beeradmoore There are other reference from Michal, but here is one: https://github.com/dotnet/runtime/issues/72989#issuecomment-1198778044
Perfect. Thanks @Beau-Gosse-dev
Hello.
"rd.xml" has been deprecated, The alternative solution TrimmerRootDescriptor xml in dotnet8 does not seem to solve this problem.
https://github.com/dotnet/runtime/issues/95058 https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options?pivots=dotnet-8-0
So until dotnet 9 or the aws dynamodb sdk supports nativeaot, do I need to use the "rd.xml" file?
@sudoudaisuke , I think the trimming options listed in the link you posted should be able to do anything you're doing in an rd.xml file. Which part of the rd.xml file is not supported with the other/newer trimming options?
@Beau-Gosse-dev
I tested 3 patterns.
Cases 1 and 2 succeeded, but Case 3 warn at compiletime and failed at runtime. The reason for the error is described in the following link, but the "TrimmerRootDescriptor" xml file does not seem to work well with dotnet8 for generic type descriptions. The same link recommends "TrimmerRootAssembly" and "Type.GetType("")" as workarounds.
https://github.com/dotnet/runtime/issues/95058
$ dotnet publish && ./bin/Release/net8.0/linux-x64/publish/bootstrap
HelloWorldAot -> ./bin/Release/net8.0/linux-x64/publish/
Unhandled Exception: System.TypeInitializationException: A type initializer threw an exception. To determine which type, inspect the InnerException's StackTrace property.
---> System.NotSupportedException: 'System.Nullable`1[System.Byte]' is missing native code or metadata. This can happen for code that is not compatible with trimming or AOT. Inspect and fix trimming and AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility
at System.Reflection.Runtime.General.TypeUnifier.WithVerifiedTypeHandle(RuntimeConstructedGenericTypeInfo, RuntimeTypeInfo[]) + 0x85
at Amazon.DynamoDBv2.Converter`1.<GetTargetTypes>d__0.MoveNext() + 0xd4
at Amazon.DynamoDBv2.ConverterCache.AddConverter(Converter converter, DynamoDBEntryConversion conversion) + 0x99
at Amazon.DynamoDBv2.DynamoDBEntryConversion.SetV1Converters() + 0x2d
at Amazon.DynamoDBv2.DynamoDBEntryConversion..ctor(ConversionSchema schema, Boolean isImmutable) + 0x9f
at Amazon.DynamoDBv2.DynamoDBEntryConversion..cctor() + 0x27
at System.Runtime.CompilerServices.ClassConstructorRunner.EnsureClassConstructorRun(StaticClassConstructionContext*) + 0xb4
--- End of inner exception stack trace ---
at System.Runtime.CompilerServices.ClassConstructorRunner.EnsureClassConstructorRun(StaticClassConstructionContext*) + 0x147
at System.Runtime.CompilerServices.ClassConstructorRunner.CheckStaticClassConstructionReturnNonGCStaticBase(StaticClassConstructionContext*, IntPtr) + 0x9
at Program.<<Main>$>d__0.MoveNext() + 0x372
--- End of stack trace from previous location ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x1c
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xbe
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4e
at Program.<Main>(String[] args) + 0x24
at bootstrap!<BaseAddress>+0x93b7cc
Aborted
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AWSProjectType>Lambda</AWSProjectType>
<AssemblyName>bootstrap</AssemblyName>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<PublishAot>true</PublishAot>
<StripSymbols>true</StripSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Amazon.Lambda.RuntimeSupport" Version="1.10.0" />
<PackageReference Include="Amazon.Lambda.APIGatewayEvents" Version="2.7.1" />
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.4.3" />
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.7.400.3" />
</ItemGroup>
<!--
<ItemGroup>
<TrimmerRootAssembly Include="AWSSDK.Core" />
<TrimmerRootAssembly Include="AWSSDK.DynamoDBv2" />
<TrimmerRootAssembly Include="bootstrap" />
</ItemGroup>
-->
<!--
<ItemGroup>
<TrimmerRootDescriptor Include="MyRoots.xml" />
</ItemGroup>
-->
<!--
<ItemGroup>
<RdXmlFile Include="rd.xml" />
</ItemGroup>
-->
</Project>
<linker>
<assembly fullname="AWSSDK.Core" preserve="all" />
<assembly fullname="AWSSDK.DynamoDBv2" preserve="all" />
<assembly fullname="bootstrap" preserve="all" />
<assembly fullname="System.Collections">
<type fullname="System.Collections.Generic.HashSet`1[[System.Boolean,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.Byte,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.Byte[],System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.Char,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.DateTime,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.Decimal,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.Double,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.Guid,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.Int16,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.Int32,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.Int64,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.UInt16,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.UInt32,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.UInt64,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.SByte,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.Single,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.HashSet`1[[System.String,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.Boolean,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.Byte,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.Byte[],System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.Char,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.DateTime,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.Decimal,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.Double,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.Guid,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.Int16,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.Int32,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.Int64,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.UInt16,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.UInt32,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.UInt64,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.SByte,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.Single,System.Runtime]]" preserve="all" />
<type fullname="System.Collections.Generic.List`1[[System.String,System.Runtime]]" preserve="all" />
</assembly>
<assembly fullname="System.Runtime">
<type fullname="System.Nullable`1[System.Byte]" preserve="all"/>
<type fullname="System.Nullable`1[System.SByte]" preserve="all"/>
<type fullname="System.Nullable`1[System.UInt16]" preserve="all"/>
<type fullname="System.Nullable`1[System.Int32]" preserve="all"/>
<type fullname="System.Nullable`1[System.UInt32]" preserve="all"/>
<type fullname="System.Nullable`1[System.Int16]" preserve="all"/>
<type fullname="System.Nullable`1[System.Int64]" preserve="all"/>
<type fullname="System.Nullable`1[System.UInt64]" preserve="all"/>
<type fullname="System.Nullable`1[System.Single]" preserve="all"/>
<type fullname="System.Nullable`1[System.Double]" preserve="all"/>
<type fullname="System.Nullable`1[System.Decimal]" preserve="all"/>
<type fullname="System.Nullable`1[System.Char]" preserve="all"/>'
<type fullname="System.Nullable`1[System.DateTime]" preserve="all"/>
<type fullname="System.Nullable`1[System.Guid]" preserve="all"/>
<!--
<type fullname="System.Nullable`1[System.Enum]" preserve="all"/>
-->
<type fullname="System.Nullable`1[System.Boolean]" preserve="all"/>
<!--
<type fullname="System.Nullable`1[System.IO.MemoryStream]" preserve="all"/>
<type fullname="System.Nullable`1[System.String]" preserve="all"/>
-->
</assembly>
</linker>
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<Assembly Name="AWSSDK.Core" Dynamic="Required All" />
<Assembly Name="AWSSDK.DynamoDBv2" Dynamic="Required All" />
<Assembly Name="bootstrap" Dynamic="Required All" />
<Assembly Name="System.Collections">
<Type Name="System.Collections.Generic.HashSet`1[[System.Boolean,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Byte,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Byte[],System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Char,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.DateTime,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Decimal,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Double,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Guid,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Int16,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Int32,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Int64,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.UInt16,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.UInt32,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.UInt64,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.SByte,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.Single,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.HashSet`1[[System.String,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Boolean,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Byte,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Byte[],System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Char,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.DateTime,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Decimal,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Double,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Guid,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Int16,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Int32,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Int64,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.UInt16,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.UInt32,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.UInt64,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.SByte,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.Single,System.Runtime]]" Dynamic="Required All" />
<Type Name="System.Collections.Generic.List`1[[System.String,System.Runtime]]" Dynamic="Required All" />
</Assembly>
<Assembly Name="System.Runtime">
<Type Name="System.Nullable`1[System.Byte]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.SByte]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.UInt16]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Int32]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.UInt32]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Int16]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Int64]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.UInt64]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Single]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Double]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Decimal]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Char]" Dynamic="Required All"/>'
<Type Name="System.Nullable`1[System.DateTime]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.Guid]" Dynamic="Required All"/>
<!--
<Type Name="System.Nullable`1[System.Enum]" Dynamic="Required All"/>
-->
<Type Name="System.Nullable`1[System.Boolean]" Dynamic="Required All"/>
<!--
<Type Name="System.Nullable`1[System.IO.MemoryStream]" Dynamic="Required All"/>
<Type Name="System.Nullable`1[System.String]" Dynamic="Required All"/>
-->
</Assembly>
</Application>
</Directives>
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
/*
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.Boolean]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.Byte]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.Byte[]]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.Char]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.DateTime]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.Decimal]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.Double]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.Guid]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.Int16]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.Int32]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.Int64]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.UInt16]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.UInt32]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.UInt64]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.SByte]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.Single]");
_ = Type.GetType("System.Collections.Generic.HashSet`1[System.String]");
_ = Type.GetType("System.Collections.Generic.List`1[System.Boolean]");
_ = Type.GetType("System.Collections.Generic.List`1[System.Byte]");
_ = Type.GetType("System.Collections.Generic.List`1[System.Byte[]]");
_ = Type.GetType("System.Collections.Generic.List`1[System.Char]");
_ = Type.GetType("System.Collections.Generic.List`1[System.DateTime]");
_ = Type.GetType("System.Collections.Generic.List`1[System.Decimal]");
_ = Type.GetType("System.Collections.Generic.List`1[System.Double]");
_ = Type.GetType("System.Collections.Generic.List`1[System.Guid]");
_ = Type.GetType("System.Collections.Generic.List`1[System.Int16]");
_ = Type.GetType("System.Collections.Generic.List`1[System.Int32]");
_ = Type.GetType("System.Collections.Generic.List`1[System.Int64]");
_ = Type.GetType("System.Collections.Generic.List`1[System.UInt16]");
_ = Type.GetType("System.Collections.Generic.List`1[System.UInt32]");
_ = Type.GetType("System.Collections.Generic.List`1[System.UInt64]");
_ = Type.GetType("System.Collections.Generic.List`1[System.SByte]");
_ = Type.GetType("System.Collections.Generic.List`1[System.Single]");
_ = Type.GetType("System.Collections.Generic.List`1[System.String]");
_ = Type.GetType("System.Nullable`1[System.Byte]");
_ = Type.GetType("System.Nullable`1[System.SByte]");
_ = Type.GetType("System.Nullable`1[System.UInt16]");
_ = Type.GetType("System.Nullable`1[System.Int16]");
_ = Type.GetType("System.Nullable`1[System.UInt32]");
_ = Type.GetType("System.Nullable`1[System.Int32]");
_ = Type.GetType("System.Nullable`1[System.UInt64]");
_ = Type.GetType("System.Nullable`1[System.Int64]");
_ = Type.GetType("System.Nullable`1[System.Single]");
_ = Type.GetType("System.Nullable`1[System.Double]");
_ = Type.GetType("System.Nullable`1[System.Decimal]");
_ = Type.GetType("System.Nullable`1[System.Char]");
_ = Type.GetType("System.Nullable`1[System.DateTime]");
_ = Type.GetType("System.Nullable`1[System.Guid]");
//_ = Type.GetType("System.Nullable`1[System.Enum]");
_ = Type.GetType("System.Nullable`1[System.Boolean]");
//_ = Type.GetType("System.Nullable`1[System.IO.MemoryStream]");
//_ = Type.GetType("System.Nullable`1[System.String]");
*/
_ = DynamoDBEntryConversion.V2.ConvertToEntry(true);
_ = DynamoDBEntryConversion.V1.ConvertToEntry(true);
_ = DynamoDBEntryConversion.V2.ConvertToEntry(new byte[] { 0x00 });
_ = DynamoDBEntryConversion.V1.ConvertToEntry(new byte[] { 0x00 });
var context = new DynamoDBContext(new AmazonDynamoDBClient(new AmazonDynamoDBConfig { ServiceURL = "http://localhost:8000/", UseHttp = true }));
int bookId = 1001; // Some unique value.
Book myBook = new Book
{
Id = bookId,
Title = "object persistence-AWS SDK for.NET SDK-Book 1001",
Isbn = "111-1111111001",
BookAuthors = new List<string> { "Author 1", "Author 2" },
};
await context.SaveAsync(myBook);
_ = await context.LoadAsync<Book>(bookId);
Console.WriteLine("ok");
[DynamoDBTable("ProductCatalog")]
public class Book
{
public Book() { }
[DynamoDBHashKey] // Partition key
public int Id { get; set; }
[DynamoDBProperty]
public string Title { get; set; }
[DynamoDBProperty]
public string Isbn { get; set; }
[DynamoDBProperty("Authors")] // String Set datatype
public List<string> BookAuthors { get; set; }
}
Thanks for the detailed explanation. That helps a lot. I think this quote for the other issue you linked is important:
The position is really that if something is generating warnings, it may not work, it needs to be written so that it doesn't warn, and that's it.
If option 2 is working as a work-around for now, that's okay. But we wouldn't recommend using any of this in production unless you can get rid of all trimming warnings in the first place. Because even if it's working today, something could change in your code that breaks it at runtime in the future and you could have no advanced warning that it will break.
What really needs to be done is a refactoring/rewrite of the DynamoDb reflection code to remove unconstrained reflection in order to remove all trimming warnings. Possibly with source generators.
Describe the bug
Was running some NET7 AOT experiments with DynamoDBContext and was receiving runtime errors after doing an AOT compilation:
Expected Behavior
For DynamoDB to be AOT NET 7 supported
Current Behavior
Errors out after dotnet publish in NET7 AOT mode
Reproduction Steps
Attempt to run any DynamoDB queries that use DynamoDBContext with latest version of AWS SDK
Possible Solution
Decided to hack into the SDK to find the culprit. Discovered .MakeGenericType is throwing the runtime errors. Switched these 4 lines for experimentation purposes:
In
DynamoDBEntryConversion.cs
: Line 651:var nullableType = typeof(Nullable<>).MakeGenericType(type)
Potential Fix?:yield return typeof(Nullable<>);
In SchemaV1.cs:
Line 379:
yield return pt.MakeArrayType();
Fix?:yield return typeof(Array);
Line 382:yield return listType.MakeGenericType(pt);
Fix?:yield return typeof(List<>);
Line 384:yield return setType.MakeGenericType(pt);
Fix?:yield return typeof(HashSet<>);
This allowed my test application to run and work correctly. Is this is right long-term fix to the problem? I don't know, but just wanted to let you know!
Additional Information/Context
With AWS starting to push AOT further, it would be great to start working through the bugs that prevent an AOT build from working. I believe this fits as a bug opposed to a feature request, especially with the push towards AOT compatible lambdas!
AWS .NET SDK and/or Package version used
AWS SDK DynamoDBv2 3.7.101.44
Targeted .NET Platform
.NET 7
Operating System and version
Windows 10