-なぜタグ追い越しがおきるのか

なぜJSFにおいて「タグ追い越し」問題がおきるのかは明白です。それはJSPが、そういう用途を考えてなかったから。JSFのタグの基底であるUIComponentTagのdoEndTag()にこんなことが書いてあります。

if(component.getRendersChildren()) {
  encodeBegin();
  encodeChildren();
}
encodeEnd();

JSFの出力はUIComponentのencodeBegin()とencodeEnd()および子コンポーネントの出力をうながすencodeChildren()で行われますが、これらがすべてTag#doEndTag()で実行される(場合がある)のです。なんでこんなことをしているかというと、doStartTag()冒頭にてUIComponentのツリーを作っているためです。JSPの描画によるツリーウォークによって、UIComponentのネスト状態を作ります。component.getRendersChildren()は子コンポーネントが自分の描画に関与する可能性があるかどうかをテストするもので、これがtrueだとdoStartTag()ではencodeBegin()は行えず、コンポーネントツリーを作るだけにとどめます。そして、JSPの描画ツリーウォークを待ち、自分が描画できるまでまちます。やっと描画できるタイミング、それがdoEndTag()です。
JSFのタグの場合、この事情を知ってますのでしっかり子タグも描画を待ってくれますが、JSPの普通のタグやJSP上のテンプレートテキストは待ってくれません。よって、「タグ追い越し」問題が発生するわけです。
さて、これの対応はいくつか考えられます。一つ目はS2JSFのやった方法。テンプレート上のテキストやエレメントを全部JSFのUIComponentTagにしてしまうことです。すべてをUIComponentTagにすることによってUIComponentツリーを確実に構築します。JSFコンポーネントモデルはそれでもよくできているので、これはかなり有効な手だと思います。Tapestryは実はまったくJSFとは異なる技術ですが、この技法に近いことをします。
もうひとつは、まったくJSPのタグを使わないことです。もっと詳しくいうと、UIComponentのツリー構築と描画をフェーズわけすること。Mayaはこっちで行こうと思います。ツリー構築と描画を同時にやらざるを得ないJSPとは違って、Mayaはいまからでも、JSF用にいんちきすればいいんだからね。。。UIComponentを構築するのと、描画を別タイミングでおこない、その描画はとにかくbeginとendで順送りに実行していけばシンプルに実現できるはず。
ただ、Maya全体でやると、必要ないMaya単体もしくはMaya+Strutsのときにパフォーマンス的にもったいないので、設定チューニングできるようにデザインしたいと思います。