第4回 デプロイしたEJBを使う

EJBコンソーシアム
2005/3/5



主な内容
デプロイされたEJBを使う
EJB参照の定義
EJBの向かう先は?

 本連載では、JBossIDEおよびXDocletを使って、EJBを作成する方法を説明してきました。最終回は、前回「第3回 CMP Entity Beanのメリット」までに作成したEJBをどのように使えばよいを説明し、今後のEJBの進む方向性について紹介しましょう。

デプロイされたEJBを使う

 前回までに、EJBの作成とデプロイを行いました。今回は、そのEJBを使う方法を説明します。ここでは、これまでの連載で作成したBank EJBをServletから使う方法を説明します。

 Bank EJBは、簡単な銀行口座を扱うサービスを実装したStateless Session Beanです。Bank EJBは、以下のような仕様で、JBoss Serverにデプロイされています。

項目 内容
Home Interface sample.BankHome
Remote Interface sample.Bank
JNDI名 ejb/sample/Bank

 J2EEアプリケーションサーバにデプロイされたEJBへは、JNDIリポジトリを通してアクセスできます。具体的には、JNDIレポジトリからEJBのホームオブジェクト (ホームインターフェイスを実装したコンテナ管理のオブジェクト) を検索し、ホームオブジェクトのメソッドからEJBオブジェクトを生成・取得することによって、EJBオブジェクトにアクセスします。EJBのホームオブジェクトを取得する際のキーになるのがEJBに付けられたJNDI名です。以下で、この手順についてコードを通して説明します。

int balance = 0;
try {
    Hashtable env = new Hashtable();
    InitialContext ctx = new InitialContext(env); //(1)
    BankHome home =
      (BankHome)PortableRemoteObject.narrow(
        ctx.lookup("ejb/sample/Bank"),
        BankHome.class); // (2)
    Bank bank = home.create(); // (3)
    balance = bank.balance(accountNumber); // (4)
    bank.remove(); // (5)
} catch (NamingException ne) {
    ne.printStackTrace();
} catch (CreateException ce) {
    ce.printStackTrace();
} catch (RemoveException re) {
    re.printStackTrace();
}

 初めにInitialContextを作成します(1)。次に、JNDIレポジトリからEJBのJNDI名を指定して、EJBのホームオブジェクトを取得しています(2)。そして、ホームオブジェクトのメソッドを呼び出して、EJBオブジェクトを取得します(3)。そのEJBオブジェクトのメソッドを呼び出します(4)。最後にEJBオブジェクトのremoveメソッドを呼び出します(5)

 ここで呼び出したEJBはStateless Session Beanなので、(3)および(5)での処理では、実際にはEJBオブジェクトが作成・削除されるのではなく、EJBオブジェクトへの参照の取得・開放が行われます。上の例では、呼び出し元のコンポーネントから同じJ2EEアプリケーションサーバ上で動いているEJBを呼び出しているため、ここでは、InitialContext作成時にenv変数で引数として与えているHashtableに何も値を入れていませんが、ほかのサーバで動いているEJBにアクセスする際にここにそこへのアクセスを提供するネームサービスのURLを指定するなど、どのようにネームサービスへアクセスするかを指定することができます。

EJB参照の定義

 このコードでは、EJBを検索する際に、そのJNDI名などをコード中に記述しています。しかし、アプリケーションサーバによっては異なる名前空間にデプロイされたり、後で構成を変えてJNDI名が変わってしまったりすることがあります。このような場合、JNDI名などの設定情報がハードコードされていると柔軟に対応することが難しくなります。J2EEでは、これを解決するために、EJB参照という仕組みを用意しています。EJB参照の仕組みでは、デプロイメントディスクリプタにEJB参照を定義し、アプリケーション内からはEJBがjava:comp/env以下の名前空間にあるものとして扱い、ここで定義された名前と実際に使用するEJBの結び付けをデプロイ時に行います。例えば、サーブレットなどのWebコンポーネントからEJBを使う場合は、web.xmlに以下のようなEJB参照の定義を行います。

<web-app>
  …
  <ejb-ref>
    <ejb-ref-name>ejb/Bank</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <home>sample.BankHome</home>
    <remote>sample.Bank</remote>
  </ejb-ref>
</web-app>

 上記の例では、WebコンポーネントからこのEJBに対して、java:comp/env/ejb/Bankという名前で参照できます。

 そして、デプロイ時にEJB参照を実際のEJBと結び付けます。JBoss Serverでは、JBoss Server用のデプロイメントディスクリプタにどのように結び付けるかを記述します。Webコンテナで使用する際には、jboss-web.xmlに以下のように記述します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.3//EN" "http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd">
<jboss-web>
  <ejb-ref>
    <ejb-ref-name>ejb/Bank</ejb-ref-name>
    <jndi-name>ejb/sample/Bank</jndi-name>
  </ejb-ref>
</jboss-web>

 ここでは、web.xmlの中でejb-ref-name要素にejb/Bankという名前で定義されているEJB参照に対して、同じサーバにejb/sample/BankというJNDI名でデプロイされているEJBを割り当てています。代わりに、jnp://<サーバ名>/<JNDI名>のように指定することによって、ほかのJBoss Serverで動いているEJBを割り当てることもできます。

 これらの設定を、XDocletを用いて自動生成することができます。たとえば、以下のようにサーブレットなどのWebコンポーネントのクラスレベルコメントにXDocletコメントを記述します。

/**
 * @web.servlet name = "Sample" display-name = "Sample"
 * @web.servlet-mapping url-pattern="/sample"
 * @web.ejb-ref name = "ejb/Bank"
 *              home = "sample.BankHome"
 *              remote = "sample.Bank"
 *              type = "Session"
 * @jboss.ejb-ref-jndi jndi-name = "ejb/sample/Bank"
 *                      ref-name = "ejb/Bank"
*/
public class SampleServlet extends HttpServlet {

 ここでは、@web.ejb-ref要素を用いて、web.xmlにEJB参照を作成し、@jboss.ejb-ref-jndi要素を用いて、jboss-web.xmlにその参照とEJBの結び付けを作成しています。

EJBの向かう先は?

 ここまでで、XDocletを用いてEJBのBean実装ファイルに少しの付加情報(メタデータ)を加えて、各種インターフェイスやデプロイメントディスクリプタを自動生成する方法を説明しました。ここでは、これらのファイルについて特に意識せずにEJBを作成することができたと思います。

 一方、最新のJavaの開発環境、JDK 5.0では、Javaのソースコードにメタデータを加えて付属するファイルなどを自動生成する仕組みであるアノテーションがサポートされました。アノテーションでは、ソースコード中に@を用いてメタデータを記述します。

 JDK 5.0をベースにしたJ2EEの仕様はまだ確定していませんが、J2EE 5.0に含まれるEJB 3.0の仕様に関して、Early Draftが公開されていますので、その動向を探ることができます。EJB 3.0の特徴のひとつに、アノテーションを用いてEJBを作成する仕組みが検討されています。これによって、いままでのEJBで必要とされていた各種インターフェイスやデプロイメントディスクリプタが必要なくなる方針が示されています。Early Draftは以下のページで公開されています。

 現状では、EJB 3.0の仕様は確定していませんが、JBossから現状のEJB 3.0のEarly Draftで示されているプログラミングモデルを先取りした環境が提供されています。これに関する情報は、以下のURLのページで提供されています。EJBの新しい流れを体験してみたい方は参照ください。

 しかし、現状ではまだJ2EE 5.0の仕様も確定していませんし、それをアプリケーションサーバがサポートするのはまだ先だと思います。そこで、現状で使用できるXDocletを使って、メタデータを用いたEJBプログラミングに備えることはいいアイデアではないでしょうか?

筆者プロフィール

鷲尾典俊
EJBコンソーシアム オープンソース研究会 JBossチーム リーダー(日立ソフトウェアエンジニアリング株式会社 インターネットビジネス部)

河村嘉之
EJBコンソーシアム オープンソース研究会 副主査(日立ソフトウェアエンジニアリング株式会社 研究部)


【筆者あとがき 】
EJBコンソーシアムでは、オープンソースプロダクトを題材にJ2EE技術者のすそ野を広げる目的で、J2EEオープンソース研究会を立ち上げ、第1期としてJBossとJUnitに関する教材を作成いたしました。なお、この原稿はEJBコンソーシアムJ2EEオープンソース研究会JBossチームの成果を基に書かれています。このチームの成果は、以下の各社の皆さまの努力によるものです。

 川鉄情報システム株式会社
 株式会社電通国際情報サービス
 株式会社トスコ
 日立ソフトウェアエンジニアリング株式会社
 富士通株式会社
 株式会社豆蔵




Java Solution全記事一覧



Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間