JSF 2.0のPROJECT_STAGEをアプリケーションの外部から指定する

JSF 2.0ではProjectStageなるものを指定できて、開発時はDevelopmentにして詳細なエラーメッセージを表示し、正式運用時にはProductionとかに変更したりする。

巷のサンプルでは、この値を以下のようにweb.xmlで指定しているものが多い。

  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
  </context-param>

個人的な感覚だと、この手の「開発環境か運用環境か」に関係する値を web.xml というアプリケーションの一部に埋め込むのは気持ち悪いので、外部から指定する方法を探してみた。

で、やっぱりまずは原典だろということでJSFの仕様を見てみたら、「PROJECT_STAGEはJNDIからも設定できるよ。詳しくはApplication.getProjectStage()のJavadocを見てね」とあり即刻やり方が判明してしまった。ProjectStage.PROJECT_STAGE_JNDI_NAMEの値である ""java:comp/env/jsf/ProjectStage" というJNDI名で "Development" とかの文字列値を設定しておけば見てくれる。これはJSFの仕様で決まっているらしい。

値を指定する方法は動作環境によって色々だけど、たとえばTomcat6なら server.xml とかの Context 要素を以下のようにする(この例はCXFシリーズでのWebアプリ)。

<Context docBase="ws-webclient" path="/ws-webclient" reloadable="true" source="org.eclipse.jst.jee.server:ws-webclient">
   <!-- java:comp/env/jsf/ProjectStage というJNDI名で Develpment という文字列値を設定 -->
  <Environment name="jsf/ProjectStage" value="Development" type="java.lang.String" />
</Context>

値をセットしたら、web.xml には以下のように指定してWebアプリケーション側で使えるようにする。

<resource-env-ref>
  <resource-env-ref-name>jsf/ProjectStage</resource-env-ref-name>
  <resource-env-ref-type>java.lang.String</resource-env-ref-type>
</resource-env-ref>

これで最初の context-param を使うのと同じことがJNDIを通して「動作環境」の側で指定できるようになった。すっきり。

EclipseWTPTomcatで開発している場合、Serversプロジェクトの中のserver.xmlに対する変更は自動的には反映されない点に注意が必要。server.xmlを変更したら、「サーバー」ビューの該当のサーバで一旦「公開」を行わないと反映されない。