AntでEJB開発を効率化現場に活かすJakarta Project(3)

» 2003年02月19日 00時00分 公開
[岡本隆史NTTデータ]

 本稿では、前回「AntでJavaのビルドを簡単にする」のAntの使い方の応用編ということで、Antのタスクとして利用できるコード生成エンジンXDocletを用いてEJBを簡単に生成する方法について解説します。XDocletを利用すると、1つのJavaBeanを作成するだけで、EJBに必要なリモート/ホームインターフェイス、各種配備記述子(以下DD)を自動的に生成できるようになります。XDocletの利用は、EJB開発の効率化、管理の手間の削減に非常に効果があります。EJBの開発の煩雑さに困っている人、EJBを使ってみたいけど、作り方が難しくて使えなかった人は、ぜひ本稿を読んで実践してみてください。

煩雑なEJB開発を楽にしたい

 皆さんは、EJBをどのようにして作成しているでしょうか?筆者が初めてEJBのプログラムを書いたときは、テキストエディタを使ってEJBを作成しました。テキストエディタを使ってEJBのコードを書く作業は、通常のJavaBeanを作成するのに比べると非常に大変です。例えば、オープンソースのアプリケーションサーバJBoss上で動く簡単なCMPを1つ作るのにも、下表のように複数のファイルが必要となります。

ファイル 解説
HelloRemote リモートインターフェイス
HelloHome ホームインターフェイス
HelloCMP CMPエンティティBean本体
ejb-jar.xml EJB用の配備記述子
jboss.xml JBoss用の配備記述子
jbosscmp-jdbc.xml JBoss用の配備記述子(CMP用)
表1 CMPエンティティBeanを作成するのに必要なファイル

 1つのBeanを作成するのに、これだけのファイルが必要になると、開発効率の低下が容易に予想されます。また、これらのファイルは互いに依存しているため、HelloCMPにメソッドを追加した場合、HelloHome/HelloRemoteなども変更する必要があり、メンテナンス性も悪くなります。

 また、CMPエンティティBeanを使うと、SQL文を用いたJDBCによるコーディングを行うことなくデータベースを利用することができるため、開発が楽になるといわれていますが、その話をうのみにしてCMPエンティティBeanを利用して痛い目に遭った方も中にはいらっしゃるのではないでしょうか。

 EJBを利用している現場では、市販のIDEを利用して開発しているケースが多いでしょう。しかし、Java Solutionフォーラムで行った「第5回読者アンケート:IDE/APサーバ/フレームワークの利用状況を総括」を見ると分かるように、Javaの利用者の多くは、テキストエディタを利用してコードを書いているのが現状です。また、たとえIDEを使ったとしても、IDEの機能を適切に使わずにソースコードに直接メソッドを追加しているうちに、ファイルの整合性が取れなくなるということもあります。

 「何で1つのEJBを作成するのに、こんなにたくさんのファイルが必要になるのだろうか?1つのEJBを作成するのに、1つのJavaコードで記述できたら……」とEJBの開発に携わったことのある人なら誰しも一度は思うことでしょう。この「EJB開発者の夢」を実現してくれるのが、今回紹介するXDocletなのです。

XDocletとは?

 XDocletとは、コード生成エンジンであり、Javaのためのアトリビュート指向プログラミングを提供するものです。アトリビュート指向とは、ユーザが特殊なJavaDocタグをコード中に記述することにより、そのコードに対するアトリビュート(属性)を与え、コードの自動生成に対するヒントとします。XDocletはソース中に埋め込まれた属性から、さまざまなファイル(EJBの場合、ホーム/リモートインターフェイス、各種DD)を自動生成します(図1)

図1 XDocletによるコード生成 図1 XDocletによるコード生成

 XDocletを使うことにより、次のような利点があります。

  1. 複数のコードに分散していたソースコードを1つのJavaBeanにまとめることができ、開発の効率化とコードの大幅な削減を行うことができます。XDocletのWebページによると、約85%のコードをXDocletが自動生成してくれると書かれています。

  2. ファイルが1つになったことにより、メンテナンスの手間を大幅に削減します。EJB本体、インターフェイス、DD間の不整合が生じることもありません。

  3. アプリケーションサーバの種類やバージョンの違いによりDDが異なりますが、DDはXDocletが自動的に生成してくれるので、開発者は、アプリケーションサーバごとの違いを意識する必要がありません。また、アプリケーションサーバ固有の設定も、Antの引数やタグのコメントで簡潔に記述できます。

 本稿では、EJBの生成についてのみ解説しますが、XDocletにはWebアプリケーション、hibernate/jdoなどのO-Rマッピング、JMXの開発を支援するタスクが用意されています。

タスク 機能
ejbdoclet EJB開発支援
webdoclet Servlet/JSP開発支援
jdodoclet O-Rマッピング(JDO(*1))開発支援
hibernatedoclet O-Rマッピング(hibernate(*2))開発支援
jmxdoclet JMX開発支援
表2 XDocletで提供されているタスク

*1:Java Data Object。JSR-000012としてJCPで標準化されているO-Rマッピングの標準API。詳細はhttp://access1.sun.com/jdo/を参照。
*2:SourceForgeで開発されているO-Rマッピングツール(http://sourceforge.net/projects/hibernate/

 また、XDocletは拡張性に優れ、コード生成のテンプレートを作成することにより、別のアプリケーション/技術に対応させることができます。拡張性の利点は表2に示すようにさまざまなタスクが提供されていることからもお分かりでしょう。

 なお、XDoclet 1.x系では、このテンプレートにXMLベースで記述されたXDoclet独自の構文を利用していますが、XDoclet 2.0からJakartaのテンプレートエンジンVelocityも利用できるようになります。Velocityはシンプルな構文に強力な機能を備えており、XDocletの拡張性はさらに向上することでしょう。

 XDocletは、Jakartaプロジェクトで開発されているわけではありませんが、すでに述べたようにAnt/Velocityなどと深いかかわりがあります。また、Ant 2.0のproposalディレクトリには、XDocletが含まれており、Ant 2.0からはデフォルトで添付されそうです。

XDocletによるEJB生成

 それでは、実際にAntとXDocletを利用してEJBを作成してみましょう。ここでは、JBossで利用可能なEJBをXDocletを使って作成します。作成するEJBは、メールアドレスと名前をデータベースのテーブルで管理するCMPエンティティBeanで、MemberBeanと命名します。MemberBeanは、フィールドにemailとnameを持ち、emailをプライマリキーとします。また、トランザクションは、特に考慮しないこととします。このMemberBeanクラスのサンプルをリスト1に示します。

リスト1 MemberBean.java
package test.ejb;

import javax.ejb.*;
import java.util.Collection;

/** 
   * EJB全体に対する設定
 * @ejb.bean
 *  type="CMP"             EJBのタイプ
 *  name="Member"          EJBの名前
 *  primkey-field="email"  プライマリキーフィールド
 *  view-type="remote"     ビュータイプ
 * 
 * @ejb.finder             ファインダ
 *  signature="Collection findAll()"
 *  transaction-type="NotSupported"
 * @ejb.persistence
 *  table-name="member"    O-Rマッピングを行うテーブル名
*/
public abstract class MemberBean 
extends BaseEntityBean implements EntityBean {

/**
 * getEmailメソッド(emailフィールド)に対する設定
 *
 * @ejb.interface-method    リモートインターフェイスを生成
 * @ejb.pk-field            このメソッドに対応するフィールドを
 *                          プライマリキーに指定
 * @ejb.persistence データベースのテーブルとのマッピングの指定
 *  column-name="email"     カラム名
 *  sql-type="VARCHAR"      SQLのタイプ
 */
 public abstract String getEmail();

 /**
 * setEmailメソッドに対する設定
 *
 * @ejb.interface-method    リモートインターフェイスを生成
 */
 public abstract void setEmail(String email);

 /**
 * getNameメソッド(nameフィールド)に対する設定
 *
 * @ejb.interface-method   リモートインターフェイスを生成
 * @ejb.persistence        データベースのテーブルとのマッピングの指定
 *  column-name="name"     カラム名
 *  sql-type="VARCHAR"     SQLのタイプ
     */

public abstract String getName();
    /**
     * setNameメソッドに対する設定
     *
     * @ejb.interface-method リモートインターフェイスを生成
     */
   public abstract void setName(String name);

    /**
     * EJBの生成に対する設定
     *
     * @ejb.create-method createメソッドを生成
     */
    public String ejbCreate(String email)
 throws CreateException {
        setEmail(email);
        return null;
    }

}

※赤字部分は注釈であり、実際のリストには含まれません。

注:ここでは、コードを分かりやすくするために、エンティティBeanに共通なメソッドを実装した抽象クラスBaseEntityBeanを用意し、そのクラスを継承してMemberBeanを実装しています。

 XDocletを利用する場合、コメントに埋め込んだタグ(リスト1の青字部分)により、EJBの属性を指定します。この属性は、クラスコメントとメソッドコメントにより、それぞれ次のように指定項目が異なります。

  • クラスコメント
    EJBのタイプ、EJB名、テーブル名、プライマリキーフィールドの指定など、EJB全体にわたる属性を指定します。

  • メソッドコメント
    O-Rマッピングを行うときの、データベースのテーブルのカラムとフィールドの対応付け、そのメソッドに対するリモートインターフェイスを生成するかどうか、createメソッドを生成するかどうかなど、メソッドに対する属性を指定します。

 なお、XDocletのEJB生成に使えるタグについての詳細は、Tag Reference for @ejbサイトをご覧ください。

■Antのビルドファイル

 XDocletのタスクは、初めはAntには含まれていません。提供されていないタスクを利用するには、taskdefタスクを利用して、次のようにタスクを定義する必要があります。

<taskdef name="ejbdoclet"
classname="xdoclet.modules.ejb.EjbDocletTask"
classpathref="class.path"/>

 ここでは、xdoclet.modules.ejb.EjbDocletTaskクラスをejbdocletタスクとして定義します。XDocletに限らず、拡張タスクを利用する場合には、taskdefを利用するので、覚えておくとよいでしょう。定義したejbdocletタスクを利用するには、次のように記述します。

<ejbdoclet
    destdir="${gen-src.dir}" 生成されたコードを出力するディレクトリ
    excludedtags="@version,@author,@todo" 処理対象から外すタグ
    ejbspec="2.0" EJB仕様のバージョン
>


<!-- ソースファイルの指定 -->
<fileset dir="${src.dir}">
    <include name="test/ejb/*Bean.java"/>
</fileset>

<!-- CMPエンティティBean生成 -->
<entitycmp/>

<!-- リモート/ホームインターフェイス生成 -->
<remoteinterface/>
<homeinterface/>

<!-- ejb-jar.xmlの生成 -->
<deploymentdescriptor
    destdir="${meta-inf.dir}" DDを生成するディレクトリ
/>

<!-- JBoss固有のDDの生成 -->
<jboss
    version="3.0" JBossのバージョン
    destdir="${meta-inf.dir}" DDを生成するディレクトリ
/>

</ejbdoclet>

※赤字部分は注釈であり、実際のリストには含まれません。

 さて、実際に、XDocletとJBossを利用して、サンプルプログラムからEJBを生成して利用してみましょう。

インストールと実行

 Antを前回の記事に従い、インストールしておいてください。また、J2SDK(1.4.1_01)、JBoss、XDocletを下記のディレクトリにインストールします。

JBoss C:\jboss-3.2.0RC1_tomcat-4.1.18
XDoclet C:\ xdoclet
XDoclet C:\j2sdk1.4.1_01
注:本稿では、Windowsを対象に記述していますが、パス名を変更すれば、UNIXでも利用可能です。また、ほかのディレクトリにインストールした人は適宜読み替えてください。

●XDocletのインストール
 http://sourceforge.net/project/showfiles.php?group_id=31602から、XDoclet-bin-1.2b2.zipをダウンロードしてください。C:\xdocletディレクトリを作成し、このディレクトリに解凍してください。

●JBossのインストール
 http://sourceforge.net/project/showfiles.php?group_id=22866からjboss-3.2.0RC1_tomcat-4.1.18.zipをダウンロードしてください。ダウンロードしたzipファイルを、C:\ディレクトリにそのまま解凍してください。

 XDocletとJBossのインストールが完了したら、C:\jboss-3.2.0RC1_tomcat-4.1.18ディレクトリ(以下、JBOSS_HOMEと記述)と、C:\XDocletディレクトリにそれぞれのファイルがインストールされていることを確認してください。別のディレクトリにインストールした場合(特にUNIXを利用する方)や、別のバージョンのJBossを利用する方は適宜読み替えてください。

 今回ご紹介したサンプルをここからダウンロードして、C:\ディレクトリに解凍してください。サンプルには、次のファイルが含まれます。

ファイル 説明
build.xml Antのビルドファイル
build.properties プロパティファイル(build.xmlからインクルードされる。JBossをXDocletのパスに設定する)
src/test/ejb/MemberBean.java XDocletで利用するEJBのソースコード
src/TestClient.java テスト用のコード

 もし、XDocletとJBossを上記に指定したディレクトリと別のディレクトリにインストールした場合には、build.propertiesファイルに含まれるjbossとXDocletのルートディレクトリのパスを変更してください。これで準備は完了です。

 さて、Antを使って、EJBを生成してみましょう。C:\XDoclet-sampleディレクトリに移動し、

C:\xdoclet-sample> ant

と実行すると、EJBが生成されます。Antを実行すると、まず、ejbdocletターゲットにより、src/test/ejb/MemberBean.javaにあるMemberBean.javaから次のファイルが生成されます。

build/gen-src/test/ejb/MemberCMP.java CMPエンティティBean本体
build/gen-src/test/ejb/Member.java リモートインターフェイス
build/gen-src/test/ejb/MemberHome.java ホームインターフェイス
build/meta-inf/ejb-jar.xml EJBの標準DD
build/meta-inf/jboss.xml JBoss固有のDD
build/meta-inf/jbosscmp-jdbc.xml JBoss固有のDD(CMP用)

 たった1つのMemberBean.javaからEJBに必要なファイルが次々と生成される様はまるで魔法のようで、まさにハーマイオニーもびっくりです。これらのファイルは、コンパイルされて、dest/xdoclet-sample.jarにEJBのjarファイルとして生成されます。

動作確認

 xdoclet-sample.jarを、JBossをインストールしたディレクトリの下のserver/default/deployディレクトリにコピーし、JBOSS_HOME\bin\run.batファイルを実行(ダブルクリックもしくは、コマンドラインから実行)します。これで、JBossが起動します。

 無事JBossが起動したら、作成したEJBをテストするクライアントを実行してみましょう。c:\xdoclet-samples\build\classesディレクトリに移動し、次のように実行します(ここではJ2SDK 1.4の場合ですが、J2SDK 1.3環境で正しく動作しない場合は、C:\jboss-3.2.0RC1_tomcat-4.1.18\client以下のjarファイルすべてにクラスパスを通してください)。

C:\>cd C:\xdoclet-sample\build\classes
C:\>SET CLASSPATH=C:\jboss-3.2.0RC1_tomcat-4.1.18\client\jbossall-client.jar;


C:\xdoclet-sample\client>java TestClient create okamototk@nttdata.co.jp "Takashi Okamoto" 
[create]
email:okamototk@nttdata.co.jp
name :Takashi Okamoto


C:\xxdoclet-sample\client>java TestClient find okamototk@nttdata.co.jp
[find]
email:okamototk@nttdata.co.jp
name :Takashi Okamoto


C:\xdoclet-sample\client>java TestClient remove okamototk@nttdata.co.jp
[remove]
email:okamototk@nttdata.co.jp
name :Takashi Okamoto

 当然ながら、登録したメンバーは、データベースに永続化されているので、メンバーを削除しない限り、JBossをいったん停止して再起動しても検索できます。

XDocletの柔軟性

 XDocletを利用すると、簡単にEJBを作成できるだけでなく、JavaBeanのタグやejbdocletのオプションを少し変更するだけで、EJBの設定を簡単に変えることができます。ここでは、先ほどのサンプルを基にして、データソースの指定、ローカルEJBの作成、WebLogic用のDDの作成を通して、XDocletの柔軟性を見てみましょう。

■データソースを指定

 サンプルでは、JBossのデフォルトのデータソース(java:/DefaultDS)を利用するようになっていますが、明示的にデータソースを指定するには、次のようにejbdocletタスクにvalueobjectタグを含め、jbossタグにデータソースを指定します。

<!-- Valueオブジェクト生成 -->
<valueobject />

<!-- JBoss固有のDDの生成 -->
<jboss
  version="3.0"
  destdir="${meta-inf.dir}"
  datasource="java:/PostgreSQLDS" データソース名
  datasourceMapping="PostgreSQL" データベースタイプ
/>

注:サンプルでは、Valueオブジェクトを生成しませんが、データソースの設定をするために必要となっています。Valueオブジェクトを生成する場合は、MemberBean.javaで@ejb.value-object name="Member"とします。

■ローカルEJBの作成

 今回は、通常のCMPエンティティBeanを作成しましたが、XDocletを利用すると、EJB 2.0からサポートされたローカルEJBも簡単に作成することができます。クラスタグの下記のview-type

@ejb.bean

...

view-type="remote"
ビュータイプ

を次のようにlocalに変更します。

view-type="local" ビュータイプ

 また、build.xmlの下記の部分

<remoteinterface/>
<homeinterface/>

<localinterface/>
<localhomeinterface/>


とローカルインターフェイスを生成するように変更するだけで、ローカルEJBを作成することができます。生成されるファイルの名前も、Member(リモートインターフェイス)がMemberLocal(ローカルインターフェイス)に、MemberHome(ホームインターフェイス)がMemberLocalHome(ローカルホームインターフェイス)に変わります。

 view-typeをbothにして、リモートEJBの設定とローカルEJBの設定を書くことで、両方のEJBを同時に生成することもできます。

■WebLogic用のDDを作成

 WebLogic用のDDを作成するには、ejbdocletタスク中にjbossタグの代わりにweblogicタグを定義します。

<weblogic
  version="6.1"
  destdir="${samples.meta-inf.dir}"
  datasource="java:/samplesDataSource"
  persistence="weblogic"
/>

 jbossタグとweblogicタグを同時に定義すれば、JBoss用とWebLogic用のDDが生成されるので、2つのアプリケーションサーバに対応したEJBを作成することが可能です。そのほか、WebSphere(websphereタグ)/JOnAS(jonasタグ)/JRun(jrunタグ)などに対応しています。このように簡単にほかのアプリケーションサーバ用のDDを作成することができます。

 ご覧のとおり、XDocletを利用すると、ejbdocletタスクのパラメータやJavaBeanのタグを変更するだけで柔軟にEJBの生成ルールを変えることができます。

まとめ

 今回は、応用編ということで、XDocletを用いたEJBの作成方法についてご紹介しました。XDocletを利用すると、高価なIDEを購入することなく、EJBの開発を簡単に行えるようになります。まさに革命的といってよいでしょう。いままでEJBを敬遠していた方も、XDocletを使って、EJBに触れてみてはいかがでしょうか?

筆者プロフィール

岡本隆史(おかもと たかし)

現在、株式会社NTTデータ 技術開発本部に所属。Webサービス技術の研究開発に携わる。個人では、Debian/GNU Linuxをはじめとしたさまざまなオープンソースプロジェクトにコントリビュートしており、Jakartaでは、プロダクトの国際化/日本語へのローカライズを中心として活動している。



Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。