从 dotnet 发布输出文件夹运行应用程序时,无法加载文件或程序集 Newtonsoft.Json [英] Could not load file or assembly Newtonsoft.Json when running app from the dotnet publish output folder

查看:20
本文介绍了从 dotnet 发布输出文件夹运行应用程序时,无法加载文件或程序集 Newtonsoft.Json的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现 Newtonsoft.Json 库抛出一个问题

System.IO.FileNotFoundException:无法加载文件或程序集Newtonsoft.Json,版本=13.0.0.0,Culture=neutral,PublicKeyToken=30ad4fe6b2a6aeed".该系统找不到指定的文件

当作为 Docker 容器运行应用程序时,我想知道为什么会发生这种情况以及为什么依赖项管理工作不顺利.

我使用 .NET 5.

我有一个库 MyLibrary.A,它明确使用 Newtonsoft.Json 13.0.1 来序列化和反序列化 json.

我有一个不同的库 MyLibrary.B,它封装了一个 MassTransit.AmazonSQS 库.这个 MassTransit 库也使用 Newtonsoft.Json,但可能是不同的版本.如果我没有做任何明确的事情,似乎 MassTransit 依赖项显示了 Newtonsoft.Json 11.0.2.如果在 MyLibrary.B 我明确添加了 Newtonsoft.Json 13.0.1,即使我没有明确使用它,那么 MassTransit 似乎很高兴使用这个最新的 <代码>Newtonsoft.Json 13.0.1

现在,我有一个使用 MyLibrary.AMyLibrary.B 的网络应用程序 MyApp.它在本地运行良好,但我使用 CI/CD 服务器生成 Docker 映像.

现在我将这个 Docker 映像作为本地容器​​(作为 Docker Compose)启动,但出现错误

未处理的异常.System.IO.FileNotFoundException:无法加载文件或程序集Newtonsoft.Json,版本=13.0.0.0,Culture=neutral,PublicKeyToken=30ad4fe6b2a6aeed".该系统找不到指定的文件.

它抱怨一个甚至不存在的版本.没有 13.0.0.0,这个库好像从 12.0.3 到 13.0.1.

我现在正在检查我的所有库,并确保它们都明确使用 Newtonsoft.Json 13.0.1.当我检测到其中一些使用依赖于 Newtonsoft.Json 的第三方时,我明确添加了完全相同的版本,以便我可以随处获得 13.0.1版本.


更新 1:我的解决方法无效.我不知道还能尝试什么.

我什至已经将 Newtonsoft.Json 13.0.1 明确添加到我的 web 应用程序中,所以我希望至少在运行时它可用.

此外,如果我在本地将我的网络作为标准 Kestrel AspNetCore 应用程序 (.NET 5) 运行,它会正确启动.到底是怎么回事?为什么我的 docker 容器抱怨 Newtonsoft.Json 13.0.0.0 找不到?

这些是尝试作为 Docker 容器运行时的痕迹

docker run -p 8080:80 >-e ASPNETCORE_ENVIRONMENT=生产>registry.gitlab.com/sample/foo-integration-service:latest无法在本地找到图像registry.gitlab.com/sample/foo-integration-service:latest"最新:从示例/foo-integration-service 中提取07aded7c29c6:拉取完成97aff7269a5a:拉动完成633b89d569a5:拉动完成bd0e639a2ac9:拉取完成a9a5571a369e:拉取完成9569d825ee3a:拉动完成摘要:sha256:5499b40392512f1731890ccf1ee13507769b733ee2f30c95d281f0550f7a892e状态:为 registry.gitlab.com/sample/foo-integration-service:latest 下载了较新的镜像未处理的异常.System.IO.FileNotFoundException:无法加载文件或程序集Newtonsoft.Json,版本=13.0.0.0,Culture=neutral,PublicKeyToken=30ad4fe6b2a6aeed".该系统找不到指定的文件.文件名:'Newtonsoft.Json,版本=13.0.0.0,文化=中性,PublicKeyToken=30ad4fe6b2a6aeed'在 System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)在 System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument 参数)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite TransientCallSite, RuntimeResolverContext context)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument 参数)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument 参数)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite TransientCallSite, RuntimeResolverContext context)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument 参数)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument 参数)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite TransientCallSite, RuntimeResolverContext context)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument 参数)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument 参数)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument 参数)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, RuntimeResolverContext context)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument 参数)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument 参数)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope 范围)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)在 Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken 取消令牌)在 Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost 主机,CancellationToken 令牌)在 Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost 主机,CancellationToken 令牌)在 Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost 主机)在/builds/sample/foo-integration-service/src/foo.ItgService/Program.cs:line 10 中的 foo.ItgService.Program.Main(String[] args)


更新 2:我决定在我的库中的任何地方匹配 MassTransit 依赖项 Newtonsoft.Json 11.0.2.问题仍然存在.错误现在是

未处理的异常.System.IO.FileNotFoundException:无法加载文件或程序集Newtonsoft.Json,版本=11.0.0.0,Culture=neutral,PublicKeyToken=30ad4fe6b2a6aeed".该系统找不到指定的文件.

我不明白.我对 Newtonsoft.Json 的所有依赖项现在都是 11.0.2 并且它仍然抱怨.我会在 Web 应用程序主程序集中明确添加这个版本(即使我并不直接需要它),看看它是否仍然抱怨它.


更新 3:在将 Newtonsoft.Json 11.0.2 添加到我的所有库后以及在我的 Web 应用程序程序集中添加完全相同的依赖项作为依赖项后仍然存在同样的问题.

根据 Chris 的评论,我现在有一个 .dockerignore.

bin/目标/

我构建镜像的方式是,使用 GitLab,使用标准的 dotnet builddotnet publish,然后将发布文件夹的所有内容复制到 Docker 镜像中,例如这个

来自 mcr.microsoft.com/dotnet/aspnet:5.0复制发布/.曝光 80入口点 [dotnet"、MyCompany.ItgService.dll"]

更具体地说,我使用 Kaniko,这是我的 .gitlab-ci.yml

图像:mcr.microsoft.com/dotnet/sdk:5.0变量:GIT_DEPTH:1000PUBLISH_OUTPUT_DIR:发布ENTRYPOINT_DLL:ReplaceMe.dllCLUSTER_NAME:替换我SERVICE_NAME:替换我阶段:- 建造- 测试- 发布- 送货建造:阶段:构建脚本:- dotnet restore --no-cache --force- dotnet build --configuration Release --no-restore文物:路径:- 测试expire_in: 8 小时规则:- 如果:$CI_COMMIT_TAG什么时候:从不- 什么时候:总是测试:阶段:测试服务:- 名称:localstack/localstack:0.12.17.5别名:localstack变量:# 带有 SNS 和 SQS 的本地堆栈AWS_DEFAULT_REGION:us-east-1"EDGE_PORT:4566"服务:sns,sqs"before_script:- 回合=10;而 [ $rounds -gt 0 ];做curl http://localstack:4566 &&回声确定 &&打破 ||回声失败回合=$回合 - 1;睡5;完毕;脚本: dotnet test --blame --configuration 发布规则:- 如果:$CI_COMMIT_TAG什么时候:从不- 存在:- test/**/*Tests.csproj发布:阶段:发布before_script:- 导出 PATH=$PATH:/root/.dotnet/tools- dotnet 工具安装 --global GitVersion.Tool --version 5.7.0- dotnet gitversion- SEMVER=$(dotnet gitversion -showvariable semver)- mkdir 版本- 回声${SEMVER}">./版本/服务器- APP_VERSION=$(cat ./version/semver)脚本:- dotnet 发布 -c 发布 -o $PUBLISH_OUTPUT_DIR -p:Version=$APP_VERSION文物:路径:- $PUBLISH_OUTPUT_DIR/- 版本/expire_in: 8 小时规则:- 如果:$CI_COMMIT_TAG什么时候:从不- 什么时候:总是容器注册表:阶段:交付图片:名称:gcr.io/kaniko-project/executor:debug入口点:["]before_script:- IMAGE_TAG=$(cat ./version/semver)- 回声bin/">$CI_PROJECT_DIR/.dockerignore- 回声obj/">$CI_PROJECT_DIR/.dockerignore- 回声来自 mcr.microsoft.com/dotnet/aspnet:5.0";>$CI_PROJECT_DIR/Dockerfile- 回声COPY $PUBLISH_OUTPUT_DIR/".>>$CI_PROJECT_DIR/Dockerfile- 回声EXPOSE 80">>$CI_PROJECT_DIR/Dockerfile- echo "ENTRYPOINT ["dotnet", "$ENTRYPOINT_DLL"]";>>$CI_PROJECT_DIR/Dockerfile- cat $CI_PROJECT_DIR/Dockerfile- echo "{"auths":{"$CI_REGISTRY":{"username":"$CI_REGISTRY_USER","password":"$CI_REGISTRY_PASSWORD"}}}">/kaniko/.docker/config.json- 猫/kaniko/.docker/config.json脚本:-/kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:latest --destination $CI_REGISTRY_IMAGE:$IMAGE_TAG规则:- 如果:$CI_COMMIT_TAG什么时候:从不- 什么时候:总是

我不知道 dotnet publish 是否对 docker 造成了一些问题,或者我的过程中是否存在一些缺陷(它适用于所有其他服务).可能是什么问题?

我可以在 dotnet publish 生成的文件中看到 Newtonsoft.Json.dll 以及 MassTransit.AmazonSqsTransport 和所有其他据称是被正确复制到 Docker 镜像.

另外,如果我打开 .deps.json 我可以看到所有对 Newtonsoft.Json 的引用都是 11.0.2,所以没有版本冲突了(我想!).

我没有想法了.


更新 4我刚刚清除了所有本地 nuget 包(使用 Ubuntu)

dotnet nuget locals all --clear清除 NuGet HTTP 缓存:/home/diegosasw/.local/share/NuGet/v3-cache清除 NuGet 全局包文件夹:/home/diegosasw/.nuget/packages/清除 NuGet 临时缓存:/tmp/NuGetScratch清除 NuGet 插件缓存:/home/diegosasw/.local/share/NuGet/plugins-cache本地资源清理完毕.

有趣的是,当我在我的项目之后恢复依赖项时

dotnet 还原

我可以在 /home/diegosasw/.nuget/packages/newtonsoft.json 看到有版本 11.0.29.0.1

所以我猜在某个地方有一个子依赖正在使用 Newtonsoft 9.0.1,即使我的 *.deps 中没有 Newtonsoft.Json 9.0.1 的痕迹.我的 dotnet publish 生成的 json ,我想知道这是否与我的问题有关,也许是因为那是正在加载的程序集并且 11 正在被忽略了?


更新 5我刚刚看到一些测试项目正在使用 Newtonsoft.Json 9.0.1,因为我可以在 coverlet.collector.deps.json 下的 code>coverlet.core 1.0.0Microsoft.Extensions.DependencyModel 2.1.0

我想这不是我问题的原因.

此外,我已经通过 docker export $(docker ps -lq) -o foo.tar 验证容器具有 Newtonsoft.Json.dll.

我想了解为什么会发生这种情况,并了解如何更好地解决此类问题.


更新 6(10 月 4 日)

我不认为问题出在 Docker 上.我认为问题可能出在 dotnet publish 或我遗漏或做错的事情上.

我已将 Docker 留在外面,因为我没有发现那里有任何问题.我试着简单地做一个

dotnet publish -c Release -o publish

并在其中执行应用程序使用 dotnet MyCompany.ItgService.dll 发布文件夹以重现异常.

但在发布之前,当我使用

运行应用程序时

dotnet run -c Release --project src/Rubiko.ItgService

我不明白这个例外.

参见 https://github.com/dotnet/sdk/issues/21716 获取完整细节、跟踪、树结构等.

总结

问题是:

  • 为什么 dotnet publish 似乎无法生成我的应用运行所需的一切?

  • 为什么它会在运行时抱怨那里的程序集?

    $ ls 发布/|grep 牛顿软件Newtonsoft.Json.Bson.dll*Newtonsoft.Json.dll*


最终更新:问题已解决.请参阅我自己的回复,其中有关如何正确解决此类问题的信息以及我如何通过确保我的测试项目(使用不同版本的库)不发布工件并覆盖所需的依赖项程序集来解决该问题的信息.

解决方案

我解开了这个谜.它与 Docker 无关.这有点与 dotnet publish 有关,但 SDK 运行良好.

正如最初怀疑的那样,该问题与版本冲突有关.当使用 dotnet publish -c Release -o publish 发布时,我可以在那里看到 Newtonsoft.Json.dll.但以下让我怀疑

ls 发布/-al |grep 牛顿软件-rwxrw-r-- 1 diegosasw 89K 2017 年 3 月 22 日 Newtonsoft.Json.Bson.dll*-rwxrw-r-- 1 diegosasw 641K 2018 年 3 月 24 日 Newtonsoft.Json.dll*

对于那个版本来说,2018 年似乎有点旧.如果.. 发布的 Newtonsoft.Json 程序集毕竟不是 11.0.2 版本怎么办?

我更新了我的所有库以匹配对 Newtonsoft 11.0.2 的 MassTransit 依赖,但我在更新 4 上的发现让我认为还有一些其他项目间接依赖于 Newtonsoft.Json 9.0.1,这就是为什么我可以看到 nuget 包在本地缓存.

如果不知何故,发布的程序集不是预期的 Newtonsoft.Json 11.0.2,而是 Newtonsoft.Json 9.0.1,则该错误在以下情况下是有意义的抱怨找不到程序集 Newtonsoft.Json 11.0.2

宾果游戏!

我在我的 Ubuntu 中安装了 exiftool 来检查 dll 和 exe 版本.

sudo apt install libimage-exiftool-perl

我运行以下

$ exiftool 发布/Newtonsoft.Json.dllExifTool 版本号:11.88文件名:Newtonsoft.Json.dll目录:发布文件大小:465 KB文件修改日期/时间:2021:07:19 19:52:18+02:00文件存取日期/时间:2021:10:04 12:53:14+02:00文件 inode 更改日期/时间:2021:10:04 12:44:39+02:00文件权限:rwxrw-r--文件类型:Win32 DLL文件类型扩展名:dllMIME 类型:应用程序/八位字节流机器类型:Intel 386 或更高版本,以及兼容机时间戳:2016:06:13 13:05:00+02:00图像文件特征:可执行、大地址感知、DLLPE 类型 : PE32链接器版本:48.0代码大小:465920初始化数据大小:2048未初始化的数据大小:0入口点:0x738b6操作系统版本:4.0图像版本:0.0子系统版本:4.0子系统:Windows 命令行文件版本号:9.0.1.19813产品版本号:9.0.1.0文件标志掩码:0x003f文件标志:(无)文件操作系统:Win32目标文件类型:动态链接库文件子类型:0语言代码:中性字符集:Unicode评论:Json.NET 是一种流行的.NET 高性能JSON 框架公司名称:牛顿软件文件描述:Json.NET .NET Standard 1.0文件版本:9.0.1.19813内部名称:Newtonsoft.Json.dll法律版权 : 版权所有 © James Newton-King 2008合法商标:原始文件名:Newtonsoft.Json.dll产品名称 : Json.NET产品版本:9.0.1汇编版本:9.0.0.0

如您所见,发布的程序集是 Newtonsoft.Json 9.0.1.一种混合的解脱侵袭了我.

我转到我的测试项目并将以下内容添加到 *.csproj

false

rm -rd 发布dotnet 发布 -c 发布 -o 发布

关键时刻

$ exiftool 发布/Newtonsoft.Json.dllExifTool 版本号:11.88文件名:Newtonsoft.Json.dll目录:发布文件大小:641 kB文件修改日期/时间:2018:03:24 18:44:14+01:00文件存取日期/时间:2021:10:04 12:44:38+02:00文件 inode 更改日期/时间:2021:10:04 12:57:29+02:00文件权限:rwxrw-r--文件类型:Win32 DLL文件类型扩展名:dllMIME 类型:应用程序/八位字节流机器类型:Intel 386 或更高版本,以及兼容机时间戳:2098:12:14 20:33:48+01:00图像文件特征:可执行、大地址感知、DLLPE 类型 : PE32链接器版本:48.0代码大小:653824初始化数据大小:2048未初始化的数据大小:0入口点:0xa16b6操作系统版本:4.0图像版本:0.0子系统版本:4.0子系统:Windows 命令行文件版本号:11.0.2.21924产品版本号:11.0.2.0文件标志掩码:0x003f文件标志:(无)文件操作系统:Win32目标文件类型:动态链接库文件子类型:0语言代码:中性字符集:Unicode评论:Json.NET 是一种流行的.NET 高性能JSON 框架公司名称:牛顿软件文件描述:Json.NET .NET Standard 2.0文件版本:11.0.2.21924内部名称:Newtonsoft.Json.dll法律版权 : 版权所有 © James Newton-King 2008合法商标:原始文件名:Newtonsoft.Json.dll产品名称 : Json.NET产品版本:11.0.2汇编版本:11.0.0.0

现在发布的程序集是预期的 11.0.2.

我确认从发布文件夹运行我的应用程序现在可以正常工作!

cd 发布dotnet MyCompany.ItgService.dll

I am finding a problem with Newtonsoft.Json library throwing a

System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. The system cannot find the file specified

when running an app as a Docker container and I'd like to know why this happens and why dependency management does not work smoothly.

I use .NET 5.

I have a library MyLibrary.A that explicitly uses Newtonsoft.Json 13.0.1 for serializing and deserializing json.

I have a different library MyLibrary.B that wraps a MassTransit.AmazonSQS library. This MassTransit library also uses Newtonsoft.Json, but probably a different version. If I don't do anything explicit, it seems the MassTransit dependency shows the Newtonsoft.Json 11.0.2. If at MyLibrary.B I explicitly add Newtonsoft.Json 13.0.1, even though I don't explicitly use it, then MassTransit seems to be happy with using this newest Newtonsoft.Json 13.0.1

Now, I have a web app MyApp that uses MyLibrary.A and MyLibrary.B. It works fine locally, but I use a CI/CD server to generate a Docker image.

Now I spin up this Docker image as a container locally (as a Docker Compose) and I get the error

Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. The system cannot find the file specified.

It complains about a version that does not even exist. There is no 13.0.0.0, This library seems to go from 12.0.3 to 13.0.1.

I am now going through all my libraries and making sure they all use Newtonsoft.Json 13.0.1 explicitly. And when I detect that some of them use some third party that relies on Newtonsoft.Json I add explicitly the very same version, so that I can get everywhere the 13.0.1 version.


UPDATE 1: My workaround didn't work. I don't know what else to try.

I have even added the Newtonsoft.Json 13.0.1 explicitly to my webapp so I was hoping that at least at runtime it has it available.

Also, if I run my web up locally as a standard kestrel AspNetCore app (.NET 5) it launches properly. What is going on? Why is my docker container complaining about Newtonsoft.Json 13.0.0.0 not being found?

These are the traces when attempting to run as a Docker container

docker run -p 8080:80 
>     -e ASPNETCORE_ENVIRONMENT=Production 
>     registry.gitlab.com/sample/foo-integration-service:latest
Unable to find image 'registry.gitlab.com/sample/foo-integration-service:latest' locally
latest: Pulling from sample/foo-integration-service
07aded7c29c6: Pull complete 
97aff7269a5a: Pull complete 
633b89d569a5: Pull complete 
bd0e639a2ac9: Pull complete 
a9a5571a369e: Pull complete 
9569d825ee3a: Pull complete 
Digest: sha256:5499b40392512f1731890ccf1ee13507769b733ee2f30c95d281f0550f7a892e
Status: Downloaded newer image for registry.gitlab.com/sample/foo-integration-service:latest
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. The system cannot find the file specified.

File name: 'Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, 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.VisitConstructor(ConstructorCallSite constructorCallSite, 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.VisitConstructor(ConstructorCallSite constructorCallSite, 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.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, 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__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at foo.ItgService.Program.Main(String[] args) in /builds/sample/foo-integration-service/src/foo.ItgService/Program.cs:line 10


UPDATE 2: I decided to match MassTransit dependency Newtonsoft.Json 11.0.2 everywhere in my libraries. The problem remains. The error is now

Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. The system cannot find the file specified.

I don't get it. All my dependencies of Newtonsoft.Json are now 11.0.2 and still it complains. I'll add this version explicitly (even though I don't directly need it) at the web app main assembly and see if it still complains about it.


UPDATE 3: Still same problem after adding Newtonsoft.Json 11.0.2 to all my libraries and after adding that very same dependency to my web app assembly as a dependency.

As per Chris' comment I have now a .dockerignore.

bin/
obj/

The way I build the image is, with GitLab, with a standard dotnet build, dotnet publish and then copying all the contents of publish folder into the Docker image like this

FROM mcr.microsoft.com/dotnet/aspnet:5.0
COPY publish/ .
EXPOSE 80
ENTRYPOINT ["dotnet", "MyCompany.ItgService.dll"]

More specific, I use Kaniko and this is my .gitlab-ci.yml

image: mcr.microsoft.com/dotnet/sdk:5.0

variables:
  GIT_DEPTH: 1000
  PUBLISH_OUTPUT_DIR: publish
  ENTRYPOINT_DLL: ReplaceMe.dll
  CLUSTER_NAME: ReplaceMe
  SERVICE_NAME: ReplaceMe

stages:
  - build
  - test
  - publish
  - delivery

build:
  stage: build
  script:
    - dotnet restore --no-cache --force
    - dotnet build --configuration Release --no-restore
  artifacts:
    paths:
    - test
    expire_in: 8 hour
  rules:
    - if: $CI_COMMIT_TAG
      when: never  
    - when: always

test:
  stage: test
  services:
    - name: localstack/localstack:0.12.17.5
      alias: localstack
  variables:
    # Localstack with SNS and SQS
    AWS_DEFAULT_REGION: "us-east-1"
    EDGE_PORT: "4566"
    SERVICES: "sns,sqs"
  before_script:
    - rounds=10;
      while [ $rounds -gt 0 ]; do
        curl http://localstack:4566 && echo OK && break || echo FAIL
        rounds=$rounds - 1;
        sleep 5;
      done;
  script: dotnet test --blame --configuration Release
  rules:
    - if: $CI_COMMIT_TAG
      when: never  
    - exists:
      - test/**/*Tests.csproj

publish:
  stage: publish
  before_script:
    - export PATH=$PATH:/root/.dotnet/tools
    - dotnet tool install --global GitVersion.Tool --version 5.7.0
    - dotnet gitversion
    - SEMVER=$(dotnet gitversion -showvariable semver)
    - mkdir version
    - echo "${SEMVER}" > ./version/semver
    - APP_VERSION=$(cat ./version/semver)
  script:
    - dotnet publish -c Release -o $PUBLISH_OUTPUT_DIR -p:Version=$APP_VERSION
  artifacts:
    paths: 
      - $PUBLISH_OUTPUT_DIR/
      - version/
    expire_in: 8 hour
  rules:
    - if: $CI_COMMIT_TAG
      when: never  
    - when: always

container_registry:
  stage: delivery
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  before_script:
    - IMAGE_TAG=$(cat ./version/semver)
    - echo "bin/" > $CI_PROJECT_DIR/.dockerignore
    - echo "obj/" > $CI_PROJECT_DIR/.dockerignore
    - echo "FROM mcr.microsoft.com/dotnet/aspnet:5.0" > $CI_PROJECT_DIR/Dockerfile
    - echo "COPY $PUBLISH_OUTPUT_DIR/ ." >> $CI_PROJECT_DIR/Dockerfile
    - echo "EXPOSE 80" >> $CI_PROJECT_DIR/Dockerfile
    - echo "ENTRYPOINT ["dotnet", "$ENTRYPOINT_DLL"]" >> $CI_PROJECT_DIR/Dockerfile
    - cat $CI_PROJECT_DIR/Dockerfile
    - echo "{"auths":{"$CI_REGISTRY":{"username":"$CI_REGISTRY_USER","password":"$CI_REGISTRY_PASSWORD"}}}" > /kaniko/.docker/config.json
    - cat /kaniko/.docker/config.json
  script:
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:latest --destination $CI_REGISTRY_IMAGE:$IMAGE_TAG
  rules:
    - if: $CI_COMMIT_TAG
      when: never
    - when: always

I don't know if the dotnet publish is messing something up for docker or whether there is some flaw in my process (it works fine for all other services). What might be the problem?

I can see Newtonsoft.Json.dll among the files produced by dotnet publish along with MassTransit.AmazonSqsTransport and all others that are supposedly being copied properly to the Docker image.

Also, If I open the .deps.json I can see all references to Newtonsoft.Json are 11.0.2, so no version conflict anymore (I think!).

I'm out of ideas.


UPDATE 4 I've just cleared all my local nuget packages (using Ubuntu)

dotnet nuget locals all --clear
Clearing NuGet HTTP cache: /home/diegosasw/.local/share/NuGet/v3-cache
Clearing NuGet global packages folder: /home/diegosasw/.nuget/packages/
Clearing NuGet Temp cache: /tmp/NuGetScratch
Clearing NuGet plugins cache: /home/diegosasw/.local/share/NuGet/plugins-cache
Local resources cleared.

An interesting thing is that when I restore dependencies after that on my project

dotnet restore

I can see at /home/diegosasw/.nuget/packages/newtonsoft.json that there are versions 11.0.2 and 9.0.1

So I guess somewhere somehow a sub-dependency is using Newtonsoft 9.0.1, even though there is no trace of a Newtonsoft.Json 9.0.1 in my the *.deps.json that my dotnet publish produces, and I'm wondering whether this is related to my problem, maybe because that's the assembly being loaded and the 11 is being ignored?


UPDATE 5 I've just seen that the Newtonsoft.Json 9.0.1 is being used by some test project, because I can trace it at coverlet.collector.deps.json under coverlet.core 1.0.0 and the Microsoft.Extensions.DependencyModel 2.1.0

I guess it's not the cause of my problem then.

Also I've verified with docker export $(docker ps -lq) -o foo.tar that the container has the Newtonsoft.Json.dll.

I would like to understand why is this happening and learn how to better troubleshoot these kind of things.


UPDATE 6 (4 Oct)

I don't think the problem is with Docker. I think the problem is likely with dotnet publish or something I'm missing or doing wrong.

I have left Docker outside since I didn't see anything wrong there. I tried to simply do a

dotnet publish -c Release -o publish

and execute the app in that publish folder with dotnet MyCompany.ItgService.dll to reproduce the exception.

But before publishing, when I run the application with a

dotnet run -c Release --project src/Rubiko.ItgService

I don't get that exception.

See https://github.com/dotnet/sdk/issues/21716 for full details, traces, tree structure, etc.

Summary

The questions are:

  • Why dotnet publish does not seem to produce everything my app needs to run?

  • Why does it complain at runtime about an assembly that is there?

    $ ls publish/ | grep Newtonsoft
    Newtonsoft.Json.Bson.dll*
    Newtonsoft.Json.dll*
    


FINAL UPDATE: Problem solved. See my own response where info on how to properly troubleshoot these kind of issues and how I solved it by ensuring my test projects (that use different version of the library) don't publish artifacts and overwrite the desired dependency assembly.

解决方案

I solved the mystery. It had nothing to do with Docker. It kind of had something to do with dotnet publish but the SDK works well.

The problem was, as initially suspected, with a version conflict. When publishing with dotnet publish -c Release -o publish I could see the Newtonsoft.Json.dll there. But the following made me suspicious

ls publish/ -al | grep Newtonsoft
-rwxrw-r-- 1 diegosasw  89K mar 22  2017 Newtonsoft.Json.Bson.dll*
-rwxrw-r-- 1 diegosasw 641K mar 24  2018 Newtonsoft.Json.dll*

2018 seems a bit old for that version. What if.. that Newtonsoft.Json assembly being published wasn't the version 11.0.2 after all?

I updated all my libraries to match MassTransit dependency on Newtonsoft 11.0.2 but my findings on Update 4 made me think there was some other project depending indirectly on Newtonsoft.Json 9.0.1, and that's why I could see that nuget package being cached locally.

If, somehow, the assembly being published is not the expected Newtonsoft.Json 11.0.2 but the Newtonsoft.Json 9.0.1, the error would make sense when complaining about not finding the assembly Newtonsoft.Json 11.0.2

Bingo!

I installed exiftool in my Ubuntu to check dll and exe versions.

sudo apt install libimage-exiftool-perl

I run the following

$ exiftool publish/Newtonsoft.Json.dll
ExifTool Version Number         : 11.88
File Name                       : Newtonsoft.Json.dll
Directory                       : publish
File Size                       : 465 kB
File Modification Date/Time     : 2021:07:19 19:52:18+02:00
File Access Date/Time           : 2021:10:04 12:53:14+02:00
File Inode Change Date/Time     : 2021:10:04 12:44:39+02:00
File Permissions                : rwxrw-r--
File Type                       : Win32 DLL
File Type Extension             : dll
MIME Type                       : application/octet-stream
Machine Type                    : Intel 386 or later, and compatibles
Time Stamp                      : 2016:06:13 13:05:00+02:00
Image File Characteristics      : Executable, Large address aware, DLL
PE Type                         : PE32
Linker Version                  : 48.0
Code Size                       : 465920
Initialized Data Size           : 2048
Uninitialized Data Size         : 0
Entry Point                     : 0x738b6
OS Version                      : 4.0
Image Version                   : 0.0
Subsystem Version               : 4.0
Subsystem                       : Windows command line
File Version Number             : 9.0.1.19813
Product Version Number          : 9.0.1.0
File Flags Mask                 : 0x003f
File Flags                      : (none)
File OS                         : Win32
Object File Type                : Dynamic link library
File Subtype                    : 0
Language Code                   : Neutral
Character Set                   : Unicode
Comments                        : Json.NET is a popular high-performance JSON framework for .NET
Company Name                    : Newtonsoft
File Description                : Json.NET .NET Standard 1.0
File Version                    : 9.0.1.19813
Internal Name                   : Newtonsoft.Json.dll
Legal Copyright                 : Copyright © James Newton-King 2008
Legal Trademarks                : 
Original File Name              : Newtonsoft.Json.dll
Product Name                    : Json.NET
Product Version                 : 9.0.1
Assembly Version                : 9.0.0.0

and as you can see, the published assembly is Newtonsoft.Json 9.0.1. A mix of relief invades me.

I went to my test projects and added the following to the *.csproj

<IsPublishable>false</IsPublishable>

and

rm -rd publish
dotnet publish -c Release -o publish

Moment of truth

$ exiftool publish/Newtonsoft.Json.dll
ExifTool Version Number         : 11.88
File Name                       : Newtonsoft.Json.dll
Directory                       : publish
File Size                       : 641 kB
File Modification Date/Time     : 2018:03:24 18:44:14+01:00
File Access Date/Time           : 2021:10:04 12:44:38+02:00
File Inode Change Date/Time     : 2021:10:04 12:57:29+02:00
File Permissions                : rwxrw-r--
File Type                       : Win32 DLL
File Type Extension             : dll
MIME Type                       : application/octet-stream
Machine Type                    : Intel 386 or later, and compatibles
Time Stamp                      : 2098:12:14 20:33:48+01:00
Image File Characteristics      : Executable, Large address aware, DLL
PE Type                         : PE32
Linker Version                  : 48.0
Code Size                       : 653824
Initialized Data Size           : 2048
Uninitialized Data Size         : 0
Entry Point                     : 0xa16b6
OS Version                      : 4.0
Image Version                   : 0.0
Subsystem Version               : 4.0
Subsystem                       : Windows command line
File Version Number             : 11.0.2.21924
Product Version Number          : 11.0.2.0
File Flags Mask                 : 0x003f
File Flags                      : (none)
File OS                         : Win32
Object File Type                : Dynamic link library
File Subtype                    : 0
Language Code                   : Neutral
Character Set                   : Unicode
Comments                        : Json.NET is a popular high-performance JSON framework for .NET
Company Name                    : Newtonsoft
File Description                : Json.NET .NET Standard 2.0
File Version                    : 11.0.2.21924
Internal Name                   : Newtonsoft.Json.dll
Legal Copyright                 : Copyright © James Newton-King 2008
Legal Trademarks                : 
Original File Name              : Newtonsoft.Json.dll
Product Name                    : Json.NET
Product Version                 : 11.0.2
Assembly Version                : 11.0.0.0

Now the assembly published is the expected 11.0.2.

I verify that running my app from the publish folder now works fine!

cd publish
dotnet MyCompany.ItgService.dll

这篇关于从 dotnet 发布输出文件夹运行应用程序时,无法加载文件或程序集 Newtonsoft.Json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆