概要
bindingRedirect の newVersion が、実際に配布されるアセンブリの版と食い違っている。
宣言した版がリポジトリのどこにも無いため、その範囲に入る要求は解決に失敗する。
#554(未使用・陳腐化した参照)で 1 件だけ見つかっていたが、
全体を洗ったら 8 件あったので、独立させる。
現状(実測)
追跡下の *.config から bindingRedirect を集め、
AssemblyName.GetAssemblyName() で得た実在するアセンブリの版と突き合わせた。
|
件数 |
bindingRedirect の総数 |
847 |
| 一致 |
832 |
| 不一致(宣言した版が存在しない) |
8 |
| 実体なし(そのアセンブリ自体がリポジトリに無い) |
7 |
不一致の 8 件
| 場所 |
アセンブリ |
宣言 |
実体 |
CS/Frameworks/Tests/TestCode/App.config |
Newtonsoft.Json |
10.0.0.0 |
13.0.0.0 |
CS/Frameworks/Tests/EncAndDecUtilCUI/App.config |
Newtonsoft.Json |
11.0.0.0 |
13.0.0.0 |
CS/Frameworks/Tests/TestBatch/SimpleBatch/app.config |
Newtonsoft.Json |
12.0.0.0 |
13.0.0.0 |
CS/Frameworks/Infrastructure/Public/Db/DamMySQL/app.config |
Google.Protobuf |
3.6.1.0 |
3.30.0.0 / 3.30.2.0 |
CS/Samples/WS_sample/WSClient_sample/WSClientWinCone_sample/app.config |
Microsoft.Owin |
4.0.0.0 |
4.2.2.0 |
CS/Samples/WS_sample/WSClient_sample/WSClientWPF_sample/app.config |
Microsoft.Owin |
4.0.0.0 |
4.2.2.0 |
VB/Samples/WS_sample/WSClient_sample/WSClientWin_sample/app.config |
Microsoft.Owin |
4.0.0.0 |
4.2.2.0 |
| 〃 |
Microsoft.Owin.Security |
3.1.0.0 |
4.2.2.0 |
Newtonsoft.Json は 10 / 11 / 12 とバラバラで、単体テストの 3 プロジェクトすべてが該当する。
Google.Protobuf の乖離が最大(3.6.1.0 → 3.30.x)。
なぜ問題か
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0"/>
これは「0.0.0.0〜12.0.0.0 の要求が来たら 12.0.0.0 を読め」という意味である。
12.0.0.0 は配布されていないので、この範囲の要求は解決に失敗する。
今は動いている。それが厄介である
実体の 13.0.0.0 を要求するコードは、範囲外なので転送されず、直接束縛される。
つまり現状の組み合わせでは表面化しない。
古い版を要求する依存が 1 つ増えた瞬間に落ちる、という形で顕在化する。
0_RunAll.ps1 -Lang Both は通る(実測)。
Samples4NetCore/ANALYSIS.md 7 節との違い
同書 7 節は同じ「バージョンのずれ」でも別の現象なので、混同しないこと。
|
net10.0(同書 7 節) |
net48(本件) |
bindingRedirect |
仕組み自体が無い |
ある |
| ずれると |
即 FileNotFoundException で起動不能 |
**黙って通る。**条件が揃うと落ちる |
| 直し方 |
サンプル側のパッケージ版を上げる |
newVersion を実体に合わせる |
net48 の方が見つけにくい。
対応(案)
① 実体に合わせる
機械的な置換で済む。8 件。
ただし bindingRedirect は NuGet の生成物である。
パッケージ操作(更新・再インストール)でまた書き換わるため、
直しても再発する。
② 検知の仕組みを持つ
#553 で入れた CompareConfig.ps1 と同じ考え方で、
ずれを検出できる状態にしておく方が本質だと考える。
今回の洗い出しはスクリプト 1 本で済んでいる。
1. リポジトリ内の *.dll から AssemblyName.GetAssemblyName() で版を集める
2. 追跡下の *.config から assemblyIdentity + bindingRedirect を集める
3. newVersion が、集めた版の集合に無いものを挙げる
リポジトリに入れるなら root/programs/CompareRedirect.ps1 あたり。
CompareConfig.ps1 と同じく合否を返す形にできる。
③ 何もしない(記録だけ)
現状は動いており、bindingRedirect は生成物である。
「再発するものを手で直す」ことの費用対効果は、確かに検討の余地がある。
影響
- 利用者への影響: 無し(現状の組み合わせでは動作が変わらない)。
ただし将来の不具合の芽であり、直せば芽は消える
- net48 / net10.0: net48 のみ(
bindingRedirect は net48 の仕組み)
- 検証:
0_RunAll.ps1 -Lang Both。
ただし通ることは「直った」証拠にならない(直す前から通る)。
確認は宣言と実体の突き合わせで行う
関連
#554(未使用・陳腐化した参照。ここで 1 件見つけ、本件へ切り出した)
#553(CS / VB の設定同期。VB の Newtonsoft.Json 3 件はそこで直した。
CS / VB のずれとして現れたためで、本件の 8 件とは別)
Samples4NetCore/ANALYSIS.md 7 節
概要
bindingRedirectのnewVersionが、実際に配布されるアセンブリの版と食い違っている。宣言した版がリポジトリのどこにも無いため、その範囲に入る要求は解決に失敗する。
#554(未使用・陳腐化した参照)で 1 件だけ見つかっていたが、全体を洗ったら 8 件あったので、独立させる。
現状(実測)
追跡下の
*.configからbindingRedirectを集め、AssemblyName.GetAssemblyName()で得た実在するアセンブリの版と突き合わせた。bindingRedirectの総数不一致の 8 件
CS/Frameworks/Tests/TestCode/App.configNewtonsoft.JsonCS/Frameworks/Tests/EncAndDecUtilCUI/App.configNewtonsoft.JsonCS/Frameworks/Tests/TestBatch/SimpleBatch/app.configNewtonsoft.JsonCS/Frameworks/Infrastructure/Public/Db/DamMySQL/app.configGoogle.ProtobufCS/Samples/WS_sample/WSClient_sample/WSClientWinCone_sample/app.configMicrosoft.OwinCS/Samples/WS_sample/WSClient_sample/WSClientWPF_sample/app.configMicrosoft.OwinVB/Samples/WS_sample/WSClient_sample/WSClientWin_sample/app.configMicrosoft.OwinMicrosoft.Owin.SecurityNewtonsoft.Jsonは 10 / 11 / 12 とバラバラで、単体テストの 3 プロジェクトすべてが該当する。Google.Protobufの乖離が最大(3.6.1.0 → 3.30.x)。なぜ問題か
これは「0.0.0.0〜12.0.0.0 の要求が来たら 12.0.0.0 を読め」という意味である。
12.0.0.0 は配布されていないので、この範囲の要求は解決に失敗する。
今は動いている。それが厄介である
実体の 13.0.0.0 を要求するコードは、範囲外なので転送されず、直接束縛される。
つまり現状の組み合わせでは表面化しない。
古い版を要求する依存が 1 つ増えた瞬間に落ちる、という形で顕在化する。
0_RunAll.ps1 -Lang Bothは通る(実測)。Samples4NetCore/ANALYSIS.md7 節との違い同書 7 節は同じ「バージョンのずれ」でも別の現象なので、混同しないこと。
bindingRedirectFileNotFoundExceptionで起動不能newVersionを実体に合わせるnet48 の方が見つけにくい。
対応(案)
① 実体に合わせる
機械的な置換で済む。8 件。
ただし
bindingRedirectは NuGet の生成物である。パッケージ操作(更新・再インストール)でまた書き換わるため、
直しても再発する。
② 検知の仕組みを持つ
#553で入れたCompareConfig.ps1と同じ考え方で、ずれを検出できる状態にしておく方が本質だと考える。
今回の洗い出しはスクリプト 1 本で済んでいる。
リポジトリに入れるなら
root/programs/CompareRedirect.ps1あたり。CompareConfig.ps1と同じく合否を返す形にできる。③ 何もしない(記録だけ)
現状は動いており、
bindingRedirectは生成物である。「再発するものを手で直す」ことの費用対効果は、確かに検討の余地がある。
影響
ただし将来の不具合の芽であり、直せば芽は消える
bindingRedirectは net48 の仕組み)0_RunAll.ps1 -Lang Both。ただし通ることは「直った」証拠にならない(直す前から通る)。
確認は宣言と実体の突き合わせで行う
関連
#554(未使用・陳腐化した参照。ここで 1 件見つけ、本件へ切り出した)#553(CS / VB の設定同期。VB のNewtonsoft.Json3 件はそこで直した。CS / VB のずれとして現れたためで、本件の 8 件とは別)
Samples4NetCore/ANALYSIS.md7 節