Aws-lambda-dotnet: Зависимость Nuget вызывает System.IO.FileNotFoundException

Созданный на 15 мар. 2019  ·  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) Создайте пустое приложение Serverless 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 в качестве ссылки на проект в лямбда-решении. Он отлично строится, но как только я вызываю лямбду через инструмент тестирования, возникает та же ошибка.

Я также обнаружил ошибку в проекте libphonenumber, так как не уверен, на чьей стороне проблема:
https://github.com/twcclegg/libphonenumber-csharp/issues/95

Привет @rianjs , мы изучаем это. Я подтвердил, что это не работает в тестовом инструменте, но та же библиотека будет работать в консольном приложении, как вы указали в проблеме для другого репо. Я также убедился, что некоторые другие библиотеки работают с инструментом тестирования, так что теперь я продолжу исследовать, почему эта не работает. Дайте мне знать, если у вас есть обновления на вашем конце. Спасибо, что сообщили об этом.

Если бы код был открытым, я бы с удовольствием проработал его сам. ;П

Я предполагаю, что он отлично работает в «настоящей» лямбда-среде.

Эта проблема:

У меня похожая проблема, но с другой библиотекой. У меня есть лямбда-проект netcore2.1, который ссылается на Microsoft.EntityFrameworkCore 2.2.3 и Microsoft.EntityFrameworkCore.Sqlite 2.2.3. При работе в Visual Studio с помощью Mock Lambda Test Tool выдается следующее исключение:

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)

Я подтвердил, что эту лямбда-функцию можно развернуть и успешно запустить в реальной облачной среде AWS Lambda.

См. приложенный небольшой репродукционный проект

Источник:

Я клонировал репозиторий aws-lambda-dotnet и запустил тестовый инструмент. Я создал новый модульный тест, чтобы вызвать инструмент и войти в код. Инструмент тестирования создает исключение во время выполнения метода Amazon.Lambda.TestTool.Runtime::LambdaAssemblyResolver::OnResolving. Этот метод не может разрешить AssemblyName = Microsoft.Data.Sqlite и возвращает значение null. Этот метод вызывается последним перед тем, как LoadContext должен вызвать исключение System.IO.FileNotFoundException, если сборка не разрешена.


Решение, опубликованное в другом выпуске , работает. В этом выпуске автор просто перешел на версию 2.1.*. Если мы понизим версию до 2.1.8 для обоих эталонов ядра ef, инструмент тестирования снова начнет работать. Однако это не вариант для меня. Я пытаюсь воспользоваться новыми возможностями ef core 2.2.*. IMO, инструмент должен иметь возможность загружать сборки, которые также поддерживаются в лямбда-выражении.

Эта открытая проблема в репозитории corefx может дать намеки на основную проблему.

Я бы исследовал дальше, но у меня нет времени. Есть идеи?

AWSLambda_NetCore21-EfCore22Test.zip

Я выпустил версию 0.9.2, в которой изменен способ поиска зависимостей. С этим изменением я смог выполнить лямбда-функцию с помощью этого инструмента, который использовал libphonenumber.

Если вы используете Visual Studio и AWS Toolkit для Visual Studio, обновление до версии 0.9.2 должно произойти автоматически при следующем открытии решения при условии, что вы находитесь в сети.

Также @rianjs , код для инструмента фиктивного тестирования является открытым исходным кодом, и его можно найти в этом репозитории по адресу https://github.com/aws/aws-lambda-dotnet/tree/master/Tools/LambdaTestTool.

Привет @normj ,

Спасибо за помощь. Я обновил инструмент до 0.9.2. Я все еще получаю исключение System.IO.FileNotFoundException. Можете ли вы воспроизвести мой образец проекта, указанный выше ?

На данный момент я могу обойти это, запустив свои лямбда-функции для локальной разработки через консольное приложение.

Хм, это все еще не работает для меня.

Мой предыдущий комментарий, который я отредактировал, был неправильным. Последней проблемой был просто PEBKAC. Сборка LibPhoneNumber была найдена просто отлично.

Я столкнулся с этой проблемой в 0.9.2 с пакетом nuget, на который ссылается другой проект, от которого зависит мой лямбда-проект.

У меня такая же проблема в 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 для развертывания в лямбда и 2.1 для локального запуска.

@IdresAhmed @AngelVenchev Я открыл этот запрос функции, который решит проблему использования разных версий Microsoft.Extensions.*, а затем был загружен веб-приложением ASP.NET Core инструмента тестирования.

У меня такая же проблема с зависимостью 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]);

Проблема здесь в том, что если сборка содержит несколько сред выполнения, она выберет только первую в списке. В некоторых случаях это среда выполнения unix, несовместимая с машиной Windows, которая в моем случае является операционной системой, которую я использую для разработки.

Это не вызовет проблем при развертывании, поскольку при публикации проекта зависимости отображаются правильно.

Например, когда проект компилируется для отладки, создается файл с именем «[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-> и увидел, что загружаемая сборка на самом деле неверна. Упомянутый выше код принимал только первую зависимость в списке, которая не будет работать на платформе Windows.

Для своих нужд я смог изменить начальную строку 78 LambdaAssemblyResolver.cs OnResolving на следующее:

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" />

Он работает в развернутом приложении asp.net, которое находится за шлюзом API.

Однако в тестовом инструменте выдается это исключение.

Это очень легко воспроизвести, стандартный шаблон проекта Serverless, добавьте приведенную выше сборку, добавьте строки services.AddSwaggerGen() и app.UseSwagger(); в методы ConfigureServices и Configure соответственно.

Запустите приложение с помощью инструмента Mock Lambda. Сделайте любой запрос, используя шаблон шлюза API из инструмента. Это вызовет исключение 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, а проект 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 пытается выполнить CreateFileMapping для System.Data.SqlClient.dll, он получает результат FILE LOCKED WITH ONLY READERS. Что после дальнейших исследований показывает, что это может вызвать ошибку «Не удалось загрузить файл или сборку». Я думал, что к тому времени, перезапустив Visual Studio 2019 в качестве администратора, я смогу избавиться от этой ошибки, но не тут-то было. Я подозреваю, что другие, имеющие эту проблему, также обнаружат эту проблему со сборками в Lambda, которые они также пытаются отлаживать. Я надеюсь, что это поможет кому-то. Я все еще ищу обходной путь.
FileLocked

Хорошо, хорошо, хорошо. Для меня эта проблема была связана с тем, что мне пришлось понизить версию пакета System.Data.SqlClient Nuget до 4.5.1. По какой-то причине все, что выше, вызывает ошибку «Не удалось загрузить файл или сборку», о которой идет речь в этом потоке. Версия 4.6 и выше выдает эту ошибку при локальной отладке с помощью инструмента отладки Lambda.

Хотел обновить статус. В настоящее время я работаю над версией этого инструмента для .NET Core 3.1 для будущей среды выполнения .NET Core 3.1 Lambda. Работу над этим можно проследить в mock-testtool-31 .

В этой версии я использую AssemblyDependencyResolver , который был добавлен в .NET Core 3.0 для загрузки функции 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

Просто напомню некоторые факты по этому вопросу.

  • Проект компилируется без ошибок
  • Тестовый проект выполняется успешно
  • Инструмент Mock не работает, когда выполняется код, использующий 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;
        }
    }
}

Сегодня была выпущена версия 0.10.0 для .NET Core 2.1 и .NET Core 3.1, которая теперь загружает лямбда-код в отдельный AssemblyLoadContext. Я считаю, что это исправит многие проблемы, о которых здесь сообщалось. Я собираюсь закрыть этот вопрос, так как он старый, и я считаю, что есть несколько отдельных вопросов. После использования новой версии, если проблема все еще существует, откройте отдельную проблему, чтобы ее было легче отслеживать.

Спасибо @normj и поздравляю, буду тестить

@нормдж
Привет. У меня были такие же проблемы 6 дней назад. Я попытался охватить всю информацию, которая у меня была, в последнем посте этой темы. Я не думаю, что эта проблема решена, пока мы не получим доказательства.

Вы тестировали с 3.1?

@Edulopez Вы пробовали последнюю версию, которая вышла вчера? Если проблема все еще существует, создайте отдельную проблему с вашим репозиторием. Я просто почувствовал, что эта ветка стала слишком громоздкой, и я подозреваю, что многие проблемы, о которых сообщалось, будут исправлены в новой версии.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги