Aws-lambda-dotnet: Nuget 依赖项抛出 System.IO.FileNotFoundException

创建于 2019-03-15  ·  32评论  ·  资料来源: aws/aws-lambda-dotnet

我不确定这是 libphonenumber 问题还是 AWS Lambda 测试工具问题。 感觉是测试工具有问题。

复制步骤:
1)安装AWS Lambda测试工具包:https://aws.amazon.com/blogs/developer/debugging-net-core-aws-lambda-functions-using-the-aws-net-mock-lambda-test-工具/
1) 创建一个空的无服务器 Lambda 应用程序
2)添加libphonenumber包作为依赖
3) 在Function构造函数中,执行var foo = PhoneNumberUtil.GetInstance();
4) 运行调试器
5) 发送任何请求

构造函数根本不运行。

System.IO.FileNotFoundException: Could not load file or assembly 'PhoneNumbers, Version=8.10.6.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
   at Mercury.Function..ctor()

我能想到的最小的复制案例附在这里。
AWSServerlessApp.zip

investigating

最有用的评论

我对 Google.Apis.Auth 依赖项有同样的问题。 它在部署到 AWS 时工作正常,但是当我尝试使用测试工具在本地运行它时,出现此错误。 我正在使用 .NET Core 2.1 和测试工具 0.9.2。

System.IO.FileLoadException:无法加载文件或程序集“Google.Apis.Auth,版本=1.35.1.0,文化=中性,PublicKeyToken=4b01fa6e34db77ab”。 操作在当前状态下是不合法的。

所有32条评论

我还下载了 libphonenumber 的源代码,并将 csproj 添加为 lambda 解决方案中的项目参考。 它构建得很好,但是一旦我通过测试工具调用 lambda,就会发生同样的错误。

我也在 libphonenumber 项目中打开了一个错误,因为我不确定问题出在哪一边:
https://github.com/twcclegg/libphonenumber-csharp/issues/95

@rianjs ,我们正在调查这个。 我已经确认它在测试工具中不起作用,但同一个库将在控制台应用程序中工作——正如您在另一个 repo 的问题中所述。 我还验证了其他一些库可以与测试工具一起使用,所以现在我将继续调查为什么这个库不能。 让我知道您是否有更新。 感谢您报告它。

如果代码是开放的,我会很乐意自己完成它。 ;P

我猜它在“真实”的 lambda 环境中运行良好。

问题:

我有类似的问题,但使用不同的库。 我有一个引用 Microsoft.EntityFrameworkCore 2.2.3 和 Microsoft.EntityFrameworkCore.Sqlite 2.2.3 的 netcore2.1 lambda 项目。 在 Visual Studio 中使用 Mock Lambda 测试工具运行时,会引发以下异常:

System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Data.Sqlite, Version=2.2.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
   at AWSLambda_EfCoreTest.Function.FunctionHandler(String input, ILambdaContext context)

我已经确认这个 lambda 函数可以在真实的基于 AWS 云的 Lambda 环境中成功部署和运行。

见附上的小复制项目

来源:

我克隆了 aws-lambda-dotnet 存储库并运行了测试工具。 我创建了新的单元测试来调用该工具并单步执行代码。 测试工具在 Amazon.Lambda.TestTool.Runtime::LambdaAssemblyResolver::OnResolving 方法期间引发异常。 此方法无法解析 AssemblyName = Microsoft.Data.Sqlite 并将返回 null。 如果程序集未解析,此方法是 LoadContext 必须调用 System.IO.FileNotFoundException 之前调用的最后一个方法。


另一个问题中发布的解决方案有效。 在那个问题上,作者只是简单地降级到了 2.1.* 版本。 如果我们将两个 ef 核心引用降级到 2.1.8,测试工具将再次开始工作。 但是,这不是我的选择。 我正在尝试利用 ef core 2.2.* 中的新功能。 IMO 该工具应该能够加载 lambda 也支持的程序集。

corefx repo 中的这个未解决的问题可能会暗示潜在的问题。

我会进一步探索,但我没有时间。 有任何想法吗?

AWSLambda_NetCore21-EfCore22Test.zip

我推出了 0.9.2 版,它改变了搜索依赖项的方式。 通过这个更改,我能够使用这个使用 libphonenumber 的工具执行 lambda 函数。

如果您使用的是 Visual Studio 和 AWS Toolkit for Visual Studio,那么在您下次打开解决方案(假设您在线)时,应该会自动更新到 0.9.2。

还有@rianjs ,模拟测试工具的代码是开源的,可以在https://github.com/aws/aws-lambda-dotnet/tree/master/Tools/LambdaTestTool的这个 repo 中找到

@normj

感谢你目前的帮助。 我将工具更新到 0.9.2。 我仍然收到 System.IO.FileNotFoundException。 您可以使用我上面列出的示例项目进行复制吗?

现在,我可以通过控制台应用程序启动我的 lambda 函数以进行本地开发。

嗯,这仍然对我不起作用。

我之前编辑的评论是错误的。 最新的问题只是 PEBKAC。 发现 LibPhoneNumber 程序集很好。

我在 0.9.2 中遇到了这个问题,其中一个 nuget 包被我的 lambda 项目所依赖的另一个项目引用。

我在 0.9.2 中遇到了同样的问题。
测试工具已经加载了 Microsoft.Extensions.* 2.1。 , 所以如果我们想使用 Microsoft.Extensions 将会失败。 2.2.*。

你能解决这个问题吗?

@jiabiao我也有同样的问题。

System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621)

版本 0.9.2

@AngelVenchev您可以尝试将版本从 2.2 更改为 2.1 吗? 对于类似的问题,这对我有用。 可能与 Lambda 不支持 .Net Core 2.2 有关

@IdresAhmed这就是我最终要做的,尽管我现在有两个版本 2.2 用于部署到 lambda 和 2.1 用于在本地运行。

@IdresAhmed @AngelVenchev我打开了此功能请求,该请求将解决使用不同版本 Microsoft.Extensions.* 的问题,然后由测试工具的 ASP.NET Core Web 应用程序加载

我对 Google.Apis.Auth 依赖项有同样的问题。 它在部署到 AWS 时工作正常,但是当我尝试使用测试工具在本地运行它时,出现此错误。 我正在使用 .NET Core 2.1 和测试工具 0.9.2。

System.IO.FileLoadException:无法加载文件或程序集“Google.Apis.Auth,版本=1.35.1.0,文化=中性,PublicKeyToken=4b01fa6e34db77ab”。 操作在当前状态下是不合法的。

我遇到了这个问题,相信我可能已经找到了“当前状态下的操作不合法”的原因。 请原谅下面的回复中的不良格式。

Tools\LambdaTestTool\Amazon.Lambda.TestTool\Runtime\LambdaAssemblyResolver.cs OnResolving Line 79
更具体地说,第 93 行:

return this.loadContext.LoadFromAssemblyPath(assemblies[0]);

这里的问题是,如果程序集包含多个运行时,它只会选择列表中的第一个。 在某些情况下,这是一个与 windows 机器不兼容的 unix 运行时,在我的情况下,它是我用于开发的操作系统。

这在部署时不会导致问题,因为发布项目会正确呈现依赖项。

例如,在编译项目进行调试时,会生成一个名为“[projectName].deps.json”的文件。
在我的这个文件中,我认为这是我引用的库的第一个条目:

"runtimeTargets": {
    "runtimes/unix/lib/netstandard1.6/Microsoft.Management.Infrastructure.Native.dll": {
    "rid": "unix",
    "assetType": "runtime",
    "assemblyVersion": "1.0.0.0",
    "fileVersion": "1.0.0.0"
},

为了验证我的怀疑,我运行了该项目,并在 Visual Studio 中打开了 debug->windows->modules 并且可以看到正在加载的程序集实际上是不正确的。 上面提到的代码只采用列表中的第一个依赖项,这在 Windows 平台上不起作用。

根据我的需要,我能够将 LambdaAssemblyResolver.cs OnResolving 起始行 78 修改为以下内容:

if (library != null){
        var deps = library.RuntimeAssemblyGroups.Distinct().Count() > 1
        ? library.RuntimeAssemblyGroups.Where(x => x.Runtime.StartsWith("win") && x.Runtime.Contains("x64")).SelectMany(g => g.AssetPaths)
        : library.RuntimeAssemblyGroups.SelectMany(g => g.AssetPaths);
        var wrapper = new CompilationLibrary(
                library.Type,
                library.Name,
                library.Version,
                library.Hash,
                deps,
                library.Dependencies,
                library.Serviceable);
        var assemblies = new List<string>();
        this.assemblyResolver.TryResolveAssemblyPaths(wrapper, assemblies);
        if (assemblies.Count > 0)
        {
            return this.loadContext.LoadFromAssemblyPath(assemblies.FirstOrDefault(x => !x.EndsWith(".Native.dll")));
        }
}

我添加了一个过滤器以仅提取为 win 64 及更高版本构建的运行时版本,排除本机二进制文件。

我没有将此作为 PR 提交,因为它只是“对我来说足够好”和我的具体情况,但类似的东西与操作系统和平台检测相结合将允许正确的程序集加载。

不确定这是否应该升级为功能请求或错误。

另外,如果我可以为这个项目做任何贡献,请告诉我。

有类似的问题。

我们正在尝试添加 Swagger: <PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />

它适用于 API Gateway 后面的已部署 asp.net 应用程序。

但是,在测试工具中,它会引发此异常。

很容易复现,标准的无服务器项目模板,添加上面的程序集,分别在 ConfigureServices 和 Configure 方法中添加services.AddSwaggerGen()app.UseSwagger();行。

使用 Mock Lambda 工具启动应用程序。 使用工具中的 API Gateway 模板发出任何请求。 它将抛出 FileNotFoundException

我有同样的问题

System.IO.FileNotFoundException: Could not load file or assembly 'XYZ, Version=1.0.0.32, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
   at SomeClass.Function..ctor()

其中 XYZ 是 .NET Standard 2.0 lib,Lambda 项目是 Core 2.1

同样的问题

System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621)
   at Namespace.Function..ctor()

您好,我也遇到了同样的问题,请问有什么解决办法吗?

今天与 System.Data.SqlClient.dll 相同的问题

只是对此感到好奇..但我运行 ProcMon 并观察了路径 System.Data.SqlClient.dll - (我在这种情况下遇到问题的文件)我注意到了两次,当 dotnet-lambda-test-tool -2.1.exe 正在尝试对 System.Data.SqlClient.dll 执行 CreateFileMapping,它会得到 FILE LOCKED WITH ONLY READERS 的结果。 经过进一步研究表明,它可能会导致“无法加载文件或程序集”错误。 我认为到那时以管理员身份重新启动 Visual Studio 2019,我可以让该错误消失,但没有这样的运气。 我怀疑其他遇到此问题的人也会在他们尝试调试的 Lambda 程序集中发现此问题。 我希望这可以帮助别人。 我仍在寻找解决方法。
FileLocked

好的,好的,好的.. 对我来说,这个问题是因为我不得不将 System.Data.SqlClient Nuget 包的版本降低到 4.5.1。 出于某种原因,任何更高的东西都会产生该线程所涉及的“无法加载文件或程序集”错误。 使用 Lambda 调试工具进行本地调试时,4.6 版及更高版本给了我该错误。

想提供状态更新。 我目前正在为即将推出的 .NET Core 3.1 Lambda 运行时开发此工具的 .NET Core 3.1 版本。 可以在mock-testtool-31中跟踪其工作。

在这个版本中,我使用 .NET Core 3.0 中添加的AssemblyDependencyResolver将 Lambda 函数加载到单独的 AssemblyLoadContext 中。 如果使用不同版本的程序集的 Lambda 函数然后由测试工具加载,这将有助于解决这些问题。

我们如何测试 3.1?

我的超级简单模板项目遇到了同样的问题,
System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=3.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621) at AWSLambda1.Functions.MyFunction..ctor()
还有Microsfot.Extensions.Configuration.Abstractions (最新的 3.1.3)

阅读所有评论后,我使用与你们中的一些人相同的解决方案。 我不得不将我的包和他们引用的包降级到较低版本。 在这种情况下,我使用的是 2.1。

这就是我现在拥有的,所以我的 Mock 工具可以工作。
image

只是为了提醒一些关于这个问题的事实。

  • 项目编译没有错误
  • 测试项目运行成功
  • 执行使用 dll 的代码时,模拟工具不起作用。

这是在我的情况下导致错误的行。
public MyFunction() : this(StartUp.Container.BuildServiceProvider()) {}
这是我的Startup.cs

using AWSLambda1.Config;
using AWSLambda1.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace AWSLambda1
{
    public class StartUp
    {
        public static IServiceCollection Container => ConfigureServices(LambdaConfiguration.Configuration);

        private static IServiceCollection ConfigureServices(IConfigurationRoot root)
        {
            var services = new ServiceCollection();

            var a = root.GetSection("MySection");
            services.Configure<EnvMySection>(options =>
                root.GetSection("MySection").Bind(options));

            var b = new MyFunctionEnvironment() { Something = LambdaConfiguration.Configuration["Hello"] ?? "" };
            services.AddSingleton(b);
            services.AddTransient<IMyService, MyService>();
            return services;
        }
    }
}

今天为 .NET Core 2.1 和 .NET Core 3.1 发布了 0.10.0 版,现在将 Lambda 代码加载到单独的 AssemblyLoadContext 中。 我相信这将解决这里报告的许多问题。 我将关闭这个问题,因为它很旧,我相信有几个单独的问题。 使用新版本后如果还有问题请单独开一个issue,方便追踪。

谢谢@normj ,恭喜,我会测试

@normj
嘿。 6天前我有同样的问题。 我试图涵盖我在此线程的最后一篇文章中获得的所有信息。 在我们得到证据之前,我认为这个问题还没有解决。

你用 3.1 测试过吗?

@Edulopez您是否尝试过昨天发布的最新版本? 如果问题仍然存在,请在您的存储库中创建一个单独的问题。 我只是觉得这个线程变得笨拙,我怀疑许多报告的问题将在新版本中得到修复。

此页面是否有帮助?
0 / 5 - 0 等级