SeamFramework.orgCommunity Documentation
設定とは非常につまらないトピックであり極めて退屈な作業でもあります。 残念ながら XML の数行が JSF 実装およびサーブレットコンテナへの Seam の統合に必要となります。 ただし、 次のセクションにあるようなものを独自に入力する必要はなくサンプルのアプリケーションからコピーして貼り付けるだけの作業になりますので、 それほど心配することもありません。
最初に JSF と Seam を併用する場合に常に必要となる基本の設定について見ていくことにします。
当然 faces サーブレットが必要になります。
<servlet>
<servlet-name
>Faces Servlet</servlet-name>
<servlet-class
>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup
>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name
>Faces Servlet</servlet-name>
<url-pattern
>*.seam</url-pattern>
</servlet-mapping
>
(適宜 URL パターンを調整することができます。)
また、 Seam には web.xmlファイルに次の記述も必要になります。
<listener>
<listener-class
>org.jboss.seam.servlet.SeamListener</listener-class>
</listener
>
このリスナは Seam のブートストラップおよびセッションとアプリケーションコンテキストの破棄を行います。
JSF 実装の中には Seam の対話伝播と動作するサーバー側状態保存の実装が破損しているものがあります。 フォームサブミット中の対話伝播に関する問題が見られる場合はクライアント側状態保存に切り替えて見てください。 web.xml に次が必要となります。
<context-param>
<param-name
>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value
>client</param-value>
</context-param
>
ビュー状態値の変異性に関する JSF 仕様には不明慮な部分があります。 Seam は JSF ビュー状態を使用してその PAGE スコープを支えるため、 特定の場合に問題となる可能性があります。 JSF-RI でサーバー側状態保存を使用し PAGE スコープの Bean に任意のページの特定ビューに対するその正確な値を維持させたい場合には次のコンテキストパラメータを指定する必要があります。 これ以外、 ユーザ−が「戻る」ボタンを使用すると PAGE スコープのコンポーネントは「戻る」ページ以外の値に変更している場合は最新の値を持つことになります ( 仕様に関する問題 を参照)。 それぞれの要求での JSFビューの連続化にかかるパフォーマンスヒットのため、 この設定はデフォルトでは有効にされません。
<context-param>
<param-name
>com.sun.faces.serializeServerState</param-name>
<param-value
>true</param-value>
</context-param
>
我々の意見を聞き入れていただいて、JSPの替わりに faceletを使っていただけるとしたら、faces-config.xmlに以下の設定が必要です。
<application>
<view-handler
>com.sun.facelets.FaceletViewHandler</view-handler>
</application
>
そして、 web.xmlに下の記述も必要です。
<context-param>
<param-name
>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value
>.xhtml</param-value>
</context-param
>
JBoss AS で facelets を使用している場合は facelets のログ機能が破損しているのに気づかれるでしょう。 Seam はこれを修正するための橋渡しを提供しています。 これを使用するには lib/interop/jboss-seam-jul.jar を $JBOSS_HOME/server/default/deploy/jboss-web.deployer/jsf-libs/ にコピーしてから使用するアプリケーションの WEB-INF/lib に jboss-seam-ui.jar を含ませます。
Seam リソース Servlet は Seam Remoting 、キャプチャ (セキュリティの章を参照) や JSF の UI の制御で使用されるリソースを提供します。 Seam リソース Servlet の設定には web.xml に以下の記述が必要です。
<servlet>
<servlet-name
>Seam Resource Servlet</servlet-name>
<servlet-class
>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name
>Seam Resource Servlet</servlet-name>
<url-pattern
>/seam/resource/*</url-pattern>
</servlet-mapping
>
Seam は基本的な操作の場合はサーブレットフィルタを必要としません。 ただし、 フィルタの使用に依存する機能がいくつかあります。 Seam ではわかりやすいように他の組み込み Seam コンポーネントを設定する場合と同じようにしてサーブレットフィルタを追加したり設定することができます。 この機能を利用するにはまず web.xml にマスターフィルタをインストールする必要があります。
<filter>
<filter-name
>Seam Filter</filter-name>
<filter-class
>org.jboss.seam.servlet.SeamFilter</filter-class>
</filter>
<filter-mapping>
<filter-name
>Seam Filter</filter-name>
<url-pattern
>/*</url-pattern>
</filter-mapping
>
Seam マスターフィルタは web.xml で指定される 1 番目のフィルタでなければなりません。 これによりマスターフィルタが一番最初に実行されるようになります。
Seam フィルタは共通の属性をいくつか共有するため、 これらを以下に説明するパラメータに加えて components.xml に設定することができます。
url-pattern — フィルタされる要求を指定するのに使用します。 デフォルトは全要求です。 url-pattern はワイルドカードサフィックスを許可する Tomcat スタイルのパターンになります。
regex-url-pattern — フィルタされる要求を指定するのに使用します。 デフォルトは全要求です。 regex-url-pattern は要求パスに対する true の正規表現一致になります。
disabled — ビルトインのフィルタの無効化に使用します。
パターンは要求の URI パスに対してマッチングが行われる点 (HttpServletRequest.getURIPath() を参照)、 およびサーブレットコンテキスト名はマッチングが行われる前に削除される点に注意してください。
マスターフィルタを組み込むことにより、以下の組み込みフィルタを使用できるようになります。
このフィルタは pages.xml で例外マッピングの機能を提供します (ほぼすべてのアプリケーションでこの機能が必要とされます)。 また、 捕捉されなかった例外が発生した場合にコミットされていないトランザクションのロールバックも行います。 (Java EE 仕様によるとこれは Web コンテナによって自動的に行われるはずですが、 すべてのアプリケーションサーバーでは動作が信頼できないことが判明しています。 また、 Tomcat のようなプレーンなサーブレットエンジンには必要ありません。)
デフォルトで、すべてのリクエストに対して例外処理フィルタが適用されますが、下のように、 components.xmlに<web:exception-filter>を記述して、 これを変更することもできます。
<components xmlns="http://jboss.com/products/seam/components"
xmlns:web="http://jboss.com/products/seam/web">
<web:exception-filter url-pattern="*.seam"/>
</components
>
このフィルタはSeamがブラウザのリダイレクトにより対話コンテキストを伝搬する事を可能にします。 ブラウザリダイレクトをインターセプトし、Seamの対話identifierをパラメータに追加することにより、実現しています。
リダイレクトフィルタも、デフォルトですべてのリクエストを対象としますが、 components.xmlの記述を以下のようにして変更することが可能です。
<web:redirect-filter url-pattern="*.seam"/>
このフィルタにより Seam は pages.xml ファイルの設定をベースとしたビューの URL リライトを適用することができるようになります。 このフィルタはデフォルトではアクティブにはなっていませんが、 components.xml に設定を追加することでアクティブにすることができます。
<web:rewrite-filter view-mapping="*.seam"/>
view-mapping パラメータは web.xml ファイルにある Faces Servlet 用に定義されたサーブレットマッピングに合致しなければなりません。 省略するとリライトフィルタはパターンが *.seam であるとみなします。
この機能はファイルのアップロードの時のJSF制御に必要となります。マルチパートフォームのリクエストを検出すると、 RFC-2388 (multipart/form-data 仕様) に従い処理を行います。 デフォルトの設定をオーバーライドするためには components.xmlに以下の設定を追加します。
<web:multipart-filter create-temp-files="true"
max-request-size="1000000"
url-pattern="*.seam"/>
create-temp-files — true にセットするとアップロードされたファイルがメモリに維持される代わりにテンポラリファイルに書き込まれます。 大容量ファイルのアップロードが予期される場合は考慮すべき重要な点となるかもしれません。 デフォルト設定は false です。
max-request-size — ファイルのアップロード要求サイズがこの値を越えると (要求内の Content-Length ヘッダーを読み取り判定される) その要求は中断されます。 デフォルト設定は 0 です (サイズ制限なし)。
送信されたフォームデータのキャラクターエンコーディングをセットします。
デフォルトではこのフィルタはインストールされていませんので、components.xml に以下の記述が必要です。
<web:character-encoding-filter encoding="UTF-16"
override-client="true"
url-pattern="*.seam"/>
encoding — 使用するエンコーディングです。
override-client — true にセットすると要求エンコーディングはその要求がすでにエンコーディングを指定しているか否かにかかわらず encoding で指定されているものにセットされます。 false にセットすると要求エンコーディングは要求がまだエンコーディングを指定していない場合にのみセットされます。 デフォルト設定は false です。
RichFaces をプロジェクトに使用すると Seam は RichFaces Ajax フィルタをインストールしてその他すべての組み込みフィルタより先にこのフィルタがインストールされるようにします。 web.xml に手作業で RichFaces Ajax をインストールする必要はありません。
RichFaces Ajax フィルタは RichFaces jar 群がプロジェクトにある場合にのみインストールされます。
デフォルトの設定を上書きするには次のエントリを components.xml に追加します。 オプションは RichFaces Developer Guide に記載されているものと同じです。
<web:ajax4jsf-filter force-parser="true"
enable-cache="true"
log4j-init-file="custom-log4j.xml"
url-pattern="*.seam"/>
force-parser — JSF の全ページが Richfaces の XML 構文チェッカーにより強制的に検証されるようにします。 false なら AJAX の応答のみが検証され完全な XML に変換されます。 force-parser を false に設定するとパフォーマンスは向上しますが AJAX 更新でアーチファクトが視認できてしまう可能性があります。
enable-cache — フレームワーク生成のリソースのキャッシュ化を有効にします (javascript、 CSS、 イメージなど)。 カスタムの javascript や CSS を開発している場合は true に設定するとブラウザにリソースをキャッシュさせないようにします。
log4j-init-file — アプリケーションごとのログ記録のセットアップに使用されます。 ウェブアプリケーションコンテキストに相対となる log4j.xml 設定ファイルへのパスを与えてください。
このフィルタは認証されたユーザー名を log4j マップ診断コンテキストに追加するため、 必要に応じてパターンに %X{username} を追加することでフォーマット化されたログ出力に含ませることができます。
デフォルトではロギングフィルタは全要求を処理しますが、 以下の例で示すように <web:logging-filter> のエントリを components.xml に追加してこの動作を調整することができます。
<components xmlns="http://jboss.com/products/seam/components"
xmlns:web="http://jboss.com/products/seam/web">
<web:logging-filter url-pattern="*.seam"/>
</components
>
JSF servlet以外の servletに直接送信されるリクエストは、JSFのライフサイクルでは処理されません。 そこで、Seamは Seamのコンポーネントにアクセスする必要の有る その他の servletに対して servletフィルタを提供しています。
このフィルタを適用することにより、カスタムservletが Seamコンテキストと相互に作用することを可能にします。 個々のリクエストの最初にSeamコンテキストをセットアップし、リクエストの終了畤にこれを破棄します。このフィルタは JSFの FacesServlet には決して適用されない事を銘記してください。 Seam はJSFのリクエストのコンテキスト管理には phase listenerを使用します。
デフォルトではこのフィルタはインストールされていませんので、components.xml に以下の記述が必要です。
<web:context-filter url-pattern="/media/*"/>
コンテキストフィルタはconversationIdという名前でリクエストパラメータ中に対話 id を探そうとします。必ず、リクエストパラメータに対話 idを含めるようにしてください。
また、新たな対話 idをクライアント側に確実に伝える必要があります。 Seamは組み込みコンポーネント conversationのプロパティとして対話 idを公開しています。
Seam はカスタムのフィルタをインストールすることができ、 チェーン内にフィルタを配置する 場所 を指定できます (サーブレットの仕様はフィルタを web.xml に指定すると明確な順序を提供しない)。 @Filter アノテーションを Seam コンポーネント (javax.servlet.Filter を実装しなければならない) に追加するだけです。
@Startup
@Scope(APPLICATION)
@Name("org.jboss.seam.web.multipartFilter")
@BypassInterceptors
@Filter(within="org.jboss.seam.web.ajax4jsfFilter")
public class MultipartFilter extends AbstractFilter {
@Startup アノテーションを追加すると Seam 起動時にコンポーネントが使用可能となり、 バイジェクションはここでは使用できなくなり (@BypassInterceptors)、 フィルタは RichFaces フィルタよりチェーンの下方になります (@Filter(within="org.jboss.seam.web.ajax4jsfFilter"))。
SeamInterceptor を使用する Seam コンポーネントに適用する必要があります。 アプリケーション全体に渡りこれを最も容易に行う方法は次のインターセプタ設定を ejb-jar.xml に追加する方法です。
<interceptors>
<interceptor>
<interceptor-class
>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor>
</interceptors>
<assembly-descriptor>
<interceptor-binding>
<ejb-name
>*</ejb-name>
<interceptor-class
>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor-binding>
</assembly-descriptor>
Seam は、セッション Bean が JNDI でどこにあるかを知る必要があります。 このための方法の 1 つは、 それぞれの Session Bean コンポーネントに、@JndiName を指定することです。 しかし、 これではつまらな過ぎます。 もっと良い方法は、 EJB 名から JNDI 名を判断するために、 Seam が使用するパターンを指定することです。 あいにく、EJB3 標準に定義されたグローバル JNDI をマッピングする標準は存在しないため、 このマッピングはベンダ固有になります。 通常、components.xmlにこのオプションを指定します。
JBossアプリケーションサーバでは、次のパターンは誤りではありません。
<core:init jndi-name="myEarName/#{ejbName}/local" />
ここで、myEarNameは、Bean がデプロイされた EAR の名前です。
EAR のコンテキストの外側では (JBoss 組み込み可能 EJB3 コンテナを使用するとき)、 次のパターンは使い方の 1 つです。
<core:init jndi-name="#{ejbName}/local" />
他のアプリケーションサーバーに対して正しい設定を見つけるため実験を行う必要があります。 サーバーのなかにはすべての EJB コンポーネントにいちいち明示的に JNDI 名を指定する必要があるものもあるので注意してください。 この場合は独自のパターンを選択できます。
EJB3 環境ではトランザクション管理に特殊な組み込みコンポーネントを使用することをお勧めします。 これは完全なコンテナトランザクション認識で Events コンポーネントに登録されるトランザクションの成功イベントを正しく処理することができます。 この行を components.xml ファイルに追加しないと Seam はコンテナ管理トランザクションがいつ終了するのかを認識しません。
<transaction:ejb-transaction/>
最後にもう一つ理解しておくことがあります。 Seamコンポーネントが配備されるどのようなアーカイブにも、 seam.properties、META-INF/seam.properties あるいは META-INF/components.xmlを作成しておく必要があります (空のファイルであってもかまいません)。 Seamは起動時に seamコンポーネントを探すために、すべてのアーカイブでseam.propertiesをスキャンします。
Seamコンポーネントが有る場合には、webアーカイブ (WAR) のWEB-INF/classesディレクトリに seam.propertiesファイルを作成する必要があります。
すべての Seam サンプルに空白の seam.properties ファイルがあるのはこのためです。 このファイルを削除してしまうだけですべてが動作しなくなります。
なぜ設計者は空白のファイルがソフトウェアの動作に影響するよう設計したのだろうと不思議に思うかもしれません。 これは JVM の制限を回避する方法なのです。 このメカニズムを使用しなかったとしたら、 他のフレームワーク同様に components.xml に明示的にすべてのコンポーネントをすべて記載せざるをえなくなります。 空白ファイルの方がいいでしょう?
デフォルトの JPA プロバイダとして Seam はパッケージ化され Hibernate で設定されています。 別の JPA プロバイダを使用する必要がある場合は seam に指示しなければなりません。
JPA プロバイダの設定は将来的にはより簡単になり、 カスタムの永続プロバイダ実装を追加しない限り設定変更を必要としなくなります。
seam への別の JPA プロバイダ情報の指示は 2 種類いずれかの方法で行うことができます。
アプリケーションの components.xml を更新します。 これにより汎用 PersistenceProvider は hibernate バージョンより優先となります。 次をこのファイルに追加するだけです。
<component name="org.jboss.seam.persistence.persistenceProvider"
class="org.jboss.seam.persistence.PersistenceProvider"
scope="stateless">
</component
>
JPA プロバイダの非標準の機能を利用したい場合は PersistenceProvider の独自の実装を記述する必要があります。 HibernatePersistenceProvider を起点として使用します (記述したらコミュニティに貢献するのも忘れないでくださいね)。 つぎに前述した通り seam にそれを使うよう指示する必要があります。
<component name="org.jboss.seam.persistence.persistenceProvider"
class="org.your.package.YourPersistenceProvider">
</component
>
あとは正しいプロバイダクラスおよび使用するプロバイダが必要とするプロパティで persistence.xml を更新するだけです。 新しいプロバイダの jar ファイル群をアプリケーションでパッケージ化する必要があればそれも忘れないようにしてください。

Java EE 5 環境で実行している場合は Seam を使いはじめるのに必要な設定はこれだけです。
EAR にこれらすべてをパッケージ化したらアーカイブの構造は以下のようになります。
my-application.ear/
jboss-seam.jar
lib/
jboss-el.jar
META-INF/
MANIFEST.MF
application.xml
my-application.war/
META-INF/
MANIFEST.MF
WEB-INF/
web.xml
components.xml
faces-config.xml
lib/
jsf-facelets.jar
jboss-seam-ui.jar
login.jsp
register.jsp
...
my-application.jar/
META-INF/
MANIFEST.MF
persistence.xml
seam.properties
org/
jboss/
myapplication/
User.class
Login.class
LoginBean.class
Register.class
RegisterBean.class
...jboss-seam.jar を ejb モジュールとして META-INF/application.xml で宣言しなければなりません。 jboss-el.jar は EAR の lib ディレクトリに配置されるはずです (EAR クラスパスに配置する)。
jBPM または Drools を使用したい場合は EAR の lib ディレクトリに必要な jar 群を含ませなければなりません。
facelets を使用する場合 (推奨) は WARのWEB-INF/libディレクトリに jsf-facelets.jarを含める必要があります。
Seam のタグライブラリを使用する場合には (ほとんどの Seam アプリケーションで使用される)、 WAR ファイルの WEB-INF/lib ディレクトリに jboss-seam-ui.jar を含める必要があります。 PDFや email のタグライブラリを使用する場合には、 WEB-INF/lib に jboss-seam-pdf.jar または jboss-seam-mail.jar を含める必要があります。
Seam デバッグページを使用する (facelets を使用している場合のみ利用可能) 場合には WARの WEB-INF/libディレクトリにjboss-seam-debug.jarを含めます。
サンプルアプリケーションには EJB 3.0をサポートする Java EEコンテナに配備可能な幾つかの Seam アプリケーションがふくまれています。
設定に関するトピックはこれですべてですと言いたいところなんですが、 実はまた3 分の 1 しか説明していません。 退屈な設定の説明ばかりであきてしまった場合は残りのセクションは飛ばしてあとでもう一度読み直して頂いても構いません。
Seam は EJB 3.0 の使用にまだ思い切りがつかない方にも便利です。 このような場合には EJB 3.0 永続ではなく Hibernate3 か JPA を使用し、 セッション Bean の代わりにプレーン JavaBean を使用するとよいでしょう。 セッション Bean のいくつかの優れた機能は使用できませんが、 一旦決心がついたら EJB 3.0 への移行が非常に簡単になりますし、 それまでの間は Seam 固有の宣言的な状態管理アーキテクチャを利用することができます。

Seam JavaBean コンポーネントはセッション Bean のような宣言的トランザクションのデマケーションは提供しません。 手作業で JTA UserTransaction を使用するか、 宣言的に Seam の @Transactional アノテーションを使って管理することが できます。 ただし、 ほとんどのアプリケーションは JavaBean で Hibernate を使用する場合は Seam 管理のトランザクションを使用します。
Seam の配布には、EJB3 の代わりに Hibernate や JavaBean を使用した 予約サンプルアプリケーションが含まれています。 このサンプルアプリケーションはどんなJ2EEアプリケーションサーバでも すぐにデプロイ可能です。
Seam は組み込みコンポーネント (org.jboss.seam.core.hibernate ) がインストールされていれば、 hibernate.cfg.xml ファイルから、HibernateのSessionFactoryをブートストラップします。
<persistence:hibernate-session-factory name="hibernateSessionFactory"/>
この時、インジェクションを使って、Seamの管理する HibernateのSessionを利用するのであれば、 managed sessionを設定する必要があります。
<persistence:managed-hibernate-session name="hibernateSession"
session-factory="#{hibernateSessionFactory}"/>
Seam はもし組み込みコンポーネントがインストールされていれば、persistence.xml からEntityManagerFactory JPAをブートストラップします。
<persistence:entity-manager-factory name="entityManagerFactory"/>
インジェクションで Seam 管理のJPA EntityManager を使用可能にしたい場合は 管理永続コンテキスト を設定する必要があります。
<persistence:managed-persistence-context name="entityManager"
entity-manager-factory="#{entityManagerFactory}"/>
アプリケーションは WARとしてパッケージすることが出来、その構成は以下の様になります。
my-application.war/
META-INF/
MANIFEST.MF
WEB-INF/
web.xml
components.xml
faces-config.xml
lib/
jboss-seam.jar
jboss-seam-ui.jar
jboss-el.jar
jsf-facelets.jar
hibernate3.jar
hibernate-annotations.jar
hibernate-validator.jar
...
my-application.jar/
META-INF/
MANIFEST.MF
seam.properties
hibernate.cfg.xml
org/
jboss/
myapplication/
User.class
Login.class
Register.class
...
login.jsp
register.jsp
...Hibernate を Tomcat や TestNG のような EE 以外の環境にデプロイしたい場合はもう少し作業が必要となります。
Seam を完全に EE 環境の外側で使用することが可能です。 この場合、 使用できる JTA がないので Seam にどのようにトランザクションを管理するのかを指示する必要があります。 JPA を使用している場合は Seam に JPA リソースローカルのトランザクション、 EntityTransaction などを使用するよう指示することができます。
<transaction:entity-transaction entity-manager="#{entityManager}"/>
Hibernate を使用している場合は Seam に次のような Hibernate トランザクション API を使用するよう指示することができます。
<transaction:hibernate-transaction session="#{session}"/>
当然、 データソースも定義する必要があります。
よりよい代替としては JBoss Embedded を使用して EE の API へのアクセスを取得すします。
JBoss Embedded により Java EE 5 アプリケーションサーバーのコンテキストの外側で EJB 3 のコンポーネントを実行することができるようになります。 これには限られませんが、 特にテストに便利です。
Seam 予約サンプルアプリケーションには TestNG 統合テストスィートが含まれ、 SeamTest を通じて JBoss Embedded で実行します。

この予約サンプルアプリケーションは Tomcat にもデプロイ可能です。

Embedded JBoss を正しく動作させるには Seam アプリケーション用の Tomcat にインストールしなければなりません。 Embedded JBoss は JDK 5 または JDK 6 で実行します (JDK 6 の使い方については 項40.1. 「JDK の依存性」 を参照)。 Embedded JBoss は ここ でダウンロードできます。 Embedded JBoss の Tomcat 6 へのインストール手順は非常にシンプルです。 まず、 Embedded JBoss JAR 群と設定ファイル群を Tomcat にコピーします。
jndi.properties ファイルを除き、 Embedded JBoss の bootstrap ディレクトリと lib ディレクトリの配下にある全ファイルとディレクトリを Tomcat の lib ディレクトリにコピーします。
Tomcat の lib ディレクトリから annotations-api.jar ファイルを削除します。
次に、 Embedded JBoss 固有の機能に追加するため 2 つの設定ファイルを更新する必要があります。
Embedded JBoss リスナー EmbeddedJBossBootstrapListener を conf/server.xml に追加します。 このファイル内の他のすべてのリスナーの後ろに現れなければなりません。
<Server port="8005" shutdown="SHUTDOWN">
<!-- Comment these entries out to disable JMX MBeans support used for the
administration web application -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>
<!-- Add this listener -->
<Listener className="org.jboss.embedded.tomcat.EmbeddedJBossBootstrapListener"/>
WAR ファイルのスキャンは WebinfScanner リスナーを conf/context.xml に追加することで有効になるはずです。
<Context>
<!-- Default set of monitored resources -->
<WatchedResource
>WEB-INF/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
<!-- Add this listener -->
<Listener className="org.jboss.embedded.tomcat.WebinfScanner"/>
</Context
>
JDK 6 を使用している場合は Tomcat の起動スクリプト (catalina.bat か catalina.sh のどちらか) にある Java オプションの sun.lang.ClassLoader.allowArraySyntax を true にセットする必要があります。
set JAVA_OPTS=%JAVA_OPTS% -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties" -Dsun.lang.ClassLoader.allowArraySyntax=true
設定オプションの詳細については Embedded JBoss Tomcat 統合 wiki エントリ を参照してください。
Tomcat のような サーブレットエンジンへの WAR ベースのデプロイメントのアーカイブの構造は、以下のようになります。
my-application.war/
META-INF/
MANIFEST.MF
WEB-INF/
web.xml
components.xml
faces-config.xml
lib/
jboss-seam.jar
jboss-seam-ui.jar
jboss-el.jar
jsf-facelets.jar
jsf-api.jar
jsf-impl.jar
...
my-application.jar/
META-INF/
MANIFEST.MF
persistence.xml
seam.properties
org/
jboss/
myapplication/
User.class
Login.class
LoginBean.class
Register.class
RegisterBean.class
...
login.jsp
register.jsp
...ほとんどの Seam サンプルアプリケーションは、ant deploy.tomcat を実行することによって、 Tomcat にデプロイすることも可能です。
Seam の jBPM 統合はデフォルトではインストールされないためビルトインコンポーネントをインストールすることにより jBPM を有効にする必要があります。 また、 使用するプロセスとページフローの定義を components.xml で明示的に記載する必要があります。
<bpm:jbpm>
<bpm:pageflow-definitions>
<value
>createDocument.jpdl.xml</value>
<value
>editDocument.jpdl.xml</value>
<value
>approveDocument.jpdl.xml</value>
</bpm:pageflow-definitions>
<bpm:process-definitions>
<value
>documentLifecycle.jpdl.xml</value>
</bpm:process-definitions>
</bpm:jbpm
>
ページフローのみの指定であれば、これ以上の設定は不要です。プロセス定義を 利用する場合、jBPM設定を用意しなければなりません、あわせて、jBPMで利用する Hibernate設定も用意する必要があります。Seam DVD Store demoは Seam で機能する jbpm.cfg.xmlとhibernate.cfg.xmlを含めた サンプルです:
<jbpm-configuration>
<jbpm-context>
<service name="persistence">
<factory>
<bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
<field name="isTransactionEnabled"
><false/></field>
</bean>
</factory>
</service>
<service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
<service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
<service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
<service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
<service name="authentication"
factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
</jbpm-context>
</jbpm-configuration
>
ここでのもっとも重要なことは、jBPMトランザクション制御は無効になっているということです。 Seam、あるいはEJB3がJTAトランザクションを制御するべきです。
jBPM 設定やプロセスおよびページフローの定義ファイルに対する明確なパッケージング形式がいまだありません。 Seam サンプルでは単純にこうしたファイルはすべて EAR のルートにパッケージすることにしました。 将来的には何らかの標準的なパッケージング形式を設計することになると思いますので、 EAR は次に似たようなものになります。
my-application.ear/
jboss-seam.jar
lib/
jboss-el.jar
jbpm-3.1.jar
META-INF/
MANIFEST.MF
application.xml
my-application.war/
META-INF/
MANIFEST.MF
WEB-INF/
web.xml
components.xml
faces-config.xml
lib/
jsf-facelets.jar
jboss-seam-ui.jar
login.jsp
register.jsp
...
my-application.jar/
META-INF/
MANIFEST.MF
persistence.xml
seam.properties
org/
jboss/
myapplication/
User.class
Login.class
LoginBean.class
Register.class
RegisterBean.class
...
jbpm.cfg.xml
hibernate.cfg.xml
createDocument.jpdl.xml
editDocument.jpdl.xml
approveDocument.jpdl.xml
documentLifecycle.jpdl.xmlステートフルセッション Bean のタイムアウトは HTTP セッションのタイムアウトより高くセットすることが非常に重要となります。 これをしないと SFSB がユーザーの HTTP セッションが終了する前にタイムアウトする可能性があります。 JBoss Application Servre はセッション Bean タイムアウトがデフォルトでは 30 分になり、 server/default/conf/standardjboss.xml で設定されています (default を独自の設定に置き換える)。
デフォルトの SFSB タイムアウトは LRUStatefulContextCachePolicy キャッシュ設定内の max-bean-life の値を変更して調整することができます。
<container-cache-conf>
<cache-policy
>org.jboss.ejb.plugins.LRUStatefulContextCachePolicy</cache-policy>
<cache-policy-conf>
<min-capacity
>50</min-capacity>
<max-capacity
>1000000</max-capacity>
<remover-period
>1800</remover-period>
<!-- SFSB timeout in seconds; 1800 seconds == 30 minutes -->
<max-bean-life
>1800</max-bean-life
>
<overager-period
>300</overager-period>
<max-bean-age
>600</max-bean-age>
<resizer-period
>400</resizer-period>
<max-cache-miss-period
>60</max-cache-miss-period>
<min-cache-miss-period
>1</min-cache-miss-period>
<cache-load-factor
>0.75</cache-load-factor>
</cache-policy-conf>
</container-cache-conf
>
デフォルトの HTTP セッションタイムアウトは、 JBoss 4.0.x なら server/default/deploy/jbossweb-tomcat55.sar/conf/web.xml で、 JBoss 4.2.x なら server/default/deploy/jboss-web.deployer/conf/web.xml でそれぞれ変更することができます。 このファイルの次のエントリで、 すべてのウェブアプリケーションのデフォルトセッションタイムアウトを制御します。
<session-config>
<!-- HTTP Session timeout, in minutes -->
<session-timeout
>30</session-timeout>
</session-config
>
使用するアプリケーション用にこの値を上書きするにはこのエントリをそのアプリケーションの web.xml に含ませるだけです。
Seam アプリケーションを porlet で実行させたい場合は Seam および RichFaces 用の拡張を持ち portlet 内で JSF をサポートする JSR-301 の実装 JBoss Portlet Bridge を見てみてください。 詳細は http://labs.jboss.com/portletbridge を参照してください。
Seam はリソースの起動で /seam.properties、 /META-INF/components.xml、 または /META-INF/seam.properties を含むすべての jar をスキャンします。 たとえば、 @Name アノテーションが付与されたクラスはすべて Seam コンポーネントとして Seam に登録されます。
また、 Seam にカスタムのリソースを処理させたい場合があります。 一般的な使用例としては特定のアノテーションを処理することで、 Seam はこれに対する固有のサポートを提供します。 まず Seam に /META-INF/seam-deployment.properties で処理するアノテーションを指示します。
# A colon-separated list of annotation types to handle org.jboss.seam.deployment.annotationTypes=com.acme.Foo:com.acme.Bar
次にアプリケーション起動時に @Foo アノテーションが付くすべてのクラスを捕らえることができます。
@Name("fooStartup")
@Scope(APPLICATION)
@Startup
public class FooStartup {
@In("#{deploymentStrategy.annotatedClasses['com.acme.Foo']}")
private Set<Class<Object
>
> fooClasses;
@In("#{hotDeploymentStrategy.annotatedClasses['com.acme.Foo']}")
private Set<Class<Object
>
> hotFooClasses;
@Create
public void create() {
for (Class clazz : fooClasses) {
handleClass(clazz);
}
for (Class clazz : hotFooClasses) {
handleClass(clazz);
}
}
}また、 あらゆる リソースを処理することができます。 たとえば、 .foo.xml 拡張子が付くファイルすべてを処理する場合、 カスタムのデプロイメントハンドラを記述する必要があります。
public class FooDeploymentHandler implements DeploymentHandler {
private Set<InputStream
> files = new HashSet<InputStream
>();
public String getName() {
return "fooDeploymentHandler";
}
public Set<InputStream
> getFiles() {
return files;
}
public void handle(String name, ClassLoader classLoader) {
if (name.endsWith(".foo.xml")) {
files.add(classLoader.getResourceAsStream(name));
}
}
}ここではサフィックス .foo.xml が付くすべてのファイルの一覧をビルドしているだけです。
つぎにデプロイメントハンドラを Seam に登録する必要があります。 /META-INF/seam-deployment.properties で行います。
# For standard deployment org.jboss.seam.deployment.deploymentHandlers=com.acme.FooDeploymentHandler # For hot deployment org.jboss.seam.deployment.hotDeploymentHandlers=com.acme.FooDeploymentHandler
コンマで区切った一覧を使うと複数のデプロイメントハンドラを登録することができます。
Seam は内部的にデプロイメントハンドラを使ってコンポーネントや名前空間をインストールするため、 その前に handle() を呼び出すと多くの場合に便利です。 ただし、 APPLICATION スコープのコンポーネントの起動中にデプロイメントハンドラに簡単にアクセスすることができます。
@Name("fooStartup")
@Scope(APPLICATION)
@Startup
public class FooStartup {
@In("#{deploymentStrategy['fooDeploymentHandler']}")
private MyDeploymentHandler myDeploymentHandler;
@In("#{hotDeploymentStrategy['fooDeploymentHandler']}")
private MyDeploymentHandler myHotDeploymentHandler;
@Create
public void create() {
for (InputStream is : myDeploymentHandler.getFiles()) {
handleFooXml(is);
}
for (InputStream is : myHotDeploymentHandler.getFiles()) {
handleFooXml(is);
}
}
}