Skip to content

bindingRedirect の newVersion が、実在しないアセンブリの版を指している(8 件) #556

Description

@OsscJpDevInfra

概要

bindingRedirectnewVersion が、実際に配布されるアセンブリの版と食い違っている。

宣言した版がリポジトリのどこにも無いため、その範囲に入る要求は解決に失敗する。

#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 節

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions