Faceletsで画面が正常にレンダリングされない現象

悲しいことに3時間ほどはまってしまったので、メモっておく。

現象

  • JSF 1.2 + Faceletsの構成のWebアプリで、画面が正常にレンダリングされない。
  • 私が遭遇したときは、初回アクセス時の画面は表示されるが、そこからボタンをクリックしてアクションを実行し、自画面を再描画すると画面のヘッダとフッタのみ表示されて真ん中のコンテンツ部分が何も表示されなかった(Faceletsのテンプレートを使用して、ヘッダ、フッタ、コンテンツ部分を分けてます)。
  • ERRORログは特に出力されなくて、一見正常終了しているように見える

解析

  • ログレベルを変更して、何か有効な情報が出力されていないか確認してみた。すると、INFOレベルで以下のような見慣れぬFaceletsのログが出ていることが判明。
INFO: Facelet[/template/header.xhtml] was modified @ 21:05:10 PM, flushing component applied @ 21:05:10 PM
INFO: Facelet[/template/footer.xhtml] was modified @ 21:05:10 PM, flushing component applied @ 21:05:10 PM
  • 何やらheader.xhtmlが更新されたと検知しているようである... ここでピンと来ました。そういや使用しているサーバOSの時刻がずれてたな、と。
  • OSの時刻を現在時刻に設定し再度実行してみると、、、上記のINFOログも出なくなり、正常に画面描画されるようになりました。
  • どうも、デプロイしたXHTMLファイルの更新時刻が、サーバOSの時刻より新しいと、Faceletsがそのファイルが更新されたと認識してXHTMLをリコンパイルすることでこの現象が発生してしまうようです。
  • リコンパイルされるとコンポーネントツリーが復元できなくてなるらしい。。。
  • 確かに、サーバOSの時刻は2時間ほど遅れてました。そしてデプロイしたEARは時刻が正常なPCでビルドした物だったので、見事にずれてました。

対応方法

  • サーバOSのずれている時刻を正しくすることで解決です。
  • 他にも、Faceletsの設定を変更して、XHTMLの変更を検知させなくする方法もある。web.xmlに、facelets.REFRESH_PERIODを-1と設定すればいいようです。
<context-param> 
        <param-name>facelets.REFRESH_PERIOD</param-name> 
        <param-value>-1</param-value> 
</context-param> 

参考情報

"flushing component applied" faceletsで検索すると、英語のページですが同じように引っかかった人のページが出てくる。