LambdaTestTool: System.MissingMethodException: Method not found: 'System.Diagnostics.Metrics.IMeterFactory System.Net.Http.SocketsHttpHandler.get_MeterFactory()'
Closed this issue · 5 comments
Describe the bug
I have a simple dotnet8 lambda which I try to run it locally with Mock Lambda Test Tool v8. The lambda has only these dependencies
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.2" />
<PackageReference Include="Amazon.Lambda.Core" Version="2.1.0"/>
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.3.0"/>
<PackageReference Include="Amazon.Lambda.SQSEvents" Version="2.1.0"/>
</ItemGroup>I'm injecting the HttpClient into a custom service in the constructor
public Function()
{
var services = new ServiceCollection();
services.AddHttpClient<FooAppService>();
var provider = services.BuildServiceProvider();
using var scope = provider.CreateScope();
var sp = scope.ServiceProvider;
var service = sp.GetRequiredService<FooAppService>();
}But when I run it and click on execute button inside Mock Lambda Test Tool window I get this issue:
System.MissingMethodException: Method not found: 'System.Diagnostics.Metrics.IMeterFactory System.Net.Http.SocketsHttpHandler.get_MeterFactory()'.
at Microsoft.Extensions.Http.MetricsFactoryHttpMessageHandlerFilter.<>c__DisplayClass2_0.<Configure>b__0(HttpMessageHandlerBuilder builder)
at Microsoft.Extensions.Http.LoggingHttpMessageHandlerBuilderFilter.<>c__DisplayClass6_0.<Configure>b__0(HttpMessageHandlerBuilder builder)
at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandlerEntry(String name)
at Microsoft.Extensions.Http.DefaultHttpClientFactory.<>c__DisplayClass14_0.<.ctor>b__2()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandler(String name)
at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateClient(String name)
at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.AddTransientHelper[TClient](IServiceProvider s, IHttpClientBuilder builder)
at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.<>c__DisplayClass13_0`1.<AddTypedClientCore>b__0(IServiceProvider s)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at LambdaTest.Function..ctor() in C:\Users\ciolial\dev\alberto.ciolini\LambdaTest\LambdaTest\LambdaTest\src\LambdaTest\Function.cs:line 34
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)
If I downgrade the Microsoft.Extensions.Http to v8.0.0 no exception is raised.
I tried to deploy the same code on AWS and everything went well.
I also tried the same code on Console Application and I had no issue at all.
Regression Issue
- Select this option if this issue appears to be a regression.
Expected Behavior
The expected behaviour is to run the lambda successfully through the Mock Lambda Test Tool
Current Behavior
I got an exception when I try to run the lambda
System.MissingMethodException: Method not found: 'System.Diagnostics.Metrics.IMeterFactory System.Net.Http.SocketsHttpHandler.get_MeterFactory()'.
at Microsoft.Extensions.Http.MetricsFactoryHttpMessageHandlerFilter.<>c__DisplayClass2_0.<Configure>b__0(HttpMessageHandlerBuilder builder)
at Microsoft.Extensions.Http.LoggingHttpMessageHandlerBuilderFilter.<>c__DisplayClass6_0.<Configure>b__0(HttpMessageHandlerBuilder builder)
at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandlerEntry(String name)
at Microsoft.Extensions.Http.DefaultHttpClientFactory.<>c__DisplayClass14_0.<.ctor>b__2()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandler(String name)
at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateClient(String name)
at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.AddTransientHelper[TClient](IServiceProvider s, IHttpClientBuilder builder)
at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.<>c__DisplayClass13_0`1.<AddTypedClientCore>b__0(IServiceProvider s)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at LambdaTest.Function..ctor() in C:\Users\ciolial\dev\alberto.ciolini\LambdaTest\LambdaTest\LambdaTest\src\LambdaTest\Function.cs:line 34
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)
Reproduction Steps
Create a simple lambda injecting the HttpClient into a service with Dependency Injection and with Microsoft.Extensions.Http package with version >= 9.0.0
Possible Solution
No response
Additional Information/Context
No response
AWS .NET SDK and/or Package version used
Amazon.Lambda.Core 2.1.0
Amazon.Lambda.Serialization.SystemTextJson 2.3.0
Amazon.Lambda.SQSEvents 2.1.0
Targeted .NET Platform
.NET 8
Operating System and version
Windows 10
Reproducible using below code:
.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AWSProjectType>Lambda</AWSProjectType>
<!-- This property makes the build directory similar to a publish directory and helps the AWS .NET Lambda Mock Test Tool find project dependencies. -->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<!-- Generate ready to run images during publishing to improve cold start time. -->
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Amazon.Lambda.Core" Version="2.5.0" />
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.4.4" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.2" />
</ItemGroup>
</Project>Function.cs
using Amazon.Lambda.Core;
using Microsoft.Extensions.DependencyInjection;
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
namespace AWSLambdaNet8Test;
public class Function
{
public Function()
{
var services = new ServiceCollection();
services.AddHttpClient<TestService>();
var provider = services.BuildServiceProvider();
using var scope = provider.CreateScope();
var sp = scope.ServiceProvider;
var service = sp.GetRequiredService<TestService>();
}
public string FunctionHandler(string input, ILambdaContext context)
{
return input.ToUpper();
}
}
public class TestService
{
private readonly HttpClient _client;
public TestService(HttpClient client)
{
_client = client;
_client.BaseAddress = new Uri("https://test.service.com/");
}
}Executing it with current GA AWS .NET 8.0 Mock Lambda Test Tool (0.16.2) throws below exception:
System.MissingMethodException: Method not found: 'System.Diagnostics.Metrics.IMeterFactory System.Net.Http.SocketsHttpHandler.get_MeterFactory()'.
at Microsoft.Extensions.Http.MetricsFactoryHttpMessageHandlerFilter.<>c__DisplayClass2_0.<Configure>b__0(HttpMessageHandlerBuilder builder)
at Microsoft.Extensions.Http.LoggingHttpMessageHandlerBuilderFilter.<>c__DisplayClass6_0.<Configure>b__0(HttpMessageHandlerBuilder builder)
at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandlerEntry(String name)
at Microsoft.Extensions.Http.DefaultHttpClientFactory.<>c__DisplayClass14_0.<.ctor>b__2()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandler(String name)
at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateClient(String name)
at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.AddTransientHelper[TClient](IServiceProvider s, IHttpClientBuilder builder)
at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.<>c__DisplayClass13_0`1.<AddTypedClientCore>b__0(IServiceProvider s)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at AWSLambdaNet8Test.Function..ctor() in D:\source\repros\AWSLambdaNet8Test\AWSLambdaNet8Test\Function.cs:line 20
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)The most likely reason is the way Mock Lambda Test tool tries to mimic environment and loads assembly.
@ciolial Could you please try the new experience in Lambda Test tool v2, see https://github.com/aws/aws-lambda-dotnet/tree/master/Tools/LambdaTestTool-v2 and see if the issue goes away?
Thanks,
Ashish
Hi @ashishdhingra , thanks for your support.
I managed to configure the v2 tool correctly and get the lambda running correctly but the process seems much more cumbersome than the previous version.
@ciolial Thanks for trying out the new version of the test tool. The way the new version of the test tool runs out of process of the Lambda function and the Lambda function connect to the test tool via the HTTP REST API mimics a lot closer to how Lambda runs in. It avoids the issues you ran into where the older version dynamically loaded the assemblies into the test tool causing collisions and dependency resolution issues.
Our current focus has been integrating the tool with .NET Aspire which hopefully if you tried new test tool through that experience you'll find it less cumbersome. This blog post I put out last week goes through that experience. https://aws.amazon.com/blogs/developer/building-lambda-with-aspire-part-1/. Feedback on that experience is greatly appreciated.
We do plan on also working on the setup experience for the standalone experience as well with the new test tool but I don't have an ETA for that work.
Closing this ticket since we can use Lambda Test tool v2.
For old Lambda Test tool, it is generally recommended to use packages that target the same .NET version due to the way it tries to mimic Lambda execution by loading assemblies at runtime.
Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.