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
アプリを Docker コンテナーとして実行しているときに、なぜこれが発生するのか、依存関係の管理がスムーズに機能しないのかを知りたいです。
私は.NET 5を使用しています。
json のシリアライズとデシリアライズにMyLibrary.A
明示的に使用するライブラリがあります。Newtonsoft.Json 13.0.1
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
を使用する Web アプリができました。ローカルでは問題なく動作しますが、CI/CD サーバーを使用して Docker イメージを生成します。MyLibrary.A
MyLibrary.B
ここで、この 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.
存在すらしないバージョンについて文句を言います。13.0.0.0 はありません。このライブラリは 12.0.3 から 13.0.1 になるようです。
現在、すべてのライブラリを調べて、それらがすべてNewtonsoft.Json 13.0.1
明示的に使用されていることを確認しています。そして、それらの一部が依存するサードパーティを使用していることを検出した場合Newtonsoft.Json
、まったく同じバージョンを明示的に追加して、どこでも13.0.1
バージョンを取得できるようにします。
更新 1: 私の回避策はうまくいきませんでした。他に何を試すべきかわかりません。
明示的に webapp に追加したNewtonsoft.Json 13.0.1
ので、少なくとも実行時にそれが利用できることを望んでいました。
また、Web を標準の kestrel AspNetCore アプリ (.NET 5) としてローカルで実行すると、適切に起動します。何が起こっている?Newtonsoft.Json 13.0.0.0
docker コンテナーが見つからないという不平を言っているのはなぜですか?
これらは、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
更新 2 : ライブラリのどこでも MassTransit の依存関係を一致させることにしましたNewtonsoft.Json 11.0.2
。
問題は残ります。
エラーは現在
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.
理解できません。私の依存関係はすべてNewtonsoft.Json
今11.0.2
でも不平を言っています。このバージョンを Web アプリのメイン アセンブリに明示的に (直接は必要ありませんが) 追加し、それでも問題が発生するかどうかを確認します。
更新 3Newtonsoft.Json 11.0.2
:すべてのライブラリに追加した後も、同じ依存関係を Web アプリ アセンブリに依存関係として追加した後も、同じ問題が発生します。
クリスのコメントによると、私は今持ってい.dockerignore
ます。
bin/
obj/
私がイメージを構築する方法は、GitLab を使用して、標準のdotnet build
.dotnet publish
FROM mcr.microsoft.com/dotnet/aspnet:5.0
COPY publish/ .
EXPOSE 80
ENTRYPOINT ["dotnet", "MyCompany.ItgService.dll"]
より具体的には、私は 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
dotnet publish
docker で何かが台無しになっているかどうか、または私のプロセスに何らかの欠陥があるかどうかはわかりません(他のすべてのサービスでは問題なく動作します)。何が問題なのですか?
とともにNewtonsoft.Json.dll
生成されたファイルと、Docker イメージに適切にコピーされていると思われる他のすべてのファイルを見ることができます。dotnet publish
MassTransit.AmazonSqsTransport
また、 を開くと、are.deps.json
へのすべての参照が表示されるため、バージョンの競合はもうありません (と思います!)。Newtonsoft.Json
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.
興味深いのは、プロジェクトでその後依存関係を復元すると、
dotnet restore
/home/diegosasw/.nuget/packages/newtonsoft.json
バージョン11.0.2
と_9.0.1
そのため、サブ依存関係が Newtonsoft 9.0.1 を使用している可能性があると思いますが、私が生成Newtonsoft.Json 9.0.1
したものに a の痕跡がなくても、これが私の問題に関連しているかどうか疑問に思っています。ロードされ、無視されていますか?*.deps.json
dotnet publish
11
更新 5Newtonsoft.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
その発行フォルダーでアプリを実行してdotnet MyCompany.ItgService.dll
、例外を再現します。
しかし、公開する前に、アプリケーションを
dotnet run -c Release --project src/Rubiko.ItgService
私はその例外を取得しません。
詳細、トレース、ツリー構造などについては、https://github.com/dotnet/sdk/issues/21716を参照してください。
概要
質問は次のとおりです。
dotnet publish
アプリの実行に必要なものがすべて生成されないように見えるのはなぜですか?そこにあるアセンブリについて実行時に不平を言うのはなぜですか?
$ ls publish/ | grep Newtonsoft Newtonsoft.Json.Bson.dll* Newtonsoft.Json.dll*
最終更新: 問題は解決しました。この種の問題を適切にトラブルシューティングする方法と、テスト プロジェクト (異なるバージョンのライブラリを使用する) がアーティファクトを公開せず、目的の依存関係アセンブリを上書きしないようにすることで問題を解決した方法に関する情報が記載されている、私自身の応答を参照してください。