-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Research, Fess's SearchEngineClient refers LoginAssist as getComponent() #44
Comments
そもそもJava8のfortressにて、coolのときのQuick Componentの初期化タイミングが、JSON Managerの前後になってる。
この挙動自体なんで?って感じ。 Java21の場合は、さらにObjective Configの後にJSON Managerを待たずしてすべてのQuick Componentが初期化されている。
そもそも、Java8とJava21で、Rich Componentの初期化順序もちょい違う。 lastaflute_core.xmlの定義順で言うと、Java8の方が変、PrimaryCipherを追い抜いてJsonManagerが初期化されている。
|
fortressからlastaflute_core+timeManager.xmlを削除したら再現したー。 起動時のログで、lastaflute_core+timeManager.xmlの直後にcoolが読まれてるので怪しいと思って消してたら。
lastaflute_core+timeManager.xmlを消すと、coolの読み込みが後になった。
|
なんとなく予感していたんだけど、そもそもrichの方が先でしょうから、richの中でquickを参照しても順番的に参照できないんじゃないかな?と。 DIコンテナとしてはlazyに初期化されるのでは?ってところもあるけど、 たまたまrichの途中で先にquickが初期化されても動いてるので、うまく制御すれば問題ないのかもだけど... 例えば... もしくは本来は、open()でやってることは、CurtainBeforeHookでやる方が良いのではないだろうか? |
原因まとめ: fortressにて、lastaflute_core+timeManager.xmlを削除すると再現した。 +timeManagerが存在する状態だと、+timeManagerのコンポーネント初期化が早いタイミングで実行され、 fortress自体があまりオーソドックスではない状態になっていたので最初再現してなかったと言える。 これは、(試してないけど)恐らくSeasarでも同じなのかなと。 Quick Componentの初期化がRich Componentの途中に混じっても正常に動いていたので、 また、必要とされた時点でlazyに初期化していくようにできれば良いのかもだが、それも難しそう。 そもそも、Rich ComponentからQuick Componentへの参照というのが非推奨なので、 Fessで「とあるときから落ちるようになった」というのは、 追記(2024/10/21): sugayaさんより
|
Fessでの回避の提案: 言葉の前提Rich Component (rich) :: Di xmlに定義しているコンポーネント (appパッケージ以外のもの) 提案1 // 手軽に修正パターンopen()の中では、LoginAssistを使うのではなくPrimaryCipherをDIしてoneway()を呼ぶようにする。 TypicalLoginAssist@encryptPassword()と同じことをする、というイメージ。
メリット: rich から quick の参照が無くなる 提案2 // 理想的なクラス構成だけどちょい面倒パターンLoginPasswordCipherという Rich Component を新たに作成して、両方でそれを使う。 FessLoginAssistでは、encryptPassword()をオーバーライドしてLoginPasswordCipherを使う。 メリット: どちらもログイン用の暗号化処理を使うという統一ができている、LastaFluteとしては推奨の形 提案3 // もっと理想的なクラス構成だけどもっと面倒パターン(Fessでやっている処理を完全に把握しているわけではないので、この案は本当にできるかは不明) open()でやっている(一部の!?)ことを、CurtainBeforeHookに持っていく。 「DIコンテナとしてはすべて初期化が終わっている、かつ、Tomcatはまだ公開していない」というタイミング、 // FessCurtainBeforeHook.java SearchEngineClient@insertBulkData()を、 (ただ、別のコンポーネントがinsertBulkData()に依存してて処理の順番に依存があったりすると大変かも) 提案4 // 現状のままの辻褄合わせパターン何かしらのきっかけで、Quick Component の初期化タイミングが変わっちゃったので、 でもこれは推奨しない。これから提案1や2の方が良いと思われる。 |
そもそものLasta Diの挙動分析: o SingletonLaContainerFactoryにてLaContainerFactory@create()を呼び... ただ、この時点では Di xml に include されただけで、まだ初期化されるわけじゃない。 その後の順番は?最後になると思うけど。 o その後、app.xml (or test_app.xml) の読み込みが行われる。 同じくまだ初期化されているわけではない。 o もろもろ読み込んだ後で、初期化が行われる (続く: Redeiner回り) |
Redefiner, 初期化のタイミングだと思ったら、Containerの構築で組み込まれている
LaContainerDefaultProvider@create()にて、
ということで、build()の方を経由して...getBuilder()でbuild()しておるが...
このbuilderが RedefinableXmlLaContainerBuilder になる。 xmlRddefinedという名前のコンポーネントは、redefiner.xmlにて定義されているが...
redefiner.xmlは、lasta_di.xmlにて固定でincludeされているので...
必ずこのRedefinableXmlLaContainerBuilderが使われる。 |
RedefinableXmlLaContainerBuilderのParser Override:
|
とにかく、RedefinableXmlLaContainerBuilder@mergeContainers()がキーポイントっぽい。
LaContainerBuilderUtils@mergeContainer():
これは難しい... |
追いやすいようにコメントを色々と追加 |
redefinerの処理が入ることで、なぜ cooldeploy のコンポーネントたちが先に初期化されるのか? 起動ログを見る限り、結構唐突に始まるんだよね。
|
redefinerが、追加のcontainerなどで LaContainerFactory@create() を呼んでいる。 だが、LaContainerFactory@create()は本来はroot containerを読み込むためのもののはず。 それで所属のcontainerが変わって、初期化タイミングが変わってしまっているのだと思われる。 別途チケットを起票: |
// Japanese here
from DBFlute Slack:
The text was updated successfully, but these errors were encountered: