ibe*_*dev 16 json.net nuget dotnet-sdk dotnet-publish .net-5
我发现Newtonsoft.Json图书馆抛出一个问题
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
Run Code Online (Sandbox Code Playgroud)
当将应用程序作为 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
现在,我有一个MyApp使用MyLibrary.A和的网络应用程序MyLibrary.B。它在本地运行良好,但我使用 CI/CD 服务器来生成 Docker 映像。
现在,我将此 Docker 映像作为本地容器(作为 Docker Compose)启动,并收到错误
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.
Run Code Online (Sandbox Code Playgroud)
它抱怨一个甚至不存在的版本。没有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显式添加到我的网络应用程序中,因此我希望至少在运行时它可用。
另外,如果我在本地将我的网络作为标准 kestrel AspNetCore 应用程序 (.NET 5) 运行,它会正确启动。到底是怎么回事?为什么我的 docker 容器抱怨Newtonsoft.Json 13.0.0.0找不到?
这些是尝试作为 Docker 容器运行时的跟踪
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
Run Code Online (Sandbox Code Playgroud)
更新 2:我决定Newtonsoft.Json 11.0.2在我的库中随处匹配 MassTransit 依赖项。
问题依然存在。
现在的错误是
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.
Run Code Online (Sandbox Code Playgroud)
我不明白。我所有的依赖Newtonsoft.Json现在11.0.2都在抱怨。我将在网络应用程序主程序集中显式添加此版本(即使我不直接需要它),看看它是否仍然抱怨它。
更新 3:添加Newtonsoft.Json 11.0.2到我的所有库以及将相同的依赖项添加到我的 Web 应用程序程序集作为依赖项后,仍然存在同样的问题。
根据克里斯的评论,我现在有了一个.dockerignore.
bin/
obj/
Run Code Online (Sandbox Code Playgroud)
我构建图像的方式是,使用 GitLab,使用标准dotnet build,dotnet publish然后将发布文件夹的所有内容复制到 Docker 图像中,如下所示
FROM mcr.microsoft.com/dotnet/aspnet:5.0
COPY publish/ .
EXPOSE 80
ENTRYPOINT ["dotnet", "MyCompany.ItgService.dll"]
Run Code Online (Sandbox Code Playgroud)
更具体地说,我使用 Kaniko,这是我的.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
Run Code Online (Sandbox Code Playgroud)
我不知道这是否dotnet publish给 docker 带来了麻烦,或者我的流程是否存在一些缺陷(它对于所有其他服务都工作得很好)。可能是什么问题?
我可以看到由以及所有其他Newtonsoft.Json.dll文件生成的文件,这些文件应该被正确复制到 Docker 镜像中。dotnet publishMassTransit.AmazonSqsTransport
另外,如果我打开,.deps.json我可以看到对Newtonsoft.Jsonare的所有引用11.0.2,因此不再存在版本冲突(我认为!)。
我没主意了。
更新 4 我刚刚清除了所有本地 nuget 软件包(使用 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.
Run Code Online (Sandbox Code Playgroud)
有趣的是,当我在我的项目上恢复依赖关系时
dotnet restore
Run Code Online (Sandbox Code Playgroud)
我可以看到/home/diegosasw/.nuget/packages/newtonsoft.json
有版本11.0.2和9.0.1
所以我猜想在某个地方有一个子依赖项正在使用 Newtonsoft 9.0.1,即使我生成的Newtonsoft.Json 9.0.1the 中没有任何 a 的痕迹,我想知道这是否与我的问题有关,也许是因为这是程序集已加载并且被忽略?*.deps.jsondotnet publish11
更新 5
我刚刚看到Newtonsoft.Json 9.0.1一些测试项目正在使用它,因为我可以在coverlet.collector.deps.json下面跟踪coverlet.core 1.0.0它Microsoft.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
Run Code Online (Sandbox Code Playgroud)
并在该发布文件夹中执行应用程序以dotnet MyCompany.ItgService.dll重现异常。
但在发布之前,当我使用
dotnet run -c Release --project src/Rubiko.ItgService
Run Code Online (Sandbox Code Playgroud)
我不明白这个例外。
有关完整详细信息、跟踪、树结构等,请参阅https://github.com/dotnet/sdk/issues/21716 。
概括
问题是:
为什么dotnet publish我的应用程序似乎无法生成运行所需的所有内容?
为什么它在运行时抱怨存在的程序集?
$ ls publish/ | grep Newtonsoft
Newtonsoft.Json.Bson.dll*
Newtonsoft.Json.dll*
Run Code Online (Sandbox Code Playgroud)
最终更新:问题已解决。请参阅我自己的回复,其中有关如何正确解决此类问题的信息,以及如何通过确保我的测试项目(使用不同版本的库)不会发布工件并覆盖所需的依赖项程序集来解决它。
ibe*_*dev 14
我解开了这个谜团。它与 Docker 无关。这有点关系,dotnet publish但 SDK 运行良好。
正如最初怀疑的那样,问题是版本冲突。当我发布时,dotnet publish -c Release -o publish我可以看到Newtonsoft.Json.dll那里。但下面的事情却让我产生了怀疑
ls publish/ -al | grep Newtonsoft\n-rwxrw-r-- 1 diegosasw 89K mar 22 2017 Newtonsoft.Json.Bson.dll*\n-rwxrw-r-- 1 diegosasw 641K mar 24 2018 Newtonsoft.Json.dll*\nRun Code Online (Sandbox Code Playgroud)\n2018 年的版本似乎有点旧了。如果..发布的程序集根本Newtonsoft.Json不是版本怎么办?11.0.2
我更新了所有库以匹配 MassTransit 依赖项Newtonsoft 11.0.2,但我对 Update 4 的发现让我认为还有一些其他项目间接依赖于Newtonsoft.Json 9.0.1,这就是为什么我可以看到 nuget 包在本地缓存。
如果不知何故,正在发布的程序集不是预期Newtonsoft.Json 11.0.2的而是Newtonsoft.Json 9.0.1,则在抱怨找不到程序集时该错误是有意义的Newtonsoft.Json 11.0.2
答对了!
\n我exiftool在 Ubuntu 中安装来检查 dll 和 exe 版本。
sudo apt install libimage-exiftool-perl\nRun Code Online (Sandbox Code Playgroud)\n我运行以下命令
\n$ exiftool publish/Newtonsoft.Json.dll\nExifTool Version Number : 11.88\nFile Name : Newtonsoft.Json.dll\nDirectory : publish\nFile Size : 465 kB\nFile Modification Date/Time : 2021:07:19 19:52:18+02:00\nFile Access Date/Time : 2021:10:04 12:53:14+02:00\nFile Inode Change Date/Time : 2021:10:04 12:44:39+02:00\nFile Permissions : rwxrw-r--\nFile Type : Win32 DLL\nFile Type Extension : dll\nMIME Type : application/octet-stream\nMachine Type : Intel 386 or later, and compatibles\nTime Stamp : 2016:06:13 13:05:00+02:00\nImage File Characteristics : Executable, Large address aware, DLL\nPE Type : PE32\nLinker Version : 48.0\nCode Size : 465920\nInitialized Data Size : 2048\nUninitialized Data Size : 0\nEntry Point : 0x738b6\nOS Version : 4.0\nImage Version : 0.0\nSubsystem Version : 4.0\nSubsystem : Windows command line\nFile Version Number : 9.0.1.19813\nProduct Version Number : 9.0.1.0\nFile Flags Mask : 0x003f\nFile Flags : (none)\nFile OS : Win32\nObject File Type : Dynamic link library\nFile Subtype : 0\nLanguage Code : Neutral\nCharacter Set : Unicode\nComments : Json.NET is a popular high-performance JSON framework for .NET\nCompany Name : Newtonsoft\nFile Description : Json.NET .NET Standard 1.0\nFile Version : 9.0.1.19813\nInternal Name : Newtonsoft.Json.dll\nLegal Copyright : Copyright \xc2\xa9 James Newton-King 2008\nLegal Trademarks : \nOriginal File Name : Newtonsoft.Json.dll\nProduct Name : Json.NET\nProduct Version : 9.0.1\nAssembly Version : 9.0.0.0\nRun Code Online (Sandbox Code Playgroud)\n正如您所看到的,发布的程序集是Newtonsoft.Json 9.0.1. 我感到一丝解脱。
我转到我的测试项目并将以下内容添加到*.csproj
<IsPublishable>false</IsPublishable>\nRun Code Online (Sandbox Code Playgroud)\n和
\nrm -rd publish\ndotnet publish -c Release -o publish\nRun Code Online (Sandbox Code Playgroud)\n关键时刻
\n$ exiftool publish/Newtonsoft.Json.dll\nExifTool Version Number : 11.88\nFile Name : Newtonsoft.Json.dll\nDirectory : publish\nFile Size : 641 kB\nFile Modification Date/Time : 2018:03:24 18:44:14+01:00\nFile Access Date/Time : 2021:10:04 12:44:38+02:00\nFile Inode Change Date/Time : 2021:10:04 12:57:29+02:00\nFile Permissions : rwxrw-r--\nFile Type : Win32 DLL\nFile Type Extension : dll\nMIME Type : application/octet-stream\nMachine Type : Intel 386 or later, and compatibles\nTime Stamp : 2098:12:14 20:33:48+01:00\nImage File Characteristics : Executable, Large address aware, DLL\nPE Type : PE32\nLinker Version : 48.0\nCode Size : 653824\nInitialized Data Size : 2048\nUninitialized Data Size : 0\nEntry Point : 0xa16b6\nOS Version : 4.0\nImage Version : 0.0\nSubsystem Version : 4.0\nSubsystem : Windows command line\nFile Version Number : 11.0.2.21924\nProduct Version Number : 11.0.2.0\nFile Flags Mask : 0x003f\nFile Flags : (none)\nFile OS : Win32\nObject File Type : Dynamic link library\nFile Subtype : 0\nLanguage Code : Neutral\nCharacter Set : Unicode\nComments : Json.NET is a popular high-performance JSON framework for .NET\nCompany Name : Newtonsoft\nFile Description : Json.NET .NET Standard 2.0\nFile Version : 11.0.2.21924\nInternal Name : Newtonsoft.Json.dll\nLegal Copyright : Copyright \xc2\xa9 James Newton-King 2008\nLegal Trademarks : \nOriginal File Name : Newtonsoft.Json.dll\nProduct Name : Json.NET\nProduct Version : 11.0.2\nAssembly Version : 11.0.0.0\nRun Code Online (Sandbox Code Playgroud)\n现在大会的公布是预料之中的11.0.2。
我验证从发布文件夹运行我的应用程序现在工作正常!
\ncd publish\ndotnet MyCompany.ItgService.dll\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
5642 次 |
| 最近记录: |