JRun で EJB をコーディングする場合、コーディングの他にデプロイやクライアントアクセスについても考慮する必要があります。
javax.ejb.EJBHome
を拡張し、ローカルホームインターフェイスはjavax.ejb.EJBLocalHome
を拡張します。
javax.ejb.EJBObject
を拡張し、ローカルコンポーネントインターフェイスは javax.ejb.EJBLocalObject
を拡張します。javax.ejb.SessionBean
を実装し、エンティティ bean は javax.ejb.EntityBean
を実装します。jrun-
ejb-jar.xml ファイルは、JRun 特有の EJB コンテナ情報の他に、EJB 2.0 CMP エンティティ bean のパーシスタンス情報を定義しますメモ: 1 つの EJB に対して、リモートとローカルの両方のインターフェイスを有効にできます。ただし、この用法は一般的ではないのでお勧めしません。
J2EE 互換のアプリケーションサーバとして、EJB 仕様に記述されている既存の bean をデプロイすることができます。また、JRun は EJB を開始するにあたって次の方法をサポートします。
XDoclet
サービスが EJB ディレクトリに対して有効で、XDoclet スタイルのコメントを使用して bean 実装クラスをコーディングした場合、JRun はインターフェイスディスクリプタおよびデプロイメントディスクリプタを生成します。詳細については、 「EJB と XDoclet」 を参照してください。
この章では、EJB の一般的なコーディング例を多数く取り上げていきます。XDoclet など JRun 特有の機能についても説明します。EJB プログラミングの詳細については、EJB 2.0 を解説している業界紙を参照してください。このマニュアルの序章にはこれらの本のリストが記載されています。
JRun の自動的なデプロイは、開発サイクル時における開発処理を簡素化します。JRun サーバの jrun.xml ファイルで DeoplyService の deployDirectory
属性を 1 つ以上指定している場合は、自動デプロイが有効になります
JRun サーバには、オートデプロイディレクトリが 1 つ以上存在する場合としない場合があります。デフォルトでは、各 JRun サーバのルートディレクトリに含まれるすべてのディレクトリでオートデプロイが有効です。
サーバの起動時、EJB ディレクトリとオートデプロイディレクトリに含まれるEJB JAR ファイルが、JRun によって自動的にデプロイされます。ディレクトリまたは JAR ファイルには、有効な META-INF/ejb-jar.xml ファイルの他に、コンパイル済みのインターフェイスや実装が含まれている必要があります。ejb-jar.xml ファイルや jrun-ejb-jar.xml ファイルを変更した場合は、JRun はホットデプロイを使用して、EJB コンテナに再デプロイします。
JRun では、自動デプロイされた EAR ファイルまたはエンタープライズアプリケーションのディレクトリで見つかった EJB も自動的にデプロイされます。EAR ファイルで使用する場合は、web.xml ファイルの ejb-ref
要素を使用してサーブレットから EJB へのアクセスを定義します。
EJB クライアントでは、次のようなさまざまな形式が使用されます。
コンパイル済みの EJB インターフェイスがクライアントのクラスパスに存在する必要があります。サーブレットの場合は、このインターフェイスが、WEB-INF/classes (JAR ファイル内ではない)、WEB-INF/lib (JAR ファイルの一部として)、または jrun_server/SERVER-INF/lib (JAR ファイルの一部として) に存在することがあります。)
メモ: リモート Java クライアントは、EJB にアクセスするときに、コマンドラインでセキュリティポリシーファイルを指定する必要があります。たとえば、次のコマンドラインを使用します。
java -Djava.security.policy=<JRun のルートディレクトリ>/lib/jrun.policy MyEJBClient
EJB クライアントでは、EJB のホームオブジェクトとリモートオブジェクトへのアクセスに JNDI (Java Naming and Directory Interface:Java ネーミングディレクトリインターフェイス) が使用されます。EJB にアクセスするには、次のようにInitialContext.lookup
メソッドを実行すると、クライアントはホームオブジェクトを探します。
jndi-name
要素 (これはデフォルトで ejb-jar.xml ファイルの ejb-name
要素になります) を使用して検索を実行します。
jndi-name
の値を使用できます。しかしデプロイメントディスクリプタで ejb-ref
要素や ejb-local-ref
要素を定義し、J2EE ENC (Environment Naming Context) を使用して EJB のホームインターフェイスを検索する方法もあります。J2EE ENC は、java:comp/env のルート下にすべてのリファレンス名をバインドします。たとえば、web.xml で、ejb-ref
を ejb/Orders のために定義した場合、サーブレットクライアントは java:comp/env/ejb/Orders で InitialContext
の検索を実行できます。このテクニックを使用すると、最も移植しやすいクライアントコードが作成できます。詳細については、 「ローカル EJB」 を参照してください。
クライアントコードは、リモートオブジェクトやローカルオブジェクトを通じて EJB メソッドを呼び出します。
Swing アプリケーションのようなリモートクライアント、他の JRun サーバ上のサーブレット、他の JRun サーバ上の EJB では、次の例に示すように、InitialContext
コンストラクタにプロパティを渡して bean を検索します。
...
try { // 1: // コンテキストを取得します。 Properties props = new Properties(); // サーバの SERVER-INF/jndi.properties ファイルにある // java.naming.factory.initial プロパティと比較します。 props.put(Context.INITIAL_CONTEXT_FACTORY, "jrun.naming.JRunContextFactory"); // サーバの SERVER-INF/jndi.properties ファイルにある // java.naming.provider.url のプロパティと比較します。 // コンマ区切りのリストも使用できます。 props.put(Context.PROVIDER_URL, "localhost:2918"); Context ctx = new InitialContext(props); // 2: 特定の EJBHome を検索して絞り込みます。 // java:Simple の場合もあります。 Object o = ctx.lookup("Simple"); SimpleHome home = (SimpleHome) PortableRemoteObject.narrow(o, SimpleHome.class); // 3: 特定の EJBObject を作成します。 Simple test = home.create(); // 4: EJB でメソッドを実行します。 String s = test.getMessage(); // s を使用してテストします。この例ではサーブレットを想定しています。 out.println("<br>EJB Message:" + s); } // try を終了 catch (Exception e) { e.printStackTrace(); } // catch を終了 ...
クラスタで実行するときは、オプションで、PROVIDER_URL
でコンマ区切りのサーバとポートのリストを指定できます。これは、InitialContext
の作成が最初のサーバで失敗した場合に、次のサーバにフェイルオーバーすることで、接続成功に役立ちます。EJB クラスタリングの詳細については、『JRun 管理者ガイド』を参照してください。
サーブレットや他の EJB などのローカルクライアントでは、次の例に示すように、空の InitialContext
オブジェクトを作成して bean を検索します。
...
try { // 1: // コンテキストを取得します。 Context ctx = new InitialContext(); // 2: 特定の EJBHome を検索して絞り込みます。 // java:Simple の場合もあります。 Object o = ctx.lookup("Simple"); // この bean にローカルホームインターフェイスが含まれている場合は、 // PortableRemoteObject.narrow の呼び出しの代わりにキャストを使用します。 SimpleHome home = (SimpleHome) PortableRemoteObject.narrow(o, SimpleHome.class); // 3: 特定の EJBObject を作成します。 Simple test = home.create(); // 4: EJB でメソッドを実行します。 String s = test.getMessage(); ...