ぷらぷらDiconでincludeするとCoolエラー

発生したバージョンは以下の通り:
(別のバージョンでも発生するかもですが試してない)

SAStruts: 1.0.4-sp9
Seasar(S2Container): 2.4.46
S2ClassBuilder: 0.0.11
 -> diconファイルの扱い(S2ClassBuilder) | Ymir
 -> S2ClassBuilder | DBFlute

例えば、jta+UserTransaction.diconを作成して、
UserTransactionをオーバーライドするとします。
そのUserTransactionが、とあるdicon(foo.dicon)の
コンポーネント(fooManager)をDI対象にしてるとします。
なので、jta+UserTransaction.diconで、
foo.diconをincludeします。

HotDeployでは全く正常に動作します。
UserTransactionの拡張も、DIされたfooManagerを
使って元気良く動きます。

しかし、CoolDeployにすると、初回画面アクセス時に、
以下の例外が発生:
[ESSR0007]externalContextはnullあるいは空であってはいけません
at ...deployer.RequestComponentDeployer.deploy(RequestComponentDeployer.java:54)
at ...impl.ComponentDefImpl.getComponent(ComponentDefImpl.java:111)
at ...config.S2ActionMapping.getAction(S2ActionMapping.java:320)
at ....action.ActionWrapper.(ActionWrapper.java:76)

ExternalContext extCtx = cd.getContainer().getRoot()
        .getExternalContext();
if (extCtx == null) { // ★ここが null
    RuntimeException re = new EmptyRuntimeException("externalContext");
    logger.log(re);
    throw re;
}
なんで、ExternalContextがnullなのー!?
ちゃんと、S2ContainerFilterで設定してるけどぅ。
実際に、SingletonS2ContainerFactoryからベタに
取得しても、しっかりとExternalContextは取得できます。

なので、そのActionのComponentDefのContainerを取得して、
ContainerのPathやNameなどをログに出してみました。

すると path が "jta+UserTransaction.dicon" !?

すぐさまこのファイルを消して試してみると動作しました。
もちろん、拡張が無くなっちゃうのでその分は動かない。
で、こんどはそのdiconは設置するけど、
そのdiconの中のfoo.diconへのincludeを削除。
すると正常に動作しました(するとDIはされないけど)。

正常に動作するときのActionの属するContainerは、
app.diconになります。これが恐らく正しいのかな。

なので、とりあえず回避(いや恒久対応か!?)で、
拡張したUserTransactionの中では、
fooManagerをDIせずにgetComponent()するように。
これでHotでもCoolでも無事元気良く動くように。
これ、"ぷらなんとかdicon" じゃなくて、
"ぷらぷらdicon" (e.g. foo++.dicon) でも、
発生しました。
実際にDIしてなくても、includeするだけで発生。
でも、発生しないケースもありました。
aop++.diconに意味もなくjta.diconをincludeしてもOK。

この辺のケースの厳密な切り分けはできていません。
とりあえずトリガーが分かったので回避。
まあ、仕組みの奥底なので、getComponent()でもいいやと。

多分、根本の原因は S2ClassBuilder と Seasarの
すれ違いのような気もするのだけど、どちらも枯れてて、
今後解決されるかどうかが不明なので、
バッドノウハウとしてしっかり覚えておこうと。

HotDeployは便利でありながらも、
"Coolだと動かないよ問題" にわりと対峙するものなので、
こうやってしっかりブログに書いておきます。
(同じ問題に遭遇した他の人 or 将来の自分のため)