29.3. EJB コンテナー

EJB コンテナーは、特定の EJB クラスを管理するコンポーネントです。JBoss では、デプロイされた EJB の設定ごとに org.jboss.ejb.Container のインスタンスが1つ作成されます。インスタンス化される実際のオブジェクトは、Container のサブクラスで、コンテナーインスタンスの作成は、EJBDeployer MBean が管理します。

29.3.1. EJBDeployer MBean

org.jboss.ejb.EJBDeployer MBean は、EJB コンテナーを作成します。デプロイの準備ができた EJB JAR があるとします。EJBDeployer は、EJB のタイプごとに、必要な EJB コンテナーを1つずつ作成し開始します。EJBDeployer の設定可能な属性は以下のとおりです。
  • VerifyDeployments: EJB 検証を実行すべきか示す boolean フラッグ。これにより、デプロイメントユニットの EJB が EJB 2.1 仕様に準拠しているか検証します。これを true に設定すると、デプロイメントが有効か確認できるため便利です。
  • VerifierVerbose: 検証プロセスから出される検証の失敗/警告をどの程度詳しく出すか制御する boolean。
  • StrictVerifier: 厳密な検証を有効化あるいは無効化する boolean。厳密な検証が有効であれば、検証レポートにエラーがない場合にのみ、EJB はデプロイされます。
  • CallByValue: 値渡しのセマンティクスをデフォルトで使用すべきであると指示をだす boolean フラグ。
  • ValidateDTDs: 宣言した DTD に対して、ejb-jar.xmljboss.xml 記述子が有効であることを検証するべきか示す boolean フラグ。これを true にすると、配備記述子が有効であるかを確認できるため便利です。
  • MetricsEnabled: metricsEnabled=true 属性で印付けされているコンテナーインターセプターが設定に含めるべきかを示す boolean フラグ。これにより、コンテナーインターセプター設定 (これは On/Off が可)を含むメトリクスタイプのインターセプターを定義できるようになります。
  • WebServiceName: Web サービス MBean の JMX ObjectName 文字列。これにより、動的クラスローディングに対応可能にするEJB クラスの動的クラスローディングに対応できるようになります。
  • TransactionManagerServiceName: JTA トランザクションマネージャーの JMX ObjectName 文字列。これには、javax.transaction.TransactionManager インスタンスを返す TransactionManager と呼ばれる属性を持たせる必要があります。
デプロイヤーには、deploy と undeploy という、2つの中心的なメソッドが含まれています。deploy メソッドは、EJB JAR、あるいは有効な EJB JAR と同じ構造のディレクトリ (開発目的で便利) を参照している URL を取得します。デプロイメントが行われると、同じ URL 上で undeploy が呼び出されるとアンデプロイすることができます。すでにデプロイ済みの URL で deploy が呼び出されると、undeploy が呼び出され、その URL のデプロイメントが行われます。JBoss は実装およびインターフェースクラス両方の再デプロイメントに対応しており、変更されたクラスはどれでも読み込みます。これにより、稼働中のサーバーを停止することなく EJB の開発と更新を行うことができます。
EJB JAR のデプロイメント中に、EJBDeployer とこれに関連付けられたクラスは、EJB を検証、一意の EJB ごとにコンテナを作成、デプロイメント設定情報でコンテナーを初期化するという、3つの機能を果たします。以下の章で、各機能について説明していきます。

29.3.1.1. EJB デプロイメントの検証

EJBDeployerVerifyDeployments 属性が true の場合、デプロイヤーはデプロイメントの EJB を検証します。この検証で、EJB が EJB 仕様に準拠しているか確認します。これは、EJB デプロイメントユニットに、必要なホームとリモート、ローカルホーム、ローカルインターフェースが含まれているかの検証も行います。また、これらのインターフェースに表示されるオブジェクトが正しい型で、また実装クラスに必要なメソッドが存在しているかも確認します。EJB 開発者やデプロイヤーは適切な EJB JAR を正しく構築する際に多くの手順を踏む必要があるため間違いを起こしやすいので、便利な動作としてデデフォルトで有効になっています。検証の段階で間違いを突き止め、どこを修正すべきか示すようなエラーを出しデプロイメントが失敗するように試みています。
おそらく、EJB 記述する上で最も問題となる部分は、bean 実装とリモートとホームのインターフェースの間、さらに配備記述子設定との間が分離される点です。これらの各種要素を簡単に同期しないようにできます。この問題を回避できるようにするツールの1つに XDoclet があります。このツールは、EJB bean 実装クラスの中でカスタムの JavaDoc のようなタグを使い、関連の bean インターフェース、配備記述子、関連オブジェクトを生成することができます。さらなる詳細については、XDoclet ホームページ、http://sourceforge.net/projects/xdoclet を参照してください。

29.3.1.2. EJB をコンテナーにデプロイ

EJBDeployer が行う最も重要な役割は、EJB コンテナーを作成し、EJB をコンテナーにデプロイすることです。デプロイメントフェーズでは、EJB JAR 内で EJB を反復し、ejb-jar.xml および jboss.xml 配備記述子で記述されているように、bean クラスやメタデータを抽出します。EJB JAR の各 EJB に対して、以下の手順を実行します。
  • EJB の型 (ステートレス、ステートフル、BMP エンティティ、CMP エンティティ、あるいはメッセージ駆動) に従い、org.jboss.ejb.Container のサブクラスを作成します。コンテナーに一意の ClassLoader が割り当てられ、この ClassLoader からローカルリソースをロードすることができます。 ClassLoader の一意性を利用し、標準のjava:comp JNDI 名前空間と他の J2EE コンポーネントを分類することができます。
  • jboss.xmlstandardjboss.xml 記述子を統合したものから取ったコンテナーの設定可能属性をすべて設定します。
  • コンテナーに設定されているようにコンテナーインターセプターを作成し、追加します。
  • アプリケーションオブジェクトとコンテナーを関連付けます。このアプリケーションオブジェクトは、J2EE エンタープライズアプリケーションを表し、複数の EJB および Web コンテキストを含む場合があります。
EJB がすべて正常にデプロイされると、アプリケーションが開始され、その後、順に全コンテナーを開始し EJB をクライアント側で利用できるようにします。EJB のいずれかがデプロイメントに失敗すると、デプロイメントの例外がスローされ、そのデプロイメントモジュールが失敗します。

29.3.1.3. コンテナー設定情報

JBoss は、EJB コンテナーの設定のすべて、あるいはその多くを jboss_4_0.dtd を構成する XML ファイルを使い外部に置いています。コンテナー設定情報に関連する DTD は、図29.4「コンテナー設定関連の jboss_4_0 DTD 要素」 にあります。
container-configuration 要素とそのサブ要素はcontainer-name 要素で提示されているように、コンテナーのタイプ毎にコンテナー構成の設定を指定します。各設定は、デフォルトの呼び出しタイプ、コンテナーインターセプターのマークアップ、インスタンスキャッシュ/プール、そのサイズ、永続マネージャー、セキュリティなどの情報を指定します。これには、JBoss コンテナーアーキテクチャーを詳細まで把握していなければならない情報が大量にあるので、JBoss では EJB の4つのタイプに対する標準設定を同梱しています。この設定ファイルは、standardjboss.xml と呼ばれ、EJB を使う設定ファイルセットの conf ディレクトリに置かれています。以下は、standardjboss.xml からの container-configuration 例となっています。
<container-configuration>
    <container-name>Standard CMP 2.x EntityBean</container-name>
    <call-logging>false</call-logging>
    <invoker-proxy-binding-name>entity-rmi-invoker</invoker-proxy-binding-name>
    <sync-on-commit-only>false</sync-on-commit-only>
    <insert-after-ejb-post-create>false</insert-after-ejb-post-create>
    <call-ejb-store-on-clean>true</call-ejb-store-on-clean>
    <container-interceptors>
        <interceptor>org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor</interceptor>
        <interceptor>org.jboss.ejb.plugins.LogInterceptor</interceptor>
        <interceptor>org.jboss.ejb.plugins.SecurityInterceptor</interceptor>
        <interceptor>org.jboss.ejb.plugins.TxInterceptorCMT</interceptor>
        <interceptor>org.jboss.ejb.plugins.CallValidationInterceptor</interceptor>
        <interceptor metricsEnabled="true">
            org.jboss.ejb.plugins.MetricsInterceptor
        </interceptor>
        <interceptor>org.jboss.ejb.plugins.EntityCreationInterceptor</interceptor>
        <interceptor>org.jboss.ejb.plugins.EntityLockInterceptor</interceptor>
        <interceptor>org.jboss.ejb.plugins.EntityInstanceInterceptor</interceptor>
        <interceptor>org.jboss.ejb.plugins.EntityReentranceInterceptor</interceptor>
        <interceptor>
             org.jboss.resource.connectionmanager.CachedConnectionInterceptor
        </interceptor>
        <interceptor>org.jboss.ejb.plugins.EntitySynchronizationInterceptor</interceptor>
        <interceptor>org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor</interceptor>
    </container-interceptors>
    <instance-pool>org.jboss.ejb.plugins.EntityInstancePool</instance-pool>
    <instance-cache>org.jboss.ejb.plugins.InvalidableEntityInstanceCache</instance-cache>
    <persistence-manager>org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager</persistence-manager>
    <locking-policy>org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock</locking-policy>
    <container-cache-conf>
        <cache-policy>org.jboss.ejb.plugins.LRUEnterpriseContextCachePolicy</cache-policy>
        <cache-policy-conf>
            <min-capacity>50</min-capacity>
            <max-capacity>1000000</max-capacity>
            <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>
    <container-pool-conf>
        <MaximumSize>100</MaximumSize>
    </container-pool-conf>
    <commit-option>B</commit-option>
</container-configuration>
これらの2つの例は、コンテナー設定のオプションがいかに拡張できるかを説明しています。コンテナー設定情報は、2つのレベルで指定可能です。1つは、設定ファイルセットのディレクトリに含まれている standardjboss.xml ファイル内で、2つ目は、EJB JAR レベルで指定可能です。EJB JAR META-INF ディレクトリに jboss.xml ファイルを置くことで、standardjboss.xml ファイルのコンテナー設定をオーバーライドするか、あるいは新しく名前をつけたコンテナー設定を指定することも可能です。こうすることで、コンテナーの設定が大幅に柔軟になります。前述したように、コンテナー設定属性はすべて、外部に置かれているため、変更も可能です。知識の豊富な開発者は、インスタンスプールやキャッシュなど、特別なコンテナーコンポーネントを実装し、標準のコンテナー設定と簡単に統合し、特定のアプリケーションや環境で動作の最適化を図ることさえ可能です。
EJB デプロイメントがどのようにコンテナー設定を選択するかは、jboss/enterprise-beans/<type>/configuration-name 要素が明示的か暗黙的かにより変わります。configuration-name 要素は、container-configurations/container-configuration へのリンクとなっており、参照 EJB に利用するコンテナー設定はどれかを指定します。これは、configuration-name 要素からcontainer-name 要素をリンクしています。
EJB 定義にcontainer-configuration 要素を含めることで、EJB のクラスごとにコンテナー設定を指定することができます。通常、新規コンテナー設定の定義がサポートされていても、完全な定義を行わないようです。jboss.xml レベルの container-configuration は、一般的に、standardjboss.xml 記述子にあるcontainer-configuration の1つあるいは複数の部分をオーバーライドすることで利用しています。これは、既存の standardjboss.xmlcontainer-configuration/container-name 名をcontainer-configuration/extends 属性の値として参照している、container-configuration を指定することで実行できます。以下の例は、Standard Stateless SessionBean 設定の拡張である、新規のSecured Stateless SessionBean 設定を定義してます。
<?xml version="1.0"?>
<jboss>
    <enterprise-beans>
        <session>
            <ejb-name>EchoBean</ejb-name>
            <configuration-name>Secured Stateless SessionBean</configuration-name>
            <!-- ... -->
        </session>
    </enterprise-beans>
    <container-configurations>
        <container-configuration extends="Standard Stateless SessionBean">
            <container-name>Secured Stateless SessionBean</container-name>
            <!-- Override the container security domain -->
            <security-domain>java:/jaas/my-security-domain</security-domain>
        </container-configuration>
    </container-configurations>
</jboss>
EJB がデプロイメントユニットの EJB JAR にコンテナー設定仕様を提供しない場合、コンテナーファクトリは EJB のタイプを元に standardjboss.xml 記述子からコンテナー設定を選択します。そのため、実際は、暗黙的な configuration-name 要素が EJB 型ごとに存在し、デフォルトのコンテナー設定へ EJB 型をマッピングしたものは以下の通りになります。
  • container-managed persistence entity version 2.0 = Standard CMP 2.x EntityBean
  • container-managed persistence entity version 1.1 = Standard CMP EntityBean
  • bean-managed persistence entity = Standard BMP EntityBean
  • stateless session = Standard Stateless SessionBean
  • stateful session = Standard Stateful SessionBean
  • message driven = Standard Message Driven Bean
デフォルトの bean タイプを使いたい場合は、EJB が利用するコンテナー設定はどれかを指定する必要はありません。おそらく、configuration-name を含み、必要なものを備え持った記述子を提供していますが、これは単にスタイルの問題です。
EJB が利用するコンテナー設定を指定する方法を理解いただき、デプロイメントユニットレベルのオーバーライドの定義が可能になったため、次の章で container-configuration 子要素を見ていきます。要素の多くは、インターフェースクラス実装を指定しますが、このインターフェース実装の設定は他の要素から影響を受けるため、設定要素に手を加える前に、org.jboss.metadata.XmlLoadable インターフェースについて理解する必要があります。
XmlLoadable インターフェースは、シンプルなインターフェースでメソッド1つしか含んでいません。インターフェースの定義は以下の通りです。
import org.w3c.dom.Element;
public interface XmlLoadable
{
    public void importXml(Element element) throws Exception;
}
クラスは、このインターフェースを実装し、そのクラス設定を XML 文書にて指定できるようになります。文書の root 要素は、 importXml メソッドに渡されるはずです。以下の章にてコンテナー設定の要素について説明していくため、これについていくつか例を参照できるはずです。
29.3.1.3.1. container-name 要素
container-name 要素は、設定ごとに一意名を指定します。コンテナー設定に関して、EJB のconfiguration-name 要素を container-name の値に設定することで、EJB は特定のコンテナー設定と関連付けられます。
29.3.1.3.2. call-logging 要素
call-logging 要素は、 LogInterceptor はコンテナーへのメソッド呼び出しをログするべきかを指示する値に boolean (true あるいは false) が来るであろうと予測します。これは、細かく設定可能なロギング API を提供する log4j に移行するうえで若干古くなってきています。
29.3.1.3.3. invoker-proxy-binding-name 要素
invoker-proxy-binding-name 要素は、利用するデフォルトの呼び出し名を指定します。bean レベルのinvoker-bindings 指定がない場合、 invoker-proxy-binding-name 要素の値とinvoker-proxy-binding の名前が一致するinvoker-proxy-binding を使い、ホームとリモートのプロキシを作成します。
29.3.1.3.4. sync-on-commit-only 要素
これは、パフォーマンスの最適化について設定します。このパフーマンスの最適化を行うと、エンティティ bean のステータスがコミット時のみにデータベースと同期されるようになります。通常、トランザクション内の bean のステータスはすべて、finder メソッドが呼び出された時、あるいは remove メソッドが呼び出されたときなどに同期されなければなりません。
29.3.1.3.5. insert-after-ejb-post-create
これは別のエンティティ bean の最適化ですが、これは、ejbPostCreate メソッドが呼び出されるまで、新規エンティティ bean に対するデータベースの挿入コマンドが実行されません。こうすることで、デフォルトの挿入後にアップデートを行うことなく、通常の CMP フィールドと CMR フィールドを1回の挿入で設定することができます。結果、関係フィールドに null 値を可能にするための要件を削除できます。
29.3.1.3.6. call-ejb-store-on-clean
この仕様によると、トランザクションでインスタンスが変更されなかった場合にもトランザクションがコミットされた場合、コンテナーはエンティティ bean インスタンスで ejbStore メソッドを呼び出す必要があります。これを false に設定すると、JBoss はダーティオブジェクトに対して ejbStore だけを呼び出すようになります。
29.3.1.3.7. container-interceptors 要素
container-interceptors 要素は、1つ以上のインターセプター要素を指定し、このインターセプター要素はコンテナーにメソッドインターセプターチェーンとして設定されます。インターセプター要素の値は、org.jboss.ejb.Interceptor インターフェース実装の完全修飾名です。コンテナーインターセプターは、 linked-list 構造を形成しており、この構造を使い EJB メソッドの呼び出しを渡します。MBeanServer がコンテナーにメソッド呼び出しを渡すと、チェーンにある最初のインターセプターが呼び出されます。最後のインターセプターは、bean にあるビジネスメソッドを呼び出します。Interceptor インターフェースについては、本章でコンテナープラグインフレームワークについて触れる際に後述します。一般的に、セキュリティ、トランザクション、永続性、スレッドセーフに関する EJB コントラクトはインターセプターから派生しているため、既存の標準 EJB インターセプター設定を変更する際は注意が必要です。
29.3.1.3.8. instance-pool 要素
instance-pool 要素は、org.jboss.ejb.InstancePool インターフェースの完全修飾クラス名を指定し、コンテナー InstancePool として利用します。InstancePool インターフェースについては、本章でコンテナープラグインフレームワークについて触れる際に後述します。
29.3.1.3.9. container-pool-conf 要素
container-pool-confInstancePool 実装クラスに渡します。このInstancePool 実装クラスは、XmlLoadable インターフェースが実装された場合にinstance-pool 要素により渡されます。現在の JBoss InstancePool 実装は、図29.5「container-pool-conf 要素の DTD」 で提示している要素へ対応可能にする org.jboss.ejb.plugins.AbstractInstancePool クラスから来ています。
container-pool-conf 要素の DTD

図29.5 container-pool-conf 要素の DTD

  • MinimumSize: JBoss では現在 InstancePoolMinimumSize 値にシードしませんが、MinimumSize 要素は、プールに保存できるインスタンスの最小数を渡します。
  • MaximumSize: MaximumSize は、プールインスタンスの上限数を指定します。MaximumSize のデフォルトの用途は、考えているものと少し違うかもしれません。プール MaximumSize は、EJB インスタンスの最大利用可能数ですが、同時リクエストの数が MaximumSize の値を超えた場合、さらにインスタンスを作成することができます。
  • strictMaximumSize: EJB の最大並行処理数をプールの MaximumSizeに制限したい場合、strictMaximumSize 要素を true に設定する必要があります。strictMaximumSize が true の場合、MaximumSize EJB インスタンスのみがアクティブとなります。MaximumSize が有効なインスタンスがある場合、インスタンスがプールに開放されるまでその後に続くリクエストはブロックされます。strictMaximumSize のデフォルト値は、false です。
  • strictTimeout: リクエストがインスタンスのプールオブジェクトの待機をブロックする時間は、strictTimeout 要素で制御されます。strictTimeout は、MaximumSize が有効なインスタンスがある場合にプールへインスタンスを返すまでの待機時間をミリ秒単位で定義します。0以下の値の場合は待機時間なしとなります。リクエストのインスタンス待機時間がタイムアウトした場合、java.rmi.ServerException が生成され呼び出しが中断されます。これは Long として解析されるため、最大の許容待機時間は 9,223,372,036,854,775,807 あるいは約 292,471,208 年で、これがデフォルト値となっています。
29.3.1.3.10. instance-cache 要素
instance-cache 要素は、org.jboss.ejb.InstanceCache インターフェース実装の完全修飾名を指定します。この要素は、ID が関連付けられている EJB タイプがエンティティ bean とステートフルセッション bean のみであるため、これらの bean に対してのみ意味をなします。InstanceCache インターフェースについては、コンテナープラグインフレームワークについて本章で後述する際に触れます。
29.3.1.3.11. container-cache-conf 要素
container-cache-conf 要素は、XmlLoadable インターフェースに対応している場合、InstanceCache 実装に渡されます。現在の JBoss InstanceCache 実装はすべて、org.jboss.ejb.plugins.AbstractInstanceCache クラスから来ています。このクラスは、XmlLoadable インターフェースに対応し、インスタンスキャッシュストアとして利用する org.jboss.util.CachePolicy 実装の完全修飾名としてcache-policy 子要素を利用します。cache-policy-conf 子要素は、XmlLoadable インターフェースに対応していれば、CachePolicy 実装に渡されます。対応していない場合は、cache-policy-conf は確認なしに無視されます。
現在の cache-policy-conf 子要素アレイに対応している、standardjboss.xml 設定が利用する CachePolicy の JBoss 実装が2つあります。これらの実装クラスは、 org.jboss.ejb.plugins.LRUEnterpriseContextCachePolicyorg.jboss.ejb.plugins.LRUStatefulContextCachePolicy となっています。LRUEnterpriseContextCachePolicy は、エンティティ bean コンテナーに、LRUStatefulContextCachePolicy はステートフルセッション bean コンテナーにより利用されます。このキャッシュポリシーは両方、図29.6「container-cache-conf 要素の DTD」にある以下の cache-policy-conf 子要素に対応しています。
container-cache-conf 要素の DTD

図29.6 container-cache-conf 要素の DTD

  • min-capacity: このキャッシュの最小容量を指定します。
  • max-capacity: このキャッシュの最大容量を指定しますが、 min-capacity より小さい数値には設定できません。
  • overager-period: overager タスクを実行する間隔を秒単位で指定します。overager タスクの目的は、キャッシュにmax-bean-age 要素値の一定年齢以上となっている bean が含まれているか確認することです。この基準に合致する bean はすべて非活性化 (passivate) されます。
  • max-bean-age: overager プロセスにより非活性化が行われるまで bean がどの程度アクティブでない状態でいられるか上限を指定します。
  • resizer-period: resizer タスクを実行する間隔を秒単位で指定します。resizer タスクの目的は、以下の方法で、残り3つの要素値をもとにキャッシュの容量を縮小/拡大します。resizer タスクが実行されると、キャッシュミスの現在の間隔をチェックし、この間隔がmin-cache-miss-period の値より小さい場合は、cache-load-factor を使い、キャッシュは最大で max-capacity の値まで拡大されます。キャッシュミスの間隔がmax-cache-miss-period 値より小さい場合は、このキャッシュは cache-load-factor を使い縮小されます。
  • max-cache-miss-period: キャッシュミスがキャッシュの容量が縮小されたとシグナル送信すべき間隔を指定します。キャッシュが縮小されるまで許容最小の誤り指数と同じになります。
  • min-cache-miss-period: キャッシュミスがキャッシュの容量が拡大されたとシグナル送信すべき間隔を指定します。キャッシュが拡大されるまで許容される最大の誤り指数と同じになります。
  • cache-load-factor: キャッシュ容量を縮小/拡大する因数を指定します。因数は 1 未満にしてください。キャッシュが縮小される場合、容量が削減されるので bean がキャッシュする容量の現在の割合は cache-load-factor 値と同等になります。 キャッシュが拡大される場合、 新しい容量は current-capacity * 1/cache-load-factor として確定されます。実際の拡大因数はキャッシュミス数に基づく内部アルゴリズムに応じて 2 まで上げることができます。キャッシュミス率が高いほど実際の拡大因数は 2 に近くなります。
LRUStatefulContextCachePolicy は残りの子要素にも対応しています。
  • remover-period: remover タスクを実行する間隔を秒単位で指定します。 remover タスクは max-bean-life 秒を超える間隔でアクセスされていない非活性化された bean を削除します。このタスクはユーザーにより削除されなかったステートフルセッション bean で非活性化ストアがいっぱいになってしまわないようにします。
  • max-bean-life: bean がアクティブでない状態で存在できる最大期間を秒単位で指定します。この期間を超えると、bean は非活性化ストアから削除されます。
別のキャッシュポリシー実装は org.jboss.ejb.plugins.NoPassivationCachePolicy クラスで、これは単にインスタンスの非活性化を行いません。明示的に削除しない限りインスタンスを破棄することのないインメモリの HashMap 実装を使用します。このクラスはいずれの cache-policy-conf 設定要素もサポートしません。
29.3.1.3.12. persistence-manager 要素
persistence-manager 要素の値は永続管理実装の完全修飾クラス名を指定します。実装タイプは EJB のタイプに依存します。ステートフルセッション bean の場合は org.jboss.ejb.StatefulSessionPersistenceManager インターフェースの実装、そして BMP エンティティ bean の場合は、org.jboss.ejb.EntityPersistenceManager インターフェースの実装でなければならず、CMP エンティティ bean の場合は org.jboss.ejb.EntityPersistenceStore インターフェースの実装でなければなりません。
29.3.1.3.13. web-class-loader 要素
web-class-loader 要素は、WebService MBean と併用する org.jboss.web.WebClassLoader のサブクラスを指定し、デプロイされた ear、EJB JAR および WAR から動的にリソースとクラスをローディングができるようにします。WebClassLoaderContainer に関連づけられ、その親として org.jboss.mx.loading.UnifiedClassLoader を持つ必要があります。getURLs() メソッドをオーバーライドし、ローカルのローディングに使用するものとは別のリモートローディング用の URL セットを返します。
WebClassLoader には、サブクラスによりオーバーライドされるはずのメソッドが2つあります。そのメソッドは、getKey()getBytes() です。2 番目のメソッドはこの実装では空命令で、iiop モジュールで使用されるクラスローダーなどのように、バイトコード生成機能がついたサブクラスにより上書きされるはずです。
WebClassLoader サブクラスは WebClassLoader(ObjectName containerName, UnifiedClassLoader parent) コンストラクターと同じ署名を持つコンストラクターを持っていなければなりません。
29.3.1.3.14. locking-policy 要素
locking-policy 要素は、利用する EJB ロック実装の完全修飾クラス名を渡します。このクラスは org.jboss.ejb.BeanLock インターフェースを実装しなければなりません。現在の JBoss バージョンには次が含まれます。
  • org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock: この実装は、公平な FIFO キューでトランザクションロックが開放されるのを待機するスレッドを格納します。トランザクション以外のスレッドもこの待機キューに置かれます。このクラスはキューから次の待機トランザクションをポップしてそのトランザクションに関連づけられ待機中のスレッドにのみ通知します。QueuedPessimisticEJBLock は標準設定で使用される現在のデフォルトになります。
  • org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLockNoADE: デッドロック検出が無効になっている点以外は QueuedPessimisticEJBLock と同じ動作となります。
  • org.jboss.ejb.plugins.lock.SimpleReadWriteEJBLock: このロックにより同時に複数の読み取りロックができるようになります。ライターがこのロックを要求すると、それ以降、トランザクションに読み取りロックをまだ持たない読み取りロックのリクエストは、ライターがすべて終了するまでブロックされます。その後、待機中のリーダーはすべて (再入可能設定/methodLock に従い) 同時に開始します。プロモートするリーダーは、他の待機中のライターよりも先に、書き込みロックをまず試行します。プロモート中のリーダーが存在する場合、矛盾読み取り例外がスローされます。当然、ライターは書き込みロックを得る前にすべての読み取りロックが解放されるのを待たなければなりません。
  • org.jboss.ejb.plugins.lock.NoLock: トランザクションコンテナーの設定ごとにインスタンスとともに使用されるアンチロッキングポリシーです。
ロック機能とデッドロック検出については 「エンティティ bean のロックとデッドロックの検出」 で詳細に説明します。
29.3.1.3.15. commit-option と optiond-refresh-rate 要素
commit-option 値は EJB エンティティ bean の永続ストレージコミットオプションを指定します。ABCD のいずれかにならなければなりません。
  • A: コンテナーがトランザクション間の bean のステータスをキャッシュします。このオプションはコンテナーが永続ストアにアクセスしている唯一のユーザーであると仮定しています。この仮定により、必要な場合に限ってのみコンテナーが永続ストレージからのインメモリステータスを同期できるようになります。見つかった bean で最初のビジネスメソッドが実行される前か、bean が非活性化され別のビジネスメソッドにサービスを提供するため再度アクティブにされた後に、同期が行われます。この動作はビジネスメソッドがトランザクションコンテキスト内で実行されるかどうかには依存しません。
  • B: このコンテナーはトランザクション間の bean のステータスをキャッシュします。ただし、オプション A とは異なり、このコンテナーは永続ストアへ独占的にアクセスするとの仮定は行いません。したがって、コンテナーは各トランザクション最初にインメモリのステータスを同期します。このため、トランザクションコンテキストの外側で実行しているビジネスメソッド (トランザクション属性が Never、NotSupported または Supports) はキャッシュされた (また無効である可能性がある) bean のステータスにアクセスしますが、トランザクションコンテキスト内で実行しているビジネスメソッドにとってコンテナーが bean をキャッシュしてもあまり役には立ちません。
  • C: コンテナーは bean インスタンスをキャッシュしません。インメモリのステータスは各トランザクションの起動時に同期されなければなりません。トランザクションの外側で実行しているビジネスメソッドの場合、同期はいまだ実行されますが ejbLoad が呼び出し側と同じトランザクションコンテキスト内で実行します。
  • D: EJB 仕様には記載されていない JBoss 固有のコミットオプションです。オプション A のようにトランザクション間で bean のステータスがキャッシュされる遅延読み取りスキームですが、ステータスが定期的に永続ストアのステータスと再同期されます。再ロードの間隔はデフォルトで 30 秒ですが、optiond-refresh-rate 要素を使って設定することができます。
29.3.1.3.16. security-domain 要素
security-domain 要素は org.jboss.security.AuthenticationManagerorg.jboss.security.RealmMapping のインターフェースを実装するオブジェクトの JNDI 名を指定します。特定のデプロイメントの EJB すべてが同じ方法でセキュリティーを保てるように、jboss root 要素の下にある security-domain を指定する方がより一般的となります。しかし、各 bean 設定に対してセキュリティドメインを設定することもできます。
29.3.1.3.17. cluster-config
cluster-config 要素によりコンテナー設定を使用するすべての EJB に対してクラスター固有の設定を指定することができるようになります。クラスター設定の指定はコンテナー設定レベルか個別の EJB デプロイメントレベルで行うことができます。
  • partition-name: partition-name 要素は、クラスタリング情報の交換にコンテナーが使用する org.jboss.ha.framework.interfaces.HAPartition インターフェースを検索する場所を指示します。これは HAPartition がバインドされる場所の完全 JNDI 名ではなく、目的のクラスターを管理している ClusterPartitionMBean サービスの PartitionName 属性に該当するはずです。実際の HAPartition バインディングの JNDI 名は partition-name 値に /HASessionState/ を追加した形式となります。デフォルト値は DefaultPartition です。
  • home-load-balance-policy: home-load-balance-policy 要素はホームプロキシで出された呼び出しの負荷分散に使用する Java クラス名を指示します。このクラスは org.jboss.ha.framework.interface.LoadBalancePolicy インターフェースを実装しなければなりません。 デフォルトポリシーは org.jboss.ha.framework.interfaces.RoundRobin になります。
  • bean-load-balance-policy: bean-load-balance-policy 要素は bean プロキシで呼び出しの負荷分散に使用する java クラス名を指示します。このクラスは org.jboss.ha.framework.interface.LoadBalancePolicy インターフェースを実装しなければなりません。エンティティ bean およびステートフルセッション bean の場合デフォルトは org.jboss.ha.framework.interfaces.FirstAvailavble で、 ステートレスセッション bean の場合は org.jboss.ha.framework.interfaces.RoundRobin になります。
  • session-state-manager-jndi-name: session-state-manager-jndi-name 要素はクラスター内のステータスセッション管理のバックエンドとしてコンテナーが使用する org.jboss.ha.framework.interfaces.HASessionState の名前を指示します。 partition-name 要素とは異なり、HASessionState 実装がバインドされる場所の JNDI 名になります。デフォルトの場所は /HASessionState/Default です。
29.3.1.3.18. depends 要素
depends 要素はコンテナーまたは EJB が依存するサービスの JMX ObjectName を渡します。その他サービスに対する明示的な依存性を指定すると、必要となるサービス起動後のデプロイメントの順序に依存せずにすみます。