29.2. EJB サーバー側のビュー

EJB 呼び出しはすべて JBoss サーバーがホストする EJB コンテナーに行き着く必要があります。本章では、呼び出しが JBoss サーバー VM に移動し、JMX バスを経由して EJB コンテナーへ行き着く方法を見ていきます。

29.2.1. 分離呼び出し:トランスポートの仲介

MBean サービスの RMI 互換インターフェースを公開するといったコンテキストで分離呼び出しアーキテクチャーについて前述しました。ここでは、分離呼び出しをつかい、EJB コンテナーホームと bean インターフェースをクライアントにどのように公開するか見て行きましょう。呼び出しアーキテクチャーの全体像は、図29.3「トランスポート呼び出しサーバー側のアーキテクチャー」 で提示されています。
トランスポート呼び出しサーバー側のアーキテクチャー

図29.3 トランスポート呼び出しサーバー側のアーキテクチャー

ホームプロキシの各タイプには、呼び出しへのバインドや関連付けられたトランスポートプロトコルがあります。コンテナーには、複数の呼び出しプロトコルが同時に有効になっている場合があります。jboss.xml ファイルでは、invoker-proxy-binding-name は、invoker-proxy-binding/name 要素にマッピングします。container-configuration レベルでは、これは、コンテナーにデプロイされる EJB で使うデフォルトの呼び出しを指定します。bean レベルでは、invoker-bindings が1つ以上の呼び出しを指定し、EJB コンテナー MBean とあわせて利用します。
任意の EJB デプロイメント1つに複数の呼び出しを指定した場合、ホームプロキシに一意の JNDI バインディング先を渡す必要があります。これは、invoker/jndi-name 要素値で指定できます。1つの EJB に対して複数の呼び出しが存在する場合に問題がもう1つあります。それは、EJB が別の bean を呼び出した際に取得したリモートのホームとインターフェースを処理する方法です。クライアントが呼び出しを開始するのに使ったプロキシと、渡されたリモートホームとインターフェースがそれぞれ互換がきくように、このようなインターフェースは、外部の EJB の呼び出しに利用したものと同じ呼び出しを使う必要があります。invoker/ejb-ref 要素を使うと、参照呼び出し型と一致する ejb-ref の参照先 EJB ホームに対し、プロトコルに依存しない ENC ejb-ref からホームプロキシバインディングにマッピングすることができます。
カスタムの JRMPInvoker MBean の使用しセッション bean 向けに圧縮ソケットを圧縮可能にする例は、testsuite のorg.jboss.test.jrmp パッケージにあります。以下の例では、カスタムの JRMPInvoker 設定と、ステートレスセッション bean へのマッピングについて示しています。
<server>
    <mbean code="org.jboss.invocation.jrmp.server.JRMPInvoker"
          name="jboss:service=invoker,type=jrmp,socketType=CompressionSocketFactory">
        <attribute name="RMIObjectPort">4445</attribute>
        <attribute name="RMIClientSocketFactory">
            org.jboss.test.jrmp.ejb.CompressionClientSocketFactory
        </attribute>
        <attribute name="RMIServerSocketFactory">
            org.jboss.test.jrmp.ejb.CompressionServerSocketFactory
        </attribute>
</mbean>
                </server>
ここでは、ポート 4445 にバインドし、トランスポートレベルで圧縮ができるようカスタムのソケットファクトリを使用するように、デフォルトの JRMPInvoker がカスタマイズされています。
<?xml version="1.0"?>
<!DOCTYPE jboss PUBLIC
          "-//JBoss//DTD JBOSS 3.2//EN"
          "http://www.jboss.org/j2ee/dtd/jboss_3_2.dtd">
<!-- The jboss.xml descriptor for the jrmp-comp.jar ejb unit -->
<jboss>
    <enterprise-beans>
        <session>
            <ejb-name>StatelessSession</ejb-name>
            <configuration-name>Standard Stateless SessionBean</configuration-name>
            <invoker-bindings>
                <invoker>
                    <invoker-proxy-binding-name>
                        stateless-compression-invoker
                    </invoker-proxy-binding-name>
                    <jndi-name>jrmp-compressed/StatelessSession</jndi-name>
                </invoker>
            </invoker-bindings>
        </session>
    </enterprise-beans>
                    
    <invoker-proxy-bindings>
        <invoker-proxy-binding>
            <name>stateless-compression-invoker</name>
            <invoker-mbean>
                jboss:service=invoker,type=jrmp,socketType=CompressionSocketFactory
            </invoker-mbean>
            <proxy-factory>org.jboss.proxy.ejb.ProxyFactory</proxy-factory>
            <proxy-factory-config>
                <client-interceptors>
                    <home>
                        <interceptor>org.jboss.proxy.ejb.HomeInterceptor</interceptor>
                        <interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
                        <interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
                        <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
                    </home>
                    <bean>
                        <interceptor>
                            org.jboss.proxy.ejb.StatelessSessionInterceptor
                        </interceptor>
                        <interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
                        <interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
                        <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
                    </bean>
                </client-interceptors>
            </proxy-factory-config>
        </invoker-proxy-binding>
    </invoker-proxy-bindings>
</jboss>
StatelessSession EJB invoker-bindings 設定は、stateless-compression-invoker を JNDI 名 jrmp-compressed/StatelessSession の配下にバインドされたホームインターフェースと共に利用するように指定しています。stateless-compression-invoker は、先ほど宣言したカスタムの JRMP 呼び出しにリンクされます。
以下の例 (org.jboss.test.hello testsuite パッケージ) は、HttpInvoker を使い、RMI/HTTP プロトコルを利用できるように、ステートレスセッション bean を設定しています。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss PUBLIC
          "-//JBoss//DTD JBOSS 3.2//EN"
          "http://www.jboss.org/j2ee/dtd/jboss_3_2.dtd">
<jboss>
    <enterprise-beans>
        <session>
            <ejb-name>HelloWorldViaHTTP</ejb-name>
            <jndi-name>helloworld/HelloHTTP</jndi-name>
            <invoker-bindings>
                <invoker>
                    <invoker-proxy-binding-name>
                        stateless-http-invoker
                    </invoker-proxy-binding-name>
                </invoker>
            </invoker-bindings>
        </session>
    </enterprise-beans>
    <invoker-proxy-bindings>
        <!-- A custom invoker for RMI/HTTP -->
        <invoker-proxy-binding>
            <name>stateless-http-invoker</name>
            <invoker-mbean>jboss:service=invoker,type=http</invoker-mbean>
            <proxy-factory>org.jboss.proxy.ejb.ProxyFactory</proxy-factory>
            <proxy-factory-config>
                <client-interceptors>
                    <home>
                        <interceptor>org.jboss.proxy.ejb.HomeInterceptor</interceptor>
                        <interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
                        <interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
                        <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
                    </home>
                    <bean>
                        <interceptor>
                            org.jboss.proxy.ejb.StatelessSessionInterceptor
                        </interceptor>
                        <interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
                        <interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
                        <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
                    </bean>
                </client-interceptors>
            </proxy-factory-config>
        </invoker-proxy-binding>
    </invoker-proxy-bindings>
</jboss>
ここれは、カスタムの stateless-http-invoker という名前の invoker-proxy-binding を定義します。これは、分離呼び出しとしてHttpInvoker MBean を使います。jboss:service=invoker,type=http の名前は、http-invoker.sar/META-INF/jboss-service.xml 記述子にあるように、HttpInvoker MBean のデフォルト名で、このサービス記述子の一部については以下に示しています。
<!-- The HTTP invoker service configuration -->
<mbean code="org.jboss.invocation.http.server.HttpInvoker"
       name="jboss:service=invoker,type=http">
    <!-- Use a URL of the form http://<hostname>:8080/invoker/EJBInvokerServlet
         where <hostname> is InetAddress.getHostname value on which the server
         is running. -->
    <attribute name="InvokerURLPrefix">http://</attribute>
    <attribute name="InvokerURLSuffix">:8080/invoker/EJBInvokerServlet</attribute>
    <attribute name="UseHostName">true</attribute>
</mbean>
クライアントプロキシは、EJB 呼び出しのコンテンツを HttpInvoker サービス設定で指定している EJBInvokerServlet URL に掲載します。