front cover rational application developer...

54
ibm.com/redbooks Rational Application Developer V7.5 プログラミング・ガイド 14 EJB アプリケーション の開発 Ueli Wahli Miguel Gomes Brian Hainey Ahmed Moharram Juan Pablo Napoli Marco Rohr Java EE 5 を使用した アプリケーションの開発 ローカル・サーバーと リモート・サーバーによる テスト、デバッグ、プロファイル WebSphere サーバーへの アプリケーションの デプロイ Henry Cui Patrick Gan Celso Gonzalez Pinar Ugurlu Lara Ziosi

Upload: others

Post on 24-Aug-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

ibm.com/redbooks

Rational Application Developer V7.5プログラミング・ガイド第 14 章 EJB アプリケーションの開発

Ueli WahliMiguel GomesBrian Hainey

Ahmed MoharramJuan Pablo Napoli

Marco Rohr

Java EE 5 を使用したアプリケーションの開発

ローカル・サーバーとリモート・サーバーによるテスト、デバッグ、プロファイル

WebSphere サーバーへのアプリケーションのデプロイ

Front cover

Henry CuiPatrick Gan

Celso GonzalezPinar Ugurlu

Lara Ziosi

Page 2: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての
Page 3: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

目次

第 14 章 EJB アプリケーションの開発 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1Enterprise JavaBeans の概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

EJB 3.0 仕様. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2EJB 3.0 の簡易モデル. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

メタデータ注釈 ( アノテーション ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3EJB のタイプとその定義. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

ステートレス・セッション EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4EJB 2.x でステートレス・セッション Bean を定義するステップ . . . . . . . . . . . . . . . . . . 4EJB 3.0 でステートレス・セッション Bean を定義するステップ . . . . . . . . . . . . . . . . . . 5ステートフル・セッション EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6ビジネス・インターフェース . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

セッション EJB 開発のベスト・プラクティス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8メッセージ駆動型 EJB. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9Web サービス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9ライフ・サイクル・イベント . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10インターセプター . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11依存性注入(Dependency Injection). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

@EJB 注釈 ( アノテーション ). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13@Resource 注釈 ( アノテーション ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

デプロイメント記述子の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16EJB 3.0 アプリケーション・パッケージ. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17Application Developer v7.5 の EJB フィーチャー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

サンプル・アプリケーションの概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17サンプルの準備 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

必要なソフトウェア . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20EJB 開発機能の有効化. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20EJB プロジェクトの作成と構成. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20EJB プロジェクトの作成. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20JPA エンティティーを EJB プロジェクトで利用可能にする . . . . . . . . . . . . . . . . . . . . . . . . . 23ITSOBANK データベースのセットアップ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24ITSOBANK のデータ・ソースの構成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

Enhanced EAR を使用したデータ・ソースの構成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25EJB アプリケーションの開発 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

セッション・ファサードの実装 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26例外の準備 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26EJBBank セッション Bean の作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26ビジネス・インターフェースの定義 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28セッション Bean の完成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

スケルトン・メソッドの生成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29エンティティー・マネージャーの作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29メソッドの完成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

セッション EJB とエンティティーのテスト . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34サーバーへのアプリケーションのデプロイ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

ユニバーサル・テスト・クライアントを使用したテスト . . . . . . . . . . . . . . . . . . . . . . . . . . . 34テスト用 Web アプリケーションの作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

サンプル Web アプリケーションのテスト . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39テスト・アプリケーションの視覚化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

EJB 3.0 Web アプリケーションの作成. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

目次 i

Page 4: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

RAD75EJBWeb アプリケーションの実装. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41Web アプリケーション・ナビゲーション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41サーブレットとコマンド . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42Java EE の依存関係 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42セッション EJB へのアクセス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42追加機能 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

Web アプリケーションの実行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43クリーンアップ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47リモート・インターフェースの追加 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47EJB アプリケーション交換ファイルの完成. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

その他の情報 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

ii Rational Application Developer V7.5 プログラミング・ガイド

Page 5: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

特記事項

本書は米国 IBM が提供する製品およびサービスについて作成したものです。

本書に記載の製品、サービス、または機能が日本においては提供されていない場合があります。日本で利用可能な製品、サービス、および機能については、日本 IBM の営業担当員にお尋ねください。本書で IBM 製品、プログラム、またはサービスに言及していても、その IBM 製品、プログラム、またはサービスのみが使用可能であることを意味するものではありません。これらに代えて、IBM の知的所有権を侵害することのない、機能的に同等の製品、プログラム、またはサービスを使用することができます。ただし、IBM 以外の製品とプログラムの操作またはサービスの評価および検証は、お客様の責任で行っていただきます。

IBM は、本書に記載されている内容に関して特許権 ( 特許出願中のものを含む ) を保有している場合があります。本書の提供は、お客様にこれらの特許権について実施権を許諾することを意味するものではありません。実施権についてのお問い合わせは、書面にて下記宛先にお送りください。 〒 242-8502神奈川県大和市下鶴間 1623 番 14 号日本アイ・ビー・エム株式会社法務・知的財産知的財産権ライセンス渉外

以下の保証は、国または地域の法律に沿わない場合は、適用されません。IBM およびその直接または間接の子会社は、本書を特定物として現存するままの状態で提供し、商品性の保証、特定目的適合性の保証および法律上の瑕疵担保責任を含むすべての明示もしくは黙示の保証責任または保証条件は適用されないものとします。国または地域によっては、法律の強行規定により、保証責任の制限が禁じられる場合、強行規定の制限を受けるものとします。

この情報には、技術的に不適切な記述や誤植を含む場合があります。本書は定期的に見直され、必要な変更は本書の次版に組み込まれます。IBM は予告なしに、随時、この文書に記載されている製品またはプログラムに対して、改良または変更を行うことがあります。

本書において IBM 以外の Web サイトに言及している場合がありますが、便宜のため記載しただけであり、決してそれらの Web サイトを推奨するものではありません。それらの Web サイトにある資料は、この IBM 製品の資料の一部ではありません。それらの Web サイトは、お客様の責任でご使用ください。

IBM は、お客様が提供するいかなる情報も、お客様に対してなんら義務も負うことのない、自ら適切と信ずる方法で、使用もしくは配布することができるものとします。

IBM 以外の製品に関する情報は、その製品の供給者、出版物、もしくはその他の公に利用可能なソースから入手したものです。IBM は、それらの製品のテストは行っておりません。したがって、他社製品に関する実行性、互換性、またはその他の要求については確証できません。IBM 以外の製品の性能に関する質問は、それらの製品の供給者にお願いします。

本書には、日常の業務処理で用いられるデータや報告書の例が含まれています。より具体性を与えるために、それらの例には、個人、企業、ブランド、あるいは製品などの名前が含まれている場合があります。これらの名称はすべて架空のものであり、名称や住所が類似する企業が実在しているとしても、それは偶然にすぎません。

著作権使用許諾 :

本書には、様々なオペレーティング・プラットフォームでのプログラミング手法を例示するサンプル・アプリケーション・プログラムがソース言語で掲載されています。お客様は、サンプル・プログラムが書かれているオペレーティング・プラットフォームのアプリケーション・プログラミング・インターフェースに準拠したアプリケーション・プログラムの開発、使用、販売、配布を目的として、いかなる形式においても、IBM に対価を支払うことなくこれを複製し、改変し、配布することができます。このサンプル・プログラムは、あらゆる条件下における完全なテストを経ていません。従って IBM は、これらのサンプル・プログラムについて信頼性、利便性もしくは機能性があることをほのめかしたり、保証することはできません。

© Copyright IBM Corp. 2009. All rights reserved. iii

Page 6: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

商標

IBM、IBM ロゴおよび ibm.com は、世界の多くの国で登録された International Business Machines Corps. の商標です。他の製品名およびサービス名等は、それぞれ IBM または各社の商標である場合があります。現時点での IBM の商標リストについては、http://www.ibm.com/legal/copytrade.shtml をご覧ください。

以下は、International Business Machines Corporation の米国およびその他の国における商標です。

CICS®ClearCase®ClearQuest®Cloudscape®DB2 Universal Database™DB2®developerWorks®i5/OS®

IBM®IMS™Informix®Jazz™Lotus®Rational Rose®Rational Unified Process®Rational®

Redbooks®Redbooks ( ロゴ ) ®RequisitePro®RUP®Sametime®WebSphere®z/OS®

以下は、それぞれ各社の商標です。

Adobe、Portable Document Format (PDF) は、Adobe Systems Incorporated の米国およびその他の国における登録商標または商標です。

EJB、Enterprise JavaBeans、J2EE、J2SE、Java、JavaBeans、Javadoc、JavaMail、JavaScript、JavaServer、JDBC、JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての Java 関連の商標およびロゴは、Sun Microsystems, Inc. の米国およびその他の国における商標です。

Excel、Expression、Internet Explorer、Microsoft、PowerPoint、SQL Server、Windows NT、Windows Server、Windows Vista、Windows および Windows ロゴは、Microsoft Corporation の米国およびその他の国における商標です。

Intel Pentium、Intel、Pentium、Intel ( ロゴ )、Intel Inside ( ロゴ )、Intel Centrino ( ロゴ ) は、Intel Corporation または子会社の米国およびその他の国における商標または登録商標です。

UNIX は The Open Group の米国およびその他の国における登録商標です。

Linux は、Linus Torvalds の米国およびその他の国における商標です。

他の会社名、製品名およびサービス名等はそれぞれ各社の商標です。

iv Rational Application Developer V7.5 プログラミング・ガイド

Page 7: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

ëÊ 14 èÕ EJB アプリケーションの開発

この章では、Enterprise JavaBeans (EJB) を紹介し、J2EE プラットフォームでこのようなコンポーネントの作成、保守、およびテストを行う方法について例を挙げて説明します。

エンティティー Bean の開発方法、およびエンティティー Bean とセッション Bean との関係について説明します。次に、サンプル・アプリケーション用に、EJB をフロントエンド Web アプリケーションと統合します。Rational Application Developer を使用した EJB の作成、開発、およびテストを行うための例が記載されています。

この章は、次のセクションで構成されています。

� Enterprise JavaBeans の概要� サンプル・アプリケーションの概要� サンプルの準備� EJB アプリケーションの開発� セッション EJB とエンティティーのテスト� EJB 3.0 Web アプリケーションの作成� その他の情報

この章のサンプル・コードは 7672code\ejb にあります。

14

© Copyright IBM Corp. 2009. All rights reserved. 1

Page 8: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

Enterprise JavaBeans の概要

Enterprise JavaBeans (EJB) は、Java で作成されたサーバー・サイド・コンポーネント・ベースの分散アプリケーションに使用されるアーキテクチャーです。

EJB 3.0 仕様

ここでは、セッション EJB とメッセージ駆動型 EJB について記述している EJB 3.0 仕様について説明します。このセクションは、IBM Redbooks で公開されている、SG24-7611「WebSphere Application Server Version 6.1 Feature Pack for EJB 3.0」 ( 英文 ) の 1 章『Introduction to EJB 3.0』から引用されたものです。

EJB 3.0 の簡易モデル

従来の EJB プログラミング・モデルと新しいモデルの複雑な相違点については、多くの刊行物で解説されています。このため、本書では新しいプログラミング・モデルの説明に重点を置きます。EJB 2.x の制限を取り除くため、新しい仕様ではまったく新たな簡易モデルが導入されています。この新しいモデルの主な機能は以下のとおりです。

� エンティティー EJB が JPA エンティティーになりました。これは、通常のビジネス・インターフェース (POJI) を公開する POJO (Plain Old Java Object) です。ホーム・インターフェースは必要ありません。

� 特定のインターフェースおよびデプロイメント記述子が不要になりました ( デプロイメント記述子情報の代わりに注釈 ( アノテーション ) を使用できます )。

� EJB 2.x エンティティー Bean に優先する、まったく新しいパーシステンシー・モデル (JPA 標準ベース ) が使用されます (「第 12 章 : Persistence using the Java Persistence API (JPA)」を参照 )。

� インターセプター機能によって、ビジネス・メソッドの呼び出し時またはライフ・サイクル・イベントの発生時にユーザー・メソッドを呼び出します。

� 可能な限り、デフォルト値が使用されます (「例外による構成」手法 )。

� チェック例外を使用する際の要件が削減されています。

図 14-1 は、EJB 3.0 仕様の導入により、J2EE 1.4 のモデルが完全に作り直されていることを示しています。

2 Rational Application Developer V7.5 プログラミング・ガイド

Page 9: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

図 14-1 EJB 3.0 のアーキテクチャー

以下のセクションでは、次の機能について紹介します。

メタデータ注釈 ( アノテーション ) EJB 3.0 では、Java SE 5.0 の一部としてメタデータ注釈 ( アノテーション ) が使用されます。

注釈 ( アノテーション ) は XDoclet に似ています。つまり、強力なオープン・ソース・フレームワークにより拡張可能な、メタデータ駆動型の、属性指向のフレームワークを使用して、Java コードや XML デプロイメント記述子を生成します。ただし注釈 ( アノテーション ) は、プリコンパイルが必要な XDoclet とは異なり、コンパイル時に Java コンパイラーによって構文チェックが行われ、場合によってはクラスにコンパイルされます。

特別な注釈 ( アノテーション ) を指定することで、開発者は EJB コンポーネントである POJO クラスを作成できます。

以下のセクションでは、注釈 ( アノテーション ) と EJB 3.0 を共に使用する も一般的な方法を解説します。

EJB のタイプとその定義

EJB 3.0 には、2 つのタイプの EJB が存在します。

� セッション Bean ( ステートレスおよびステートフル )� メッセージ駆動型 Bean

SessionBean

BusinessLogic Tier

Session BeansMessage

Driven BeansMessage

Driven Beans

Persistency Tier

MessageDriven Beans

JPAEntities

EntityManager

EJB Container

JMS

JTA

JNDI

JDBC

RMI-IIOP

Threating

Pooling

Security

JMSProvider

RDBMS

RemoteClient

LocalClient

Application Server

Web Services

RemoteClient

注 : EJB2.x のエンティティー Bean は JPA エンティティーに置き換えられています。詳しくは、「第 12 章 : Persistence using the Java Persistence API (JPA)」を参照してください。

第 14 章 EJB アプリケーションの開発 3

Page 10: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

次に、注釈 ( アノテーション ) を使用してセッション Bean と MDB Bean を宣言する方法について説明します。

ステートレス・セッション EJBステートレス・セッション EJB は常に、クライアント・コードで EJB を呼び出す際に実行されるタスクをモデル化するために使用されてきました。これらの EJB は、ビジネス・ロジックまたはシステムの規則を実装し、Bean 間のアクティビティーを調整します。例として、口座間の送金を行うバンキング・サービスなどが挙げられます。

一般に、ステートレス・セッション Bean は単一の要求のビジネス・ロジックに使用されます。そのため、複数の呼び出し間でクライアント固有の状態を保持することはできません。

ステートレス・セッション Bean は会話型状態を維持しないので、クライアントと EJB 間で交換されるデータはすべて、ビジネス・メソッド・インターフェースで宣言された、入力パラメーターまたは戻り値のいずれかとして受け渡しする必要があります。

EJB 3.0 仕様で行われた簡素化をより適切に理解するため、EJB 2.x と 3.0 の定義に関するステップを比較してみましょう。

EJB 2.x でステートレス・セッション Bean を定義するステップ EJB 2.x でステートレス・セッション EJB を定義するには、次のコンポーネントを定義する必要があります。

� EJB コンポーネント・インターフェース : EJB クライアントが Bean の機能へのアクセスを取得する場合に使用します。ここで、ビジネス・メソッドが定義されます。コンポーネント・インターフェースは EJB オブジェクトと呼ばれます。コンポーネント・インターフェースには、以下の 2 つのタイプがあります ( 図 14-2)。

– リモート・コンポーネント (EJBObject) — リモート・クライアントが RMI-IIOP プロトコルを介して EJB にアクセスする場合に使用します。

– ローカル・コンポーネント (EJBLocalObject) — ローカル・クライアント ( 同じ JVM 内で実行されるクライアント ) が EJB にアクセスする場合に使用します。

図 14-2 EJB 2.x コンポーネント・インターフェース

� EJB ホーム・インターフェース : EJB クライアントが Bean へのアクセスを取得する場合に使用します。ここには、作成、検索、または除去の Bean のライフ・サイクル・メソッドが含まれます。ホーム・インターフェースは EJB ホームと

4 Rational Application Developer V7.5 プログラミング・ガイド

Page 11: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

呼ばれます。EJBHome オブジェクトは、ホーム・インターフェースを実装するオブジェクトで、EJBObject の場合のように、デプロイ時にコンテナー・ツールから生成されます。ここには、コンテナー固有のコードが含まれます。 起動時に、EJB コンテナーは、デプロイ済みのエンタープライズ Bean の EJBHome オブジェクトのインスタンスを作成し、ネーム・サービスにホームを登録します。EJB クライアントは、Java Naming and Directory Interface (JNDI) を使用して EJBHome オブジェクトにアクセスします。ホーム・インターフェースには、以下の 2 つのタイプがあります ( 図 14-3)。

– リモート・インターフェース (EJBHome) — リモート・クライアントが RMI-IIOP プロトコルを介して EJB にアクセスする場合に使用します。

– ローカル・インターフェース (EJBLocalHome) — ローカル・クライアント (同じ JVM 内で実行されるクライアント)が EJB にアクセスする場合に使用します。

図 14-3 EJB 2.x ホーム・インターフェース

� EJB Bean クラス : 実際の Bean ビジネス・ロジックがすべて含まれています。ビジネス・ロジックの実装を提供するクラスです。この Bean クラス内のメソッドは、コンポーネント・インターフェースとホーム・インターフェース内のメソッドに関連します。

EJB 3.0 でステートレス・セッション Bean を定義するステップEJB 3.0 仕様に従ってステートレス・セッション Bean を宣言するには、単に POJO を定義するだけです。

@Statelesspublic class MyFirstSessionBean implements MyBusinessInterface {

// business methods according to MyBusinessInterface.....

}

この手法の新しい革新的な側面について解説します。

� MyFirstSessionBean は POJO であり、従来の普通の POJI (Plain Old Java Interface)、この場合は MyBusinessInterface を公開します。このインターフェースを使用すると、クライアントで EJB ビジネス・メソッドを呼び出すことができます。

� @Stateless 注釈 ( アノテーション ) は、コンテナーに対して、指定された Bean がステートレス・セッション Bean であり、適切なライフ・サイクルとランタイム・セマンティクスを実行できることを示しています。

第 14 章 EJB アプリケーションの開発 5

Page 12: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

� デフォルトでは、このセッション Bean はローカル・インターフェースを通じてアクセスされます。

セッション EJB のセットアップに必要な作業は以上です。拡張する特別なクラスや、実装するインターフェースはありません。EJB 3.0 の非常に単純なモデルを 図 14-4 に示します。

図 14-4 EJB は POJI を公開する POJO

一方、同じ Bean をリモート・インターフェースで公開する場合は、@Remote 注釈 ( アノテーション ) を使用します。

@Remote(MyRemoteBusinessInterface.class)@Statelesspublic class MyBean implements MyRemoteBusinessInterface {

// ejb methods.....

}

ステートフル・セッション EJB一般に、ステートフル・セッション EJB は複数のクライアント要求にまたがるタスクやビジネス・プロセスのモデル化に使用されます。したがって、ステートフル・セッション EJB には個別のクライアントに代わって状態が保持されます。一方クライアントは、ステートフル EJB へのハンドルを格納し、常に同じ EJB インスタンスにアクセスできるようにする必要があります。

ステートフル・セッション EJB の定義や注釈 ( アノテーション ) を使用した POJO の宣言を行うには、既に使用した方法と同じ方法を使用します。

@Statefulpublic class MySecondSessionBean implements MyBusinessStatefulInterface {

// ejb methods.....

}

@Stateful 注釈 ( アノテーション ) は、コンテナーに対して、指定された Bean がステートフル・セッション Bean であり、適切なライフ・サイクルとランタイム・セマンティクスを実行できることを示しています。

ビジネス・インターフェースEJB はローカルとリモートのいずれのクライアントからもアクセスできるので、必要に応じて異なるビジネス・インターフェースを公開できます。ローカルおよびリ

ヒント : セッション Bean に実装されるインターフェースが 1 つだけの場合、@Remote のみをコーディング ( クラス名なし ) することもできます。

MyFirstSessionBean

MyBusinessInterface

implements

6 Rational Application Developer V7.5 プログラミング・ガイド

Page 13: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

モート・インターフェースの両方に共通の振る舞いは、図 14-5 で示されているようにスーパー・インターフェース内に置くことをお勧めします。

次の側面について必ず考慮してください。

� ビジネス・インターフェースを、ローカルとリモート両方の Bean のビジネス・インターフェースにすることはできません。

� Bean クラスにインターフェースが 1 つしか実装されていない場合、そのインターフェースは Bean のビジネス・インターフェースと見なされます。ビジネス・インターフェースは、@Remote 注釈 ( アノテーション ) またはデプロイメント記述子を使用してリモート・ビジネス・インターフェースとして指定されない限り、ローカル・インターフェース になります。

この結果、ローカルおよびリモートのクライアントに対してどのメソッドをアクセス可能にするかを決定できるため、設計フェーズでの柔軟性を高めることができます。

図 14-5 EJB コンポーネント・インターフェースの構成方法

これらのガイドラインを使用して、次のように 1 つ目の EJB のリファクタリングを行います。

@Statelesspublic class MyFirstSessionBean

implements MyLocalBusinessInterface, MyRemoteBusinessInterface {

// implementation of methods declared in MyLocalBusinessInterface....

// implementation of methods declared in MyRemoteBusinessInterface....

}

MyLocalBusinessInterface は、@Local または @Remote 注釈 ( アノテーション ) と共にインターフェースとして宣言されます。

@Localpublic interface MyLocalBusinessInterface

extends MyAbstractBusinessInterface {

// methods declared in MyLocalBusinessInterface......

}\

MyFirstSessionBean

MyLocalBusinessInterface

implements

MyRemoteBusinessInterface

MyAbstractBusinessInterface

extends

第 14 章 EJB アプリケーションの開発 7

Page 14: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

@Remotepublic interface MyRemoteBusinessInterface

extends MyAbstractBusinessInterface {

// methods declared in MyRemoteBusinessInterface......

}

ローカルまたはリモートとして公開されるビジネス・インターフェースを定義する別の手法は、これらのインターフェースを実装する完全なクラスに @Local または @Remote 注釈 ( アノテーション ) を指定することです。

@Stateless@Local(MyLocalBusinessInterface.class)@Remote(MyRemoteBusinessInterface.class)public class MyFirstSessionBean implements MyLocalBusinessInterface, MyRemoteBusinessInterface {

// implementation of methods declared in MyLocalBusinessInterface........

// implementation of methods declared in MyRemoteBusinessInterface........

}

ビジネス・インターフェースには任意の例外を宣言できますが、次の規則を考慮する必要があります。

� RemoteException は使用しないでください。

� コンテナーによってスローされた実行時例外はすべて、EJBException にラップされます。

セッション EJB 開発のベスト・プラクティス

EJB 3.0 開発者は、以下の基本的な規則に準拠する必要があります。

� 各セッション Bean が POJO であること、そのクラスが具象クラスであること ( つまり、abstract や final でないこと )、およびそのクラスに引数がないコンストラクターがあること ( 存在しない場合は、コンパイラーによってデフォルトのコンストラクターが挿入されます )。

� POJO に 低 1 つの POJI を実装すること。「 低」という点に注意してください。ローカルとリモートのクライアントに対して異なるインターフェースを持つことは可能です。

� ビジネス・インターフェースに @Remote 注釈 ( アノテーション ) が付けられている場合、そのインターフェースを使用して渡されるすべての値に java.io.Serializable を実装すること。一般に、宣言されたパラメーターはシリアライズ可能として定義されますが、実際に渡される値がシリアライズ可能である限り、この定義は必要ありません。

� セッション EJB は POJO をサブクラス化できますが、別のセッション EJB をサブクラス化することはできません。

8 Rational Application Developer V7.5 プログラミング・ガイド

Page 15: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

メッセージ駆動型 EJB

メッセージ駆動型 Bean は、J2EE ベースのアプリケーション内で、非同期 JMS メッセージを処理するために使用されます。この Bean は、メッセージの到着時にコンテナーによって呼び出されます。

このように、メッセージ Bean は、EJB を呼び出すためのもう 1 つの対話メカニズムと考えられますが、セッション Bean と異なり、メッセージの受信時に EJB を呼び出すのは、クライアント ( または別の Bean) ではなく、コンテナーです。

EJB 3.0 でメッセージ駆動 Bean を定義するには、次の POJO を宣言します。

@MessageDriven(activationConfig = {@ActivationConfigProperty(propertyName="destinationType",

propertyValue="javax.jms.Queue"),@ActivationConfigProperty(propertyName="destination",

propertyValue="queue/myQueue")})public class MyMessageBean implements javax.jms.MessageListener {

public void onMessage(javax.msg.Message inMsg) {// implement the onMessage method// to handle the incoming message....

}}

この例に関連する主な機能は次のとおりです。

� EJB 3.0 では、MDB Bean クラスに @MessageDriven 注釈 ( アノテーション ) が付けられます。この注釈 ( アノテーション ) では、一連のアクティベーション構成パラメーターを指定します。これらのパラメーターは、MDB の駆動に使用される特定の種類の JCA 1.5 アダプターに固有です。アダプターによっては、MDB の宛先キューを指定できる構成パラメーターがあるものもあります。アダプターがこれをサポートしていない場合は、XML バインディング・ファイルで <message-destination> エントリーを使用して宛先名を指定する必要があります。

� Bean クラスは、MessageListener インターフェースを実装する必要があります。このインターフェースでは、onMessage という 1 つのメソッドのみが定義されます。この MDB で監視されるキューにメッセージが到着すると、コンテナーは Bean クラスの onMessage メソッドを呼び出し、パラメーターとして着信メッセージを受け渡します。

� また、@MessageDriven 注釈 ( アノテーション ) の activationConfig プロパティーは、メッセージング・システム固有の構成情報を提供します。

Web サービス

@WebService 注釈 ( アノテーション ) を使用して EJB 3.0 Bean を Web サービスとして公開する方法については、「第 18 章 : Web サービス・アプリケーションの開発」を参照してください。ここでは、EJB 3.0 セッション Bean の Web サービスを実装する方法が説明されています。

第 14 章 EJB アプリケーションの開発 9

Page 16: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

ライフ・サイクル・イベント

注釈 ( アノテーション ) のもう 1 つの強力な使用法は、セッション Bean のライフ・サイクル・イベント用のコールバック・メソッドをマーク することです。

EJB 2.1 およびそれ以前のリリースでは、すべての EJB について、ejbPassivate、ejbActivate、ejbLoad、ejbStore などいくつかのライフ・サイクル・メソッドを、必要がない場合でも必ず実装する必要がありました。

EJB 3.0 では POJO を使用するため、これらのライフ・サイクル・メソッドの実装はオプションになります。EJB にコールバック・メソッドを実装する場合のみ、そのメソッドがコンテナーによって呼び出されます。

セッション Bean のライフ・サイクルは、いくつかのフェーズまたはイベントに分類できます。Bean のライフ・サイクルのうち も明白なイベントは、ステートレス・セッション Bean の作成イベントと消滅イベントの 2 つです。

コンテナーがセッション Bean のインスタンスを作成した後で、コンテナーはいずれかの依存性注入 (Dependency Injection) ( 以下のセクションで説明しています ) を行い、その後で @PostConstruct という注釈 ( アノテーション ) が付けられたメソッドを呼び出します ( 存在する場合 )。

クライアントは、セッション Bean への参照を取得し、ビジネス・メソッドを呼び出します。

ライフ・サイクルの 後に、EJB コンテナーは @PreDestroy という注釈 ( アノテーション ) が付けられたメソッドを呼び出します ( 存在する場合 )。Bean インスタンスはガーベッジ・コレクションをすぐに実行できます。

2 つのコールバック・メソッドを持つステートレス・セッション Bean を以下に示します。

@Stateless public class MyStatelessBean implements MyBusinessLogic {// .. bean business method @PostConstruct public void initialize() { // initialize the resources uses by the bean } @PreDestroy public void cleanup() { // deallocates the resources uses by the bean }}

ステートレス EJB およびステートフル EJB はすべて、この 2 つの段階を踏みます。

注 : ステートレス・セッション Bean の実際のライフ・サイクルは、クライアントがその Bean への参照を取得するタイミングとは無関係です。例えば、コンテナーがクライアントに参照を渡しても、しばらく後まで ( その参照についてメソッドが実際に呼び出される時点など )、Bean のインスタンスを作成しないことがあります。または、コンテナーが起動時に多数のインスタンスを作成し、後でそれらのインスタンスを参照と一致させる場合もあります。

10 Rational Application Developer V7.5 プログラミング・ガイド

Page 17: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

また、ステートフル・セッション Bean はパッシベーションとアクティベーションのサイクルを通過します。これは、ステートフル Bean のインスタンスは特定のクライアントにバインドされていて、異なる要求の間で再利用することができないためです。また、EJB コンテナーは使用可能な物理リソースの量を管理する必要があるため、EJB コンテナーは Bean をメモリーから二次記憶装置に移動して非アクティブ化 ( パッシベーション ) する場合があります。

このような、より複雑なライフ・サイクルに対応するため、ステートフル・セッション Bean に特有の次のコールバック・メソッドが存在します。

� EJB コンテナーは、Bean をパッシブ化する直前に、@PrePassivate という注釈(アノテーション)が付けられたメソッドを呼び出します。

� パッシブ・ステージの間に、クライアントがその Bean のビジネス・メソッドを呼び出すと、EJB コンテナーは @PostActivate という注釈 ( アノテーション ) が付けられたメソッドを呼び出して Bean をアクティブ化し ( 存在する場合 )、Bean を準備完了ステージへ移します。

� ライフ・サイクルの 後に、クライアントは @Remove という注釈 ( アノテーション ) が付けられたメソッドを明示的に呼び出し、EJB コンテナーはそれに対応して、@PreDestroy という注釈 ( アノテーション ) が付けられたコールバック・メソッドを呼び出します。開発者は、@Remove という注釈 ( アノテーション ) が付けられたライフ・サイクル・メソッドのみを明示的に呼び出すことができます。その他のメソッドは、EJB コンテナーにより自動的に呼び出されます。

インターセプター

EJB 3.0 仕様では、セッション Bean とメッセージ駆動型 Bean の両方のビジネス・メソッドに対して、カスタム・メイドのインターセプターを適用する機能が定義されています。インターセプターは、@AroundInvoke 注釈 ( アノテーション ) が付けられたメソッドの形式をとります ( 例 14-1)。

例 14-1 インターセプターの適用

@Statelesspublic class MySessionBean implements MyBusinessInterface {

@Interceptors(LoggerInterceptor.class) public Customer getCustomer(String ssn) {

...}

......}

注 : ステートフル Bean は特定のクライアントにバインドされているため、ベスト・プラクティスとして、ステートフル・セッション Bean の EJB コンテナー内の占有スペースが 小になるように正しく設計してください。また、ライフ・サイクルの 後に @Remove 注釈 ( アノテーション ) が付けられたメソッドを呼び出して、Bean の割り当てを正しく解除してください。

ステートフル・セッション Bean にはタイムアウト 値が存在します。ステートフル・セッション Bean がそのタイムアウト期間内に使用されなかった場合、EJB コンテナーによって非アクティブであるとマークされ、自動削除の対象となります。もちろん、タイムアウト・メカニズムに頼って Bean の削除を行うのではなく、クライアントがその Bean の使用を終えたときにアプリケーションで削除することがベスト・プラクティスです。

第 14 章 EJB アプリケーションの開発 11

Page 18: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

public class LoggerInterceptor {@AroundInvokepublic Object logMethodEntry(InvocationContext invocationContext)

throws Exception {System.out.println("Entering method: "

+ invocationContext.getMethod().getName());Object result = invocationContext.proceed();// could have more logic herereturn result;

}}

この例については、以下の点に注意してください。

� @Interceptors 注釈 ( アノテーション ) は、そのインターセプターの適用対象となるセッション Bean メソッドを識別するために使用されます。

� LoggerInterceptor インターセプター・クラスは、@AroundInvoke 注釈 ( アノテーション ) が付けられたメソッド (logMethodEntry) を定義します。

� logMethodEntry メソッドには、アドバイザー・ロジック ( この場合は、呼び出されたメソッド名をログ出力する非常に簡単なロジック ) が含まれており、InvocationContext インターフェースの proceed メソッドを呼び出して、ビジネス・メソッドの実行を継続するようコンテナーに指示します。

EJB 3.0 におけるインターセプターの実装は、Spring や AspectJ などのフレームワークに見られるアスペクト指向プログラミング (AOP) パラダイムの類似の実装とは多少異なり、EJB 3.0 では before または after アドバイザーがサポートされておらず、around インターセプターのみがサポートされています。

ただし、around インターセプターは before または after インターセプターのいずれかまたは両方として機能することができます。invocationContext.proceed 呼び出しの前のインターセプター・コードは EJB メソッドの前に実行され、この呼び出しの後のインターセプター・コードは EJB メソッドの後に実行されます。

インターセプターの極めて一般的な使用法は、ビジネス・ロジック・タスクを呼び出す前の予備チェック ( 検証、セキュリティーなど ) を行うことなので、例外がスローされる場合があります。インターセプターは実行時にセッション Bean コードと共に呼び出されるため、このような例外が発生すると、例外は呼び出し元のクライアントに直接送られます。

この例では、特定のメソッドにインターセプターを適用しましたが、実際には @Interceptors 注釈 ( アノテーション ) はクラス・レベルで適用できます。この場合、インターセプターはすべてのメソッドに対して呼び出されます。

また、@Interceptors 注釈 ( アノテーション ) ではクラスのリストを受け付けることができるため、複数のインターセプターを同じオブジェクトに適用できます。

12 Rational Application Developer V7.5 プログラミング・ガイド

Page 19: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

特定のメソッドに対するデフォルト・インターセプターまたはクラス・インターセプターの呼び出しを無効にするには、それぞれ @ExcludeDefaultInterceptors および @ExcludeClassInterceptors 注釈 ( アノテーション ) を使用できます。

依存性注入(Dependency Injection)

新しい仕様では、Java EE リソース (JDBC データ・ソース、JMS ファクトリーとキュー、EJB 参照 ) を取得し、EJB、エンティティー、または EJB クライアントへ注入するための強力なメカニズムが導入されています。

EJB 2.x では、これらのリソースを取得する唯一の方法は、リソース参照を使用した JNDI ルックアップを使用することでした。この方式には、多くの場合に特定の J2EE コンテナー・プロバイダーに関連するプロパティーを指定する必要があったため、扱いにくいベンダー固有のコードが必要でした。

EJB 3.0 では、依存性注入 (DI) パターンが導入されています。これは、疎結合でアプリケーションを実装する 良の方法の 1 つです。この方法は、JNDI による依存性ルックアップやコンテナーによるコールバックなどの従来の手法よりもはるかに使いやすく、洗練されています。

EJB 3.0 仕様への依存性注入の実装は、注釈 ( アノテーション ) や XML 記述子エントリーに基づいており、フィールドや setter メソッドに依存性を注入することができます。

複雑な XML EJB 参照やリソース参照の代わりに、@EJB および @Resource 注釈 ( アノテーション ) を使用して、JNDI に登録されているすべてのものについて、フィールドの値を設定したり、Bean 内の setter メソッドを呼び出したりすることができます。これらの注釈 ( アノテーション ) により、EJB 参照およびデータ・ソースや JMS ファクトリーなどのリソース参照を注入できます。

ここでは、EJB 3.0 の依存性注入の も一般的な使用法を紹介します。

@EJB 注釈 ( アノテーション ) @EJB 注釈 ( アノテーション ) は、セッション Bean をクライアントに注入するために使用されます。この注入は、別の EJB やサーブレットなどの管理環境内でのみ実行できます。EJB を、例えば JSF 管理 Bean や Struts アクションに注入することはできません。

@EJB 注釈 ( アノテーション ) のパラメーターはオプションです。注釈 ( アノテーション ) のパラメーターは次のとおりです。

� name — 環境の命名コンテキスト (java:comp/env) で、注入される EJB をバインドするために使用される JNDI 名を指定します。

注 : さらに柔軟性を高めるため、EJB 3.0 ではデフォルト・インターセプターの概念が導入されており、同じ EJB モジュール内部に含まれているすべてのセッション ( または MDB) Bean に適用できます。デフォルト・インターセプターは注釈 ( アノテーション ) を使用して指定することはできません。その代わりに、EJB モジュールのデプロイメント記述子の中で定義されます。

インターセプターは次の順序で実行されます。

� デフォルト・インターセプター� クラス・インターセプター� メソッド・インターセプター

第 14 章 EJB アプリケーションの開発 13

Page 20: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

� beanInterface — EJB にアクセスするために使用されるビジネス・インターフェースを指定します。デフォルトでは、使用されるビジネス・インターフェースは、EJB が注入される対象フィールドの Java タイプから取られます。ただし、そのフィールドがビジネス・インターフェースのスーパータイプである場合、またはフィールド・ベースの注入ではなくメソッド・ベースの注入が使用される場合は、beanInterface パラメーターで提供される追加情報がないと、使用されるインターフェース・タイプがあいまいになる可能性があるため、通常はこのパラメーターが必要となります。

� beanName — 注入されるターゲット EJB の ejb-name をシステムにヒントとして指定します。これは XML 記述子の <ejb-ref> または <ejb-local-ref> スタンザに追加できる <ejb-link> スタンザと似ています。

Java サーブレットからセッション Bean にアクセスするには、例 14-2 に示すコードを使用します。

例 14-2 サーブレット内部での EJB 参照の注入

import javax.ejb.EJB;public class TestServlet extends javax.servlet.http.HttpServlet

implements javax.servlet.Servlet {

// inject the remote business interface@EJB(beanInterface=MyRemoteBusinessInterface.class) MyAbstractBusinessInterface serviceProvider;

protected void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {// call ejb method serviceProvider.myBusinessMethod();......

}}

この例に関する注意事項は次のとおりです。

� ここで beanInterface 属性が指定されているのは、EJB により 2 つのビジネス・インターフェース (MyRemoteBusinessInterface および MyLocalBusinessInterface) が公開されているためです。

� EJB により公開されているインターフェースが 1 つだけであれば、この属性を指定する必要はありません。ただし、この属性を指定した方がクライアント・コードが読みやすくなる場合があります。

ステートフル EJB 注入に関する特記 :

� サーブレットはマルチスレッド・オブジェクトなので、依存性注入を使用できません。JNDI 経由で明示的に EJB をルックアップする必要があります

� 別のセッション EJB ( ステートレスまたはステートフル ) 内でステートフル EJB を注入する操作は安全に行うことができます。これは、セッション EJB のインスタンスは一度に 1 つのスレッドでのみ実行されることが保証されているためです。

14 Rational Application Developer V7.5 プログラミング・ガイド

Page 21: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

@Resource 注釈 ( アノテーション ) @Resource 注釈 ( アノテーション ) は、主に管理コンポーネントにリソースを注入するために使用される注釈 ( アノテーション ) です。以下の解説では、この注釈 ( アノテーション ) の も一般的な使用シナリオを紹介します。

次に、データ・ソースなどの一般的なリソースをセッション Bean 内に注入する方法について説明します。

フィールド注入手法例 14-3 は、ビジネス・メソッドで使用されるプロパティーの内部にデータ・ソース (jdbc/datasource) を注入する方法を示しています。

例 14-3 データ・ソースのフィールド注入手法

@Statelesspublic class CustomerSessionBean implements CustomerServiceInterface {

@Resource (name="jdbc/dataSource") private DataSource ds;

public void businessMethod1() {

java.sql.Connection c=null;try {

c = ds.getConnection(); // .. use the connection

} catch (java.sql.SQLException e) {// ... manage the exception

} finally {// close the connectionif(c!=null) {

try { c.close(); } catch (SQLException e) { }}

}}

}

@Resource 注釈 ( アノテーション ) のパラメーターはすべてオプションです。注釈(アノテーション)のパラメーターは次のとおりです。

� name — java:comp/env 名前空間内での、コンポーネント固有の内部名 ( リソースの参照名 ) を指定します。注入されるリソースのグローバル JNDI 名は指定しません。J2EE 1.4 と同様に、リンケージを提供するために、JNDI 名への参照のバインディングは必要です。

� type — リソース・マネージャー接続ファクトリーのタイプを指定します。

� authenticationType —コンテナーと Bean のどちらが認証を実行するのかを指定します。

� shareable — リソース接続が共用可能かどうかを指定します。

� mappedName — リソースをマップする対象の、製品固有の名前を指定します。WebSphere は mappedName を使用しません。

� description — 説明。

setter メソッドの注入もう 1 つの手法は、setter メソッドを注入することです。setter 注入手法は、JavaBean プロパティーの命名規則に基づいています ( 例 14-4)。

第 14 章 EJB アプリケーションの開発 15

Page 22: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

例 14-4 データ・ソースの setter 注入手法

@Statelesspublic class CustomerSessionBean implements CustomerServiceInterface {

private Datasource ds;

@Resource (name="jdbc/dataSource")public void setDatasource(DataSource datasource) {

this.ds = datasource;}...public void businessMethod1() { ...}

}

これら 2 つの例に関する注意事項は次のとおりです。

� この例では、セッション Bean 内でデータ・ソースを直接使用しています。これは適切な方法ではありません。JDBC コードは、データ・アクセス・オブジェクトなど特定のコンポーネント内に記述すべきだからです。

� setter 注入手法の方が以下の点で柔軟性が高いため、こちらの方法を使用することをお勧めします。

– 初期化コードは setter メソッド内に記述することができます。

– セッション Bean は、簡単にテストできるようスタンドアロン・コンポーネントとしてセットアップされます。

@Resource のその他の興味深い使用法は次のとおりです。

� EJB セッション・コンテキストへの参照を取得します。

@Statelesspublic class CustomerSessionBean implements CustomerServiceInterface {

.... @Resource javax.ejb.SessionContext ctx;

}

� デプロイメント記述子内で env-entry を使用して構成されている環境変数の値を取得します。

@Statelesspublic class CustomerSessionBean implements CustomerServiceInterface {

.... @Resource String myEnvironmentVariable;

}

� JMS ファクトリーやキューなどの JMS リソースを注入します。

デプロイメント記述子の使用

ここまでは、EJB を定義する方法、その中にリソースを注入する方法、そのライフ・サイクル・イベントを注釈 ( アノテーション ) を使用して指定する方法について説明してきました。EJB モジュール内で、デプロイメント記述子 (ejb-jar.xml) を必要な情報と共に指定することによっても同じ結果が得られます。

16 Rational Application Developer V7.5 プログラミング・ガイド

Page 23: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

EJB 3.0 アプリケーション・パッケージ

セッション Bean と MDB は、Java 標準の JAR ファイルにパッケージ化できます。これを実現する手法には次の 2 つがあります。

� Java プロジェクトまたは Java ユーティリティー・プロジェクトの使用� EJB プロジェクトの使用

1 つ目の手法を使用するには、デプロイメント記述子 (application.xml) を編集し、次の行を追加して、EAR プロジェクトに Java プロジェクトを追加する必要があります。

<module><ejb>MyEJB3Module.jar</ejb>

</module>

2 つ目の手法を使用する場合、IDE では application.xml ファイルを自動的に更新し、EJB プロジェクト内に ejb-jar.xml をセットアップすることができます。ただし、EJB 3.0 では、ejb-jar.xml ファイルに EJB および関連するリソースを定義する必要はありません。これらは通常、注釈 ( アノテーション ) を使用して定義されます。デプロイメント記述子ファイルの主な用途は、注釈 ( アノテーション ) によって指定された振る舞いをオーバーライドすること、または補完することです。

Application Developer v7.5 の EJB フィーチャー

Application Developer v7.5 によってサポートされている以下の機能は、EJB 3.0 仕様のもので、WebSphere Application Server v6.1 Feature Pack for EJB 3.0 や、WebSphere Application Server v7.0 などの、Java EE 5 互換のアプリケーション・サーバーが必要です。

� セッション Bean およびメッセージ駆動型エンタープライズ Bean の作成 � JPA エンティティーを使用したデータ・パーシスタンスの構築� サーバーでのデプロイメント・コードの自動生成� ステートレス・セッション Bean での Web サービス・エンドポイントの実装が可

能� エンタープライズ Bean での外部 Web サービスの利用が可能� コンテナー管理タイマー・サービスの提供 � メッセージ駆動型 Bean により、JMS のほか、より多くのメッセージ・タイプの

サポートが可能� JPA 照会言語により、エンティティーに対して SQL に似たステートメントを実

行可能

サンプル・アプリケーションの概要

この章では、「第 8 章 : Developing Java applications」で説明したアプリケーションの設計に小さな変更をいくつか加え、再利用します。ただし、この章の内容は Java の章とは無関係です。この章のサンプルは、Java の章で開発したサンプルの知識がなくても完成できます。

この章の焦点は、通常の JavaBean の代わりにビジネス・モデル用の EJB を実装することです。アプリケーションの残りのレイヤー ( コントロールとビュー ) は、設計したとおりに適用されます。

図 14-6 は、サンプル・アプリケーションのモデル・レイヤー設計を示しています。

第 14 章 EJB アプリケーションの開発 17

Page 24: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

図 14-6 サンプル・アプリケーションの EJB モジュールのクラス図

EJBBank セッション Bean は、EJB モデルのファサードとして機能します。ビジネス・エンティティー (Customer、Account、Transaction、Credit、および Debit) は、通常の JavaBean ではなく、ローカル・インターフェースを持つ CMP エンティティー Bean として実装されます。この実装により、パーシスタンス、セキュリティー、配布、およびトランザクション管理サービスが自動的に取得されます。一方で、コントロールおよびビュー・レイヤーは異なる JVM に配置される可能性があるため、これらのエンティティーを直接参照できないことも意味します。セッション Bean (EJBBank) だけは唯一、ビジネス・エンティティーのローカル・インターフェースを経由してビジネス・エンティティーにアクセスできます。

それでは、エンティティー Bean のリモート・インターフェースも同様に公開しない理由は何かと思われるかもしれません。この理由は 2 つあります。1 つは、そのような設計では、クライアントはそれぞれのクライアント要求を解決するために、モデルに対して多くのリモート呼び出しを行うことが考えられるためです。リモート呼び出しはローカル呼び出しよりもコストがかかるため、推奨される方法ではありません。 後に、クライアントがモデルの内部を参照できるようにすると、レイヤーのカプセル化が壊れ、望ましくない依存性や結合が発生します。

コントロール・レイヤーはモデル・オブジェクトを直接参照できないため、「第 8 章 : Developing Java applications」の Java アプリケーションから Customer、Account、Transaction、Credit、および Debit をデータ送信オブジェクトとして再利用し、サーブレットおよび JSP にデータを送信します。ただし基礎となるモデルには直接アクセスできないようにします。

JPAエンティティー

セッション Bean ファサード

18 Rational Application Developer V7.5 プログラミング・ガイド

Page 25: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

図 14-7 にアプリケーション・コンポーネント・モデルとイベントのフローを示します。

図 14-7 アプリケーション・コンポーネント・モデルとワークフロー

図 14-7 に示されているイベントのフローは次のとおりです。

1. 初に発生するイベントは、Web クライアントからサーバーに発行される HTTP 要求です。この要求は、コントロール・レイヤーのサーブレット ( フロント・コントローラーとも呼ばれます ) によって応答され、要求からパラメーターが抽出されます。サーブレットは、要求を適切なコントロール JavaBean へ送信します。この Bean は、現在のユーザーとアプリケーションの状態について要求が有効かどうかを検証します。

2. 有効な場合、コントロール・レイヤーが @EJB が注入されたインターフェースを使用して要求をセッション EJB ファサードに送信します。この振る舞いには、JNDI を使用してセッション Bean のインターフェースを見つける振る舞いと、Bean の新しいインスタンスを作成する振る舞いが含まれます。

3. セッション EJB は、要求に関連して適切なビジネス・ロジックを実行します。このロジックには、モデル・レイヤーの JPA エンティティーへのアクセスが含まれます。

4. ファサードは、応答データとともに DTO を呼び出し元のコントローラー・サーブレットに戻します。戻される DTO は、JPA エンティティー、JPA エンティティーのコレクション、または任意の Java オブジェクトです。一般に、エンティティー・データ用に DTO を追加作成する必要はありません。

5. フロント・コントローラー・サーブレットは、応答 DTO を要求属性として設定し、要求をビュー・レイヤーの適切な JSP に転送し、クライアントに戻す応答をレンダリングします。

6. ビュー JSP は、応答 DTO にアクセスして、ユーザー応答を構築します。

7. 結果のビューは、一般に HTML 形式でクライアントに戻されます。

サンプルの準備

ここでは、サンプル EJB アプリケーションの開発準備の手順について説明します。

Application Server

Web Client

Web Container

EJB Container

EJB Module

Web Module

View

Control

JPA Entities

1

5

DTOs

4

6

HTTP

7

injection

2 Session Facade3

第 14 章 EJB アプリケーションの開発 19

Page 26: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

必要なソフトウェア

この章の EJB 開発サンプルを完成させるには、次のソフトウェアがインストールされている必要があります。

� IBM Rational Application Developer v7.5

� 以下のいずれかのデータベース・ソフトウェア製品 :

– Derby v10.2 (Application Developer と共にデフォルトでインストールされます )– IBM DB2 Universal Database v8.2 またはそれ以降のバージョン

EJB 開発機能の有効化

EJB を開発するには、Rational Application Developer の EJB 開発機能を有効にする必要があります。

� 「ウィンドウ」→「設定」を選択します。

� 「一般」→「機能」→「エンタープライズ Java デベロッパー」を選択し、「OK」をクリックします ( この機能は既に有効になっている場合があります )。

EJB プロジェクトの作成と構成

Application Developer で、EJB プロジェクトおよびユーティリティー・プロジェクトに、Enterprise JavaBeans および関連する Java リソースを作成し、保守します。EJB プロジェクト内では、これらのリソースを移植可能な結合単位として処理できます。

EJB 3.0 仕様では、「第 12 章 : Persistence using the Java Persistence API (JPA)」で説明したように、エンティティーは Java パーシスタンス API (JPA) によって開発され、管理されます。EJB は、セッション Bean またはメッセージ駆動型 Bean です。

EJB モジュールと、基礎となる JPA エンティティーには、一部のビジネス・ロジックを実行するために連携させるコンポーネントが含まれています。このロジックは自己完結していてもかまいませんし、必要に応じて外部のデータと関数にアクセスすることもできます。これは、ファサード ( セッション Bean) とビジネス・エンティティーで構成されている必要があります (JPA エンティティー )。ファサードは通常、1 つ以上のセッション Bean とメッセージ駆動型 Bean を使用して実装されます。

この章では、図 14-6 (18 ページ ) に示すように、JPA エンティティー (Customer、Account、Transaction) のファサードとしてセッション EJB を開発します。RAD75JPA プロジェクトをワークスペースで利用できる必要があります ( このプロジェクトは、c:\7672codesolution\jpa からインポートできます )。

EJB プロジェクトの作成

セッション EJB を開発するために、EJB プロジェクトを作成します。通常、EJB プロジェクトをデプロイするためのコンテナーとなるエンタープライズ・アプリケーション (EAR) プロジェクトも作成します。

注 : ソフトウェアのインストールについて詳しくは、「付録 A: Product installation」を参照してください。

20 Rational Application Developer V7.5 プログラミング・ガイド

Page 27: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

Java EE EJB プロジェクトを作成するには、次の手順に従います。

� Java EE パースペクティブを開きます。

� ワークベンチで、「ファイル」→「新規作成」→「プロジェクト」を選択します。

� 「新規プロジェクト」ダイアログで、「EJB」→「EJB プロジェクト」を選択し、「次へ」をクリックします。

� 「新規 EJB プロジェクト」ダイアログ ( 図 14-8) で次の操作を行います。

– 「名前」フィールドに「RAD75EJB」と入力します。

– 「ターゲット・ランタイム」で「WebSphere Application Server v7.0」を選択します。

– 「EJB モジュールのバージョン」で、「3.0」を選択します。

– 「EAR にプロジェクトを追加」( デフォルト ) を選択し、「EAR プロジェクト名」フィールドに「RAD75EJBEAR」と入力します。デフォルトでは、ウィザードは新規 EAR プロジェクトを作成しますが、ドロップダウン・コンボ・ボックスから既存のプロジェクトを選択することもできます。新規プロジェクトを作成してその場所を構成するには、「新規作成」をクリックします。この例では、表示されるデフォルト値を使用します。

– 「構成」で「WebSphere Application Server v7.0 のデフォルト構成」を選択します。オプションで、「変更」をクリックすると、プロジェクト・ファセット (EJB モジュール 3.0、Java 6.0、WebSphere EJB ( 拡張 ) 7.0) を表示できます。

– 「次へ」をクリックします。

図 14-8 EJB プロジェクトの作成ウィザード (1)

注 : EJB 3.0 では、EJB クラスを保持するためのユーティリティー・プロジェクトも使用できますが、EJB プロジェクトを使用する方が柔軟性が高まります。

第 14 章 EJB アプリケーションの開発 21

Page 28: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

� 「EJB モジュール」ダイアログ ( 図 14-9) で、次の項目を入力します。

– ソース・フォルダー : ejbModule ( デフォルト )

– 「クライアントのインターフェースとクラスを保有する EJB クライアント JAR モジュールを作成する」をクリアします ( デフォルト )。

– 「デプロイメント記述子の生成」を選択します。

– 「終了」をクリックします。

図 14-9 EJB プロジェクトの作成ウィザード (3)

� プロジェクトを作成するとき、現在のパースペクティブが Java EE パースペクティブでない場合、Java EE パースペクティブに切り替えるように Application Developer によってプロンプトが表示されます。「はい」をクリックします。

� 「Technology Quickstarts」ビューが開きます。リンクをクリックして、Application Developer ヘルプで該当するチュートリアルを開くことができます。ビューを閉じます。

� エンタープライズ・エクスプローラーには、RAD75EJB プロジェクトと、RAD75EJBEAR エンタープライズ・アプリケーションが含まれています。

注 : EJB クライアント JAR は、エンタープライズ Bean のインターフェースのほか、それらのインターフェースが依存する、スーパークラスや実装済みインターフェースなど他のクラスと、メソッド・パラメーター、結果、および例外として使用されるクラスとインターフェースを保持します。

EJB クライアント JAR は、EJB にアクセスするクライアント・アプリケーションと共にデプロイできます。この結果、EJB プロジェクトをクライアント・アプリケーションと共にデプロイする場合と比較して、クライアント・アプリケーションが小さくなります。

ただし、EJB 3.0 の EJB は、EJB 2.1 の EJB と比較して軽量な注釈 ( アノテーション ) 付き Java クラスなので、クライアント JAR の必要性は 小限です。

22 Rational Application Developer V7.5 プログラミング・ガイド

Page 29: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

JPA エンティティーを EJB プロジェクトで利用可能にする

JPA エンティティーを EJB で利用可能にするには、RAD75JPA プロジェクトを RAD75EJBEAR エンタープライズ・アプリケーションに追加し、依存関係を作成します。

� 「RAD75EJBEAR」プロジェクトを右クリックし、「Java EE」→ 「デプロイメント記述子スタブの生成」を選択します。

� application.xml ファイルを含む META-INF フォルダーがプロジェクト内に作成されます。

� application.xml ファイルを開きます。

� エディターで「設計」タブを選択すると、EJB モジュールが EAR の一部として表示されます ( 図 14-10)。エディターを閉じます。

図 14-10 EAR デプロイメント・エディター

� 「RAD75EJBEAR」プロジェクトを右クリックし、「プロパティー」を選択します。

� 「プロパティー」ダイアログで、「Java EE モジュール依存関係」を選択し、「RAD75JPA」モジュールを選択して「OK」をクリックします ( 図 14-11)。

第 14 章 EJB アプリケーションの開発 23

Page 30: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

図 14-11 EAR モジュールの依存関係

� 「RAD75EJB」プロジェクトを右クリックし、「プロパティー」を選択します。「プロパティー」ダイアログで、「Java EE モジュール依存関係」を選択し、「RAD75JPA.jar」を選択して「OK」をクリックします ( 図 14-11 と同様 )。

ITSOBANK データベースのセットアップ

JPA エンティティーは、ITSOBANK データベースを基礎としています。したがって、マッピング・ツールがデータベースからスキーマ情報を抽出するために使用するデータベース接続を、Application Developer 内で定義する必要があります。

ITSOBANK データベースを作成する方法の手順については、「付録 B: Additional material」の「Setting up the ITSOBANK database」を参照してください。データベースは DB2 または Derby を使用できます。説明を簡単にするため、この章では組み込みの Derby データベースを使用します。

ITSOBANK のデータ・ソースの構成

データ・ソースの構成に使用できる方法としては、WebSphere 管理コンソールを使用する方法や、デプロイメント記述子に構成を保存し、アプリケーションと共にデプロイされる WebSphere Enhanced EAR を使用する方法などがあります。

WebSphere 管理コンソールでのデータ・ソースの定義については、「付録 B: Additional material」の「Configuring the data source in WebSphere Application Server」で説明されています。

ここでは、WebSphere Enhanced EAR 機能を使用してデータ・ソースを構成する方法について説明します。Enhanced EAR は、EAR デプロイメント記述子エディターの

「デプロイメント」タブで構成します。完全なサンプル・コードをインポートする場合、必要な作業は、デプロイメント記述子の databaseName プロパティーの値が、データベースの場所と一致することを確認するだけです。

他のプロジェクトが存在する可能性があります

注 : データ・ソースの構成およびデプロイメントの一般的な問題について詳しくは、「第 26 章 : Deploying enterprise applications」を参照してください。

24 Rational Application Developer V7.5 プログラミング・ガイド

Page 31: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

Enhanced EAR を使用したデータ・ソースの構成デプロイメント記述子の Enhanced EAR 機能を使用して新しいデータ・ソースを構成するには、次の手順に従います。

� 「RAD75EJBEAR」プロジェクトを右クリックし、「Java EE」→「WebSphere Application Server Deployment を開く」を選択します。

� WebSphere デプロイメント・エディターが開きます。

� 「JDBC プロバイダー・リスト」から「Derby JDBC プロバイダー (XA)」を選択します。この JDBC プロバイダーはデフォルトで構成されます。

� データ・ソースの横の「追加」をクリックします。

� 「データ・ソースの作成」ダイアログで次の手順を行います。

– JDBC プロバイダーの下の「Derby JDBC プロバイダー (XA)」を選択し、「バージョン 5.0 データ・ソース」を選択して、「次へ」をクリックします。

– 「名前」に「ITSOBANKejb」、「JNDI 名」に「jdbc/itsobank」、「説明」に「Data Source for ITSOBANK EJBs」と入力します。「このデータ・ソースをコンテナー管理下パーシスタンス (CMP) で使用する」をクリアします。「次へ」をクリックします。

� 「リソース・プロパティーの作成」ダイアログで、「databaseName」を選択し、値として「C:\7672code\database\derby\ITSOBANK」と入力します。説明をクリアします。

� 「終了」をクリックします。

� デプロイメント記述子を保存して閉じます ( 図 14-12)。

図 14-12 EAR 拡張デプロイメント記述子

EJB アプリケーションの開発

EJB アプリケーションは、単純なサーブレットを持つ Web モジュールと、JPA エンティティーを使用してデータベースにアクセスする EJB 3.0 セッション Bean を持つ EJB モジュールとで構成されます。

第 14 章 EJB アプリケーションの開発 25

Page 32: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

セッション・ファサードの実装

フロントエンド・アプリケーションは、セッション・ファサードを使用して JPA エンティティー・モデルと通信します。この設計パターンにより、エンティティーは EJB クライアントから見えなくなります。

ここでは、ステートレス・セッション Bean であるセッション・ファサード EJBBank を構築します。

例外の準備

セッション Bean のビジネス・ロジックは、エラー発生時に例外をスローします。ここでは、ITSOBankException という名前のアプリケーション例外を作成します。

� 「RAD75EJB」プロジェクトを右クリックし、「新規作成」→「 クラス」を選択します。

� 「新規 Java クラス」ダイアログで、「パッケージ」に「itso.bank.exception」、「名前」に「ITSOBankException」と入力します。「スーパークラス」を

「java.lang.Exception」に設定します。「終了」をクリックします。

� エディターでコードを完成させます。

public class ITSOBankException extends Exception {private static final long serialVersionUID = 1L;

public ITSOBankException(String message) {super(message);

}}

� クラスを保存して閉じます。

EJBBank セッション Bean の作成

セッション Bean を作成するには、次の手順に従います。

� 「RAD75EJB」プロジェクトを右クリックし、「新規作成」→「セッション Bean」を選択します。

� 「EJB 3.0 セッション Bean の作成」ダイアログ ( 図 14-13) で次の手順を行います。

26 Rational Application Developer V7.5 プログラミング・ガイド

Page 33: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

図 14-13 セッション Bean の作成 (1)

– 「Java パッケージ」に「itso.bank.session」と入力します。

– 「クラス名」に「EJBBankBean」と入力します。

– 「状態タイプ」で「ステートレス」を選択します。

– 「ビジネス・インターフェースの作成」で「ローカル」を選択し、名前を「itso.bank.service.EJBBankService」に設定します。

– 「次へ」をクリックします。

� 次のダイアログで、「トランザクション・タイプ」をデフォルト値の「コンテナー」のままにし、「次へ」をクリックします ( 図 14-14)。

図 14-14 セッション Bean の作成 (2)

� 「視覚化のためクラス図を選択」ダイアログで、「Bean をクラス図に追加」を選択し、デフォルト名の「classdiagram.dnx」のままにします。

� 「終了」をクリックします。

� EJB 3.0 モデリングを有効にするようプロンプトが表示されたら、「OK」をクリックします。

第 14 章 EJB アプリケーションの開発 27

Page 34: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

� クラス図を保存して閉じます。

� EJBBankBean がエディターで開きます。@Stateless 注釈 ( アノテーション ) に着目します。

セッション Bean コードを作成する前に、ビジネス・インターフェース EJBBankService を完成させる必要があります。

ビジネス・インターフェースの定義

EJB 3.0 では、セッション Bean にビジネス・インターフェースが実装され、クライアントはこのインターフェースを使用してセッション Bean にアクセスします。セッション Bean には複数のインターフェース、例えばローカル・インターフェースとリモート・インターフェースを実装できます。ここでは単純化のため、ローカル・インターフェース EJBBankService のみを実装します。

セッション Bean ウィザードにより、EJBBankService インターフェースが作成されています。コードを完成させるには、次の手順に従います。

� EJBBankService インターフェースを開きます。@Local 注釈 ( アノテーション ) に着目します。

� Java エディターで、インターフェースにメソッドを追加します ( 例 14-5)。このコードは c:\7672code\ejb\source\EJBBankService.txt にあります。

例 14-5 セッション Bean のビジネス・インターフェース

@Localpublic interface EJBBankService {

public Customer getCustomer(String ssn) throws ITSOBankException;public Customer[] getCustomersAll();public Customer[] getCustomers(String partialName)

throws ITSOBankException;public void updateCustomer(String ssn, String title, String firstName,

String lastName) throws ITSOBankException;public Account[] getAccounts(String ssn) throws ITSOBankException;public Account getAccount(String id) throws ITSOBankException;public Transaction[] getTransactions(String accountID)

throws ITSOBankException;public void deposit(String id, BigDecimal amount)

throws ITSOBankException; public void withdraw(String id, BigDecimal amount)

throws ITSOBankException; public void transfer(String idDebit, String idCredit, BigDecimal amount)

throws ITSOBankException;public void closeAccount(String ssn, String id)

throws ITSOBankException; public String openAccount(String ssn) throws ITSOBankException; public void addCustomer(Customer customer) throws ITSOBankException;public void deleteCustomer(String ssn) throws ITSOBankException;

}

� インポートを編成します (Ctrl + Shift + O キーを押します )。プロンプトが表示されたら、「java.math.BigDecimal」および「itso.bank.entities.Transaction」を選択します。インターフェースを保存して閉じます。

28 Rational Application Developer V7.5 プログラミング・ガイド

Page 35: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

セッション Bean の完成

次は、バンキング操作を行うためにクライアントによって使用されるファサード・メソッドを追加します。

スケルトン・メソッドの生成実装が必要なビジネス・インターフェースのメソッドのメソッド・スケルトンを生成できます。

� EJBBankBean を開きます ( 閉じている場合 )。

� 「ソース」→「メソッドのオーバーライド / 実装」を選択します。

� 「メソッドのオーバーライド / 実装」ダイアログで、EJBBankService インターフェースのすべてのメソッドを選択します。「挿入ポイント」は「'EJBBankBean()' の後」を選択します。「OK」をクリックします。

� メソッド・スケルトンが生成されます。デフォルトのコンストラクターを削除します。

エンティティー・マネージャーの作成セッション Bean は、JPA エンティティーとの連携により、ITSOBANK データベースにアクセスします。エンティティー・マネージャーは、永続コンテキストにバインドされている必要があります。

� これらの定義を EJBBankBean クラスに追加します。

@PersistenceContext (unitName="RAD75JPA",type=PersistenceContextType.TRANSACTION)

private EntityManager entityMgr;

@PersistenceContext 注釈 ( アノテーション ) は、トランザクションの振る舞いを持つ永続コンテキスト単位を定義します。この単位名は、RAD75JPA プロジェクトの persistence.xml ファイルに存在する名前と一致します。

<persistence-unit name="RAD75JPA">

EntityManager インスタンスは、インスタンスの取得、挿入、更新、削除、および照会を行う JPA メソッドを実行するために使用されます。

� インポートを編成します (javax.persistence パッケージを選択します )。

メソッドの完成

セッション Bean のメソッドは、生成されたスケルトンのアルファベット順ではなく、論理的な順序で完成させます。

getCustomer メソッドgetCustomer メソッドは、ssn を使用して 1 人の顧客を取得します。1 つのインスタンスを取得するには、entityMgr.find を使用します。別の方法として、getCustomerBySSN 照会 ( コメント内のコード ) を使用することもできます。インスタンスが見つからない場合、NULL が戻されます ( 例 14-6)。

例 14-6 セッション Bean の getCustomer メソッド

public Customer getCustomer(String ssn) throws ITSOBankException {System.out.println("getCustomer:" + ssn);

ヒント : このセクションの Java コードは、c:\7672code\ejb\source\EJBBankBean.txt ファイルからコピーできます。

第 14 章 EJB アプリケーションの開発 29

Page 36: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

//Query query = null;try {

//query = entityMgr.createNamedQuery("getCustomerBySSN");//query.setParameter(1, ssn);//return (Customer)query.getSingleResult();return entityMgr.find(Customer.class, ssn);

} catch (Exception e) {System.out.println("Exception:" + e.getMessage());throw new ITSOBankException(ssn);

}}

getCustomers メソッドgetCustomers メソッドは、照会を使用して顧客のコレクションを取得します (例 14-7)。この照会は作成され、実行されます。結果リストは配列に変換されて戻されます。Customer エンティティーから照会することに注意してください。

@NamedQuery(name="getCustomersByPartialName", query="select c from Customer c where c.lastName like ?1")

この照会は SQL のように見えますが、エンティティー・オブジェクトに対して実行されます。この例ではエンティティー名とテーブル名が同じですが、必ずしも同じ名前である必要はありません。

例 14-7 セッション Bean の getCustomers メソッド

public Customer[] getCustomers(String partialName) throws ITSOBankException {System.out.println("getCustomer:" + partialName);Query query = null;try {

query = entityMgr.createNamedQuery("getCustomersByPartialName");query.setParameter(1, partialName);List<Customer> beanlist = query.getResultList();Customer[] array = new Customer[beanlist.size()];return beanlist.toArray(array);

} catch (Exception e) {throw new ITSOBankException(partialName);

} }

updateCustomer メソッドupdateCustomer メソッドは非常に単純です ( 例 14-8)。エンティティー・マネージャーへの呼び出しは必要ありません。メソッド ( トランザクション ) の終了時に、テーブルは自動的に更新されます。

例 14-8 セッション Bean の updateCustomer メソッド

public void updateCustomer(String ssn, String title, String firstName, String lastName) throws ITSOBankException {

System.out.println("updateCustomer:" + ssn);Customer customer = getCustomer(ssn);customer.setTitle(title);customer.setLastName(lastName);customer.setFirstName(firstName);System.out.println("updateCustomer:" + customer.getTitle() + " "

+ customer.getFirstName() + " " + customer.getLastName());}

30 Rational Application Developer V7.5 プログラミング・ガイド

Page 37: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

getAccount メソッドgetAccount メソッドは、getCustomer メソッドと同様に、キーを使用して 1 つの口座を取得します。

getAccounts メソッドgetAccounts メソッドは、照会を使用して、1 人の顧客のすべての口座を取得します ( 例 14-9)。Account エンティティーでの照会は次のようになります。

select a from Account a, in(a.customerCollection) c where c.ssn =?1 order by a.id

この照会は、指定された ssn を持つ顧客に属する口座を検索します。Customer クラスの別の照会を使用することもできます。

select a from Customer c, in(c.accountCollection) a where c.ssn =?1 order by a.id

例 14-9 セッション Bean の getAccounts メソッド

public Account[] getAccounts(String ssn) throws ITSOBankException {System.out.println("getAccounts:" + ssn);Query query = null;try {

query = entityMgr.createNamedQuery("getAccountsBySSN");query.setParameter(1, ssn);List<Account>accountList = query.getResultList();Account[] array = new Account[accountList.size()];return accountList.toArray(array);

} catch (Exception e) {System.out.println("Exception:" + e.getMessage());throw new ITSOBankException(ssn);

}}

getTransactions メソッドgetTransactions メソッド ( 例 14-10) は、1 つの口座のトランザクションを取得します。これは、getAccounts メソッドと同様のものです。

例 14-10 セッション Bean の getTransactions メソッド

public Transaction[] getTransactions(String accountID) throws ITSOBankException {System.out.println("getTransactions:" + accountID);Query query = null;try {

query = entityMgr.createNamedQuery("getTransactionsByID");query.setParameter(1, accountID);List<Transaction> transactionsList = query.getResultList();Transaction[] array = new Transaction[transactionsList.size()];return transactionsList.toArray(array);

} catch (Exception e) {System.out.println("Exception:" + e.getMessage());throw new ITSOBankException(accountID);

}}

第 14 章 EJB アプリケーションの開発 31

Page 38: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

deposit メソッドと withdraw メソッドdeposit メソッドは、口座を取得し、Transaction.CREDIT コードを使用してその口座の processTransaction メソッドを呼び出すことで、口座に現金を追加します。この新しいトランザクション・インスタンスは永続します ( 例 14-11)。withdraw メソッドも同様です。

例 14-11 セッション Bean の deposit メソッド

public void deposit(String id, BigDecimal amount) throws ITSOBankException {System.out.println("deposit:" + id + " amount " + amount);Account account = getAccount(id);try {

Transaction tx = account.processTransaction(amount, Transaction.CREDIT);entityMgr.persist(tx);

} catch (Exception e) {throw new ITSOBankException(e.getMessage());

};}

transfer メソッドtransfer メソッドは、2 つの口座に対して withdraw および deposit を呼び出し、一方の口座からもう一方の口座へ預金を移動します ( 例 14-12)。

例 14-12 セッション Bean の transfer メソッド

public void transfer(String idDebit, String idCredit, BigDecimal amount) throws ITSOBankException {

System.out.println("transfer:" + idCredit + " " + idDebit + " amount " + amount);

withdraw(idDebit, amount);deposit(idCredit, amount);

}

openAccount メソッドopenAccount メソッドは、ランダムに構成された口座番号を持つ、新しい口座インスタンスを作成します。このインスタンスは永続化され、顧客が customerCollection に追加されます ( 例 14-13)。

例 14-13 セッション Bean の openAccount メソッド

public String openAccount(String ssn) throws ITSOBankException {System.out.println("openAccount:" + ssn);Customer customer = getCustomer(ssn);int acctNumber = (new java.util.Random()).nextInt(899999) + 100000;String id = "00" + ssn.substring(0, 1) + "-" + acctNumber;Account account = new Account();account.setId(id);entityMgr.persist(account);//customer.getAccountCollection().add(account); // does not workjava.util.Set<Customer> custSet = new java.util.TreeSet<Customer>();custSet.add(customer);account.setCustomerCollection(custSet);System.out.println("openAccount:" + id);return id;

}

32 Rational Application Developer V7.5 プログラミング・ガイド

Page 39: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

closeAccount メソッドcloseAccount メソッドは、口座とそのすべてのトランザクションを取得してから、エンティティー・マネージャーの remove メソッドを使用して、すべてのインスタンスを削除します ( 例 14-14)。

例 14-14 セッション Bean の closeAccount メソッド

public void closeAccount(String ssn, String id) throws ITSOBankException {System.out.println("closeAccount:" + id + " of customer " + ssn);Customer customer = getCustomer(ssn);Account account = getAccount(id);Transaction[] trans = getTransactions(id);for (Transaction tx :trans) {

entityMgr.remove(tx);}entityMgr.remove(account);System.out.println("closed account with " + trans.length

+ " transactions");}

addCustomer メソッドaddCustomer メソッドは、完全に構成された Customer インスタンスを受け取り、永続化します ( 例 14-15)。

例 14-15 セッション Bean の addCustomer メソッド

public void addCustomer(Customer customer) throws ITSOBankException {System.out.println("addCustomer:" + customer.getSsn());entityMgr.persist(customer);

}

deleteCustomer メソッドdeleteCustomer メソッドは、顧客とそのすべての口座を取得した後に、口座を閉じて顧客を削除します ( 例 14-16)。

例 14-16 セッション Bean の deleteCustomer メソッド

public void deleteCustomer(String ssn) throws ITSOBankException {System.out.println("deleteCustomer:" + ssn);Customer customer = getCustomer(ssn);Account[] accounts = getAccounts(ssn);for (Account acct :accounts) {

closeAccount(ssn, acct.getId());}entityMgr.remove(customer);

}

インポートを編成します (javax.persistence.Query と java.util.List を選択します )。

注 : m:m 関係は、関係の所有 側 ( この例では 口座 ) から追加する必要があります。顧客側から関係を追加するコードはエラーが発生することなく実行されますが、関係は追加されません。

第 14 章 EJB アプリケーションの開発 33

Page 40: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

これで、EJBBankBean セッション Bean が完成しました。以下のセクションでは、初にサーブレットを使用して EJB のテストを行い、次に EJB と Web アプリケーションの統合処理に進みます。

セッション EJB とエンティティーのテスト

セッション EJB のテストは、ユニバーサル・テスト・クライアントを使用して実行できます。また、すべての機能を実行する簡単なサーブレットを開発できます。

サーバーへのアプリケーションのデプロイテスト・アプリケーションをデプロイするには、次の手順に従います。

� 「サーバー」ビューで WebSphere Application Server v7.0 を起動します。

� サーバーを選択し、「プロジェクトの追加および除去」を選択します。RAD75EJBEAR エンタープライズ・アプリケーションを追加し、「終了」をクリックします。公開が完了するまで待ちます。

� コンソールの EJB バインディング・メッセージに着目します。

[...] 00000010 ResourceMgrIm I WSVR0049I:Binding ITSOBANKejb as jdbc/itsobank[...] 00000015 EJBContainerI I CNTR0167I:The server is binding the EJBBankService interface of the EJBBankBean enterprise bean in the RAD75EJB.jar module of the RAD75EJBEAR application.The binding location is:ejblocal:RAD75EJBEAR/RAD75EJB.jar/EJBBankBean#itso.bank .service.EJBBankService[...] 00000015 EJBContainerI I CNTR0167I:The server is binding the EJBBankService interface of the EJBBankBean enterprise bean in the RAD75EJB.jar module of the RAD75EJBEAR application.The binding location is:ejblocal:itso.bank.service.EJBBankService

EJB 3.0 セッション Bean は、JNDI の長い名前と短い名前に自動的にバインドされます。

long: ejblocal:RAD75EJBEAR/RAD75EJB.jar/EJBBankBean#itso.bank....short: ejblocal:itso.bank.service.EJBBankService

ユニバーサル・テスト・クライアントを使用したテスト

EJB アプリケーションを Web アプリケーションと統合する前に、セッション Bean で JPA エンティティーへのアクセスをテストします。Application Developer に含まれているエンタープライズ・アプリケーションであるユニバーサル・テスト・クライアント (UTC) を使用します。

ここでは、ユニバーサル・テスト・クライアントで実行できるいくつかの操作について説明します。テスト・クライアントを使用して、顧客とその口座を取得します。

注 : ITSOBANK データベースのデータ・ソースが jdbc/itsobank という JNDI 名で構成されていることを確認してください。この内容は、WebSphere デプロイメント・エディター (「ITSOBANK のデータ・ソースの構成」 (24 ページ )) またはサーバーの管理コンソール (「付録 B: Additional material」の「Configuring the data source in WebSphere Application Server」) で確認できます。

34 Rational Application Developer V7.5 プログラミング・ガイド

Page 41: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

セッション Bean をテストするには、以下の手順に従います。

� 「サーバー」ビューでサーバーを右クリックし、「ユニバーサル・テスト・クライアント」→「実行」を選択します。

� 証明書を受け入れ、admin/admin (Application Developer のインストール時にセットアップされたユーザー ID) としてログインします。

� ユニバーサル・テスト・クライアントが開きます ( 図 14-15)。

図 14-15 ユニバーサル・テスト・クライアントのホーム

� 「JNDI エクスプローラー」を選択します。右側で、「[ ローカル EJB Bean]」を展開します。

� 「itso.bank.service.EJBBankService」を選択します。「EJBBankService」が「EJB Beans」の下に表示されます ( 図 14-16)。

図 14-16 UTC: JNDI エクスプローラー

� 「EJBBankService」( 左側 ) を展開し、「getCustomer」メソッドを選択します。メソッドとそのパラメーターが右側に表示されます。

� 右側に値として「111-11-1111」と入力し、「起動」をクリックします。

� 結果として Customer インスタンスが表示されます ( 図 14-17)。

第 14 章 EJB アプリケーションの開発 35

Page 42: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

図 14-17 UTC: 顧客の取得

� 「オブジェクトの使用」をクリックします。「オブジェクト」の下に Customer インスタンスが表示されます。このオブジェクトを展開し、そのメソッド (getLastName など ) を呼び出すと、顧客名を参照できます。

� 「EJBBankService」インターフェースの「getAccounts」メソッドを選択します。パラメーター値として「222-22-2222」と入力し、「起動」をクリックします。結果として 3 つの口座が表示されます。

� 「getTransactions」メソッドを選択します。パラメーター値として「002-222002」と入力し、「起動」をクリックします。いくつかのトランザクション・レコードが表示されます。

� 「openAccount」メソッドを選択します。パラメーター値として「111-11-1111」と入力し、「起動」をクリックします。ランダムな ID ( 例えば 001-169749) を持つ新しい口座が作成されます。

� 「deposit」メソッドを選択します。パラメーター値として新しい口座番号「001-xxxxxx」と「100.00」を入力し、「起動」をクリックします。

� 「getAccount」メソッドを選択します。パラメーター値として新しい口座番号「001-xxxxxx」を入力し、「起動」をクリックします。「オブジェクトの使用」をクリックして口座オブジェクトを展開し、「getBalance」メソッドを呼び出して残高を確認します。

� 「closeAccount 」メソッドを選択します。パラメーター値として「111-11-1111」と新しい口座番号「001-xxxxxx」を入力し、「起動」をクリックします。

� コンソールで、口座が閉じていることを確認します。

closed account with 1 transactions

UTC を使用して、すべての EJB メソッドが動作することを確認できます。操作が完了したら、UTC ペインを閉じます。

36 Rational Application Developer V7.5 プログラミング・ガイド

Page 43: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

テスト用 Web アプリケーションの作成

EJB 3.0 セッション Bean とエンティティー・モデルをテストするために、サーブレットを 1 つ含む小さな Web アプリケーションを作成します。

� 「ファイル」→「新規プロジェクト」→「Web」→「動的 Web プロジェクト」を選択します。

– 名前として「RAD75EJBTestWeb」と入力します。

– 動的 Web モジュールのバージョンとして「2.5」を選択します。

– RAD75EJBEAR エンタープライズ・アプリケーションにこのプロジェクトを追加します。

– 「終了」をクリックし、開いたヘルプを閉じます。

� 「RAD75EJBTestWeb」プロジェクトを右クリックし、「プロパティー」を選択します。「プロパティー」ダイアログの「Java EE モジュール依存関係」ページで、

「RAD75EJB.jar」モジュールを選択して「OK」をクリックします。

� 「RAD75EJBTestWeb」プロジェクトを右クリックし、「新規作成」→「サーブレット」を選択します。

� パッケージ名として「itso.test.servlet」、クラス名として「BankTest」と入力します。「次へ」を 2 回クリックし、doPost および doGet メソッドの生成を選択します。「終了」をクリックします。

� クラス定義の後で、ビジネス・インターフェースのインジェクターを追加します。

@javax.ejb.EJB EJBBankService bank;

サーブレットへのビジネス・インターフェースの注入は、セッション EJB の自動的なバインディングに解決されます。

� doGet メソッドに次のコードを入力します。

doPost(request, response);

� 例 14-17 のコードで doPost メソッドを完成させます。このコードは 7672code\ejb\source\BankTest.txt に含まれています。このサーブレットは、ビジネス・インターフェースへの参照を取得してから、セッション Bean のメソッドを実行します。

例 14-17 EJB 3.0 モジュールをテストするサーブレット ( 簡略版 )

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

try {PrintWriter out = response.getWriter();String partialName = request.getParameter("partialName");out.println("<html><body><h2>Customer Listing</h2>");if (partialName == null) partialName = "%";else partialName = "%" + partialName + "%";

out.println("<p>Customers by partial Name:" + partialName + "<br>");Customer[] customers = bank.getCustomers(partialName);

for (Customer cust :customers) {out.println("<br>" + cust);

}

Customer cust1 = bank.getCustomer("222-22-2222");out.println("<p>" + cust1);

第 14 章 EJB アプリケーションの開発 37

Page 44: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

Account[] accts = bank.getAccounts(cust1.getSsn());out.println("<br>Customer:" + cust1.getSsn() + " has "

+ accts.length + " accounts");Account acct = bank.getAccount("002-222002");out.println("<p>" + acct);

out.println("<p>Transactions of account:" + acct.getId());Transaction[] trans = bank.getTransactions("002-222002");out.println("<p><table border=1><tr><th>Type</th><th>Time</th>...");for (Transaction t :trans) {

out.println("<tr><td>" + t.getTransType() + "</td><td>" + ...);}out.println("</table>");

String newssn = "xxx-xx-xxxx";bank.deleteCustomer(newssn); // for rerunout.println("<p>Add a customer:" + newssn);Customer custnew = new Customer();custnew.setSsn(newssn);custnew.setTitle("Mrs");custnew.setFirstName("Julia");custnew.setLastName("Roberts");bank.addCustomer(custnew);Customer cust2 = bank.getCustomer(newssn);out.println("<br>" + cust2);

out.println("<p>Open two accounts for customer:" + newssn);String id1 = bank.openAccount(newssn);String id2 = bank.openAccount(newssn);out.println("<br>New accounts:" + id1 + " " + id2);Account[] acctnew = bank.getAccounts(newssn);out.println("<br>Customer:" +newssn + " has " +acctnew.length ...);Account acct1 = bank.getAccount(id1);out.println("<br>" + acct1);

out.println("<p>Deposit and withdraw from account:" + id1);bank.deposit(id1, new java.math.BigDecimal("777.77"));bank.withdraw(id1, new java.math.BigDecimal("111.11"));acct1 = bank.getAccount(id1);out.println("<br>Account:" +id1+ " balance " + acct1.getBalance());

trans = bank.getTransactions(id1);out.println("<p><table border=1><tr><th>Type</th><th>Time</th>...");for (Transaction t :trans) {

out.println("<tr><td>" + t.getTransType() + ...");}out.println("</table>");

out.println("<p>Close the account:" + id1);bank.closeAccount(newssn, id1);

out.println("<p>Update the customer:" + newssn);bank.updateCustomer(newssn, "Mr", "Julius", "Roberto");cust2 = bank.getCustomer(newssn);out.println("<br>" + cust2);out.println("<p>Delete the customer:" + newssn);bank.deleteCustomer(newssn);

out.println("<p>Retrieve non existing customer: ");

38 Rational Application Developer V7.5 プログラミング・ガイド

Page 45: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

Customer cust3 = bank.getCustomer("zzz-zz-zzzz");out.println("<br>customer:" + cust3);

out.println("<p>End</body></html>");} catch (Exception e) {

System.out.println("Exception:" + e.getMessage());e.printStackTrace();

}}

サンプル Web アプリケーションのテスト次のサーブレットを実行して、Web アプリケーションをテストします。

� テスト用 Web プロジェクトの「デプロイメント記述子」→ 「サーブレット」を展開し、「BankTest」サーブレットを選択して、「実行」→「サーバーで実行」を選択します。

� 「サーバーで実行」ダイアログで、「WebSphere Application Server v7.0」サーバーを選択し、「このプロジェクトを実行するときは、このサーバーを常に使用」を選択して「終了」をクリックします。

� セキュリティー証明書を受け入れます ( セキュリティーが有効な場合 )。

� サーブレットの出力サンプルを例 14-18 に示します。

例 14-18 サーブレットの出力 ( 簡略版 )

Customer ListingCustomers by partial Name: %

Customer: 111-11-1111 Mr Henry Cui Customer: 222-22-2222 Ms Pinar Ugurlu Customer: 333-33-3333 Mr Marco Rohr Customer: 444-44-4444 Mr Juan Napoli Customer: 555-55-5555 Mr Brian Hainey Customer: 666-66-6666 Mr Patrick Gan Customer: 777-77-7777 Mr Miguel Gomes Customer: 888-88-8888 Mr Lara Ziosi Customer: 999-99-9999 Mr Ahmed Moharram Customer: 000-00-0000 Mr Ueli Wahli

Customer: 222-22-2222 Ms Pinar Ugurlu Customer: 222-22-2222 has 3 accounts

Account: 002-222002 balance 87.96

Transactions of account: 002-222002 Type Time Amount Debit 2002-06-06 12:12:12.0 3.33 Credit 2003-07-07 14:14:14.0 6666.66 Credit 2004-01-08 23:03:20.0 700.77

Add a customer: xxx-xx-xxxx Customer: xxx-xx-xxxx Mrs Julia Roberts

Open two accounts for customer: xxx-xx-xxxx New accounts: 00x-861080 00x-414074 Customer: xxx-xx-xxxx has 2 accounts Account: 00x-861080 balance 0.00

Deposit and withdraw from account: 00x-861080

第 14 章 EJB アプリケーションの開発 39

Page 46: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

Account: 00x-861080 balance 666.66 Type Time Amount Debit 2008-08-13 16:40:15.203 111.11 Credit 2008-08-13 16:40:15.203 777.77

Close the account: 00x-861080

Update the customer: xxx-xx-xxxx Customer: xxx-xx-xxxx Mr Julius Roberto

Delete the customer: xxx-xx-xxxx

Retrieve non existing customer: customer:null

End

テスト・アプリケーションの視覚化

生成されたクラス図に、ビジネス・インターフェース、エンティティー、およびサーブレットを追加して、クラス図を拡張できます ( 図 14-18)。

図 14-18 テスト用 Web アプリケーションのクラス図

40 Rational Application Developer V7.5 プログラミング・ガイド

Page 47: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

EJB 3.0 Web アプリケーションの作成

RAD75EJBWeb アプリケーションは、基本的には以前の Redbooks 文書の RAD7BankBasicWeb アプリケーションのコピーです。ただし、JPA エンティティーを使用し、EJBBankBean セッション Bean 経由でエンティティーにアクセスします。

RAD75EJBWeb アプリケーションの実装

元の RAD57BankBasicWeb アプリケーションを、EJB 3.0 API を使用して EJBBankBean セッション Bean と通信するように変更します。

完成したアプリケーションは、次の場所の交換ファイルからインポートできます。

c:\7672codesolution\ejb\RAD75EJBWeb.zip

Web アプリケーション・ナビゲーションWeb ページ間のナビゲーションを図 14-19 に示します。

図 14-19 Web サイト・ナビゲーション

� ホーム・ページ (index.jsp) から、3 つの静的ページ (rates.jsp、insurance.jsp、および redbank.jsp) に移動できます。

� redbank.jsp は顧客向けのログイン・パネルです。

� ログイン後に、顧客の詳細と口座リストが表示されます (listAccounts.jsp)。

� 口座のリストから口座が選択されると、その口座の詳細と、トランザクション・リスト、預け入れ、引き出し、および送金操作用のフォームが表示されます (accountDetails.jsp)。

� 口座の詳細フォームから、バンキング・トランザクションが実行されます。

– トランザクション・リストは、以前の借方および貸方トランザクションのリストを表示します (listTransactions.jsp)。

– 預け入れ、引き出し、および送金操作が実行され、更新された口座情報が同じページに表示されます。

� 追加機能として、口座の削除、顧客情報の更新、顧客への口座の追加、および顧客の削除があります。

� エラーが発生した場合、エラー・ページが表示されます (showException.jsp)。

JSP が基礎としているテンプレートのヘッダーとフッターにより、ナビゲーション・バーが提供されます。

/theme/itso_jsp_template.jtpl, nav_head.jsp, footer.jsp

第 14 章 EJB アプリケーションの開発 41

Page 48: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

サーブレットとコマンド多くのサーブレットが、Web ページの処理およびページ間の切り替えを実行します。

� ListAccounts — 顧客のログインおよび顧客と口座の取得を行い、accountDetails.jsp に進みます。

� AccountDetails — 口座を 1 つ取得し、accountDetails.jsp に進みます。

� PerformTransaction — フォームの値を検証し、コマンド (ListTransactionsCommand、DepositCommand、WithdrawCommand、または TransferCommand のいずれか ) を呼び出します。これらのコマンドは、要求されたバンキング・トランザクションを実行し、listTransactions.jsp または accountDetails.jsp に進みます。

� UpdateCustomer — 顧客情報の更新、また顧客の削除も行います。

� DeleteAccount — 口座を削除し、listAccounts.jsp に進みます。

� NewAccount — 口座を作成し、listAccounts.jsp に進みます。

� Logout — ログアウトし、ホーム・ページを表示します。

Java EE の依存関係エンタープライズ・アプリケーション (RAD75EJBWebEAR) には、Web モジュール (RAD75EJBWeb)、EJB モジュール (RAD75EJB)、および JPA ユーティリティー・プロジェクト (RAD75JPA) が含まれています。

Web モジュール (RAD75EJBWeb) には EJB モジュール (RAD75EJB) への依存関係が存在し、このモジュールには JPA プロジェクト (RAD75JPA) への依存関係が存在します。

セッション EJB へのアクセスデータベースのすべての処理は、EJBBankBean セッション Bean を経由し、ビジネス・インターフェース (EJBBankService) を使用して行われます。

サーブレットは、EJB 3.0 注入を使用してセッション Bean にアクセスします。

@EJB EJBBankService bank;

この注入の後では、次のようなセッション Bean のすべてのメソッドを呼び出すことができます。

Customer customer = bank.getCustomer(customerNumber);Account{} accounts = bank.getAccounts(customerNumber);bank.deposit(accountId, amount);

追加機能元の Web アプリケーションは、EJB 3.0 モジュールの一部の機能を実行しません。ここでは、アプリケーションを改良して、次の機能を追加しました。

� 顧客の詳細パネル (listAccounts.jsp) に、次の 3 つのボタンを追加しました。

– New Customer— 「Title」、「First name」、「Last name」のフィールドにデータを入力してから、「New Customer」をクリックします。ランダムな社会保障番号で顧客が作成されます。

– Add Account — このアクションは、ランダムな口座番号で残高が 0 の口座を顧客に追加します。

– Delete Customer — 顧客とすべての関連口座を削除します。

42 Rational Application Developer V7.5 プログラミング・ガイド

Page 49: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

顧客の追加と削除を行うロジックは、UpdateCustomer サーブレットにあります。新規口座用のロジックは、新しい NewAccount サーブレットにあります。

� 口座の詳細ページ (accountDetails.jsp) に、次のボタンを追加しました。

Delete Account — 口座と、そのトランザクションすべてを削除します。次に、顧客が残りの口座とともに表示されます。

口座の削除用のロジックは、新しい DeleteAccount サーブレットにあります。

� ログイン・パネルにロジック (ListAccounts サーブレット内 ) を追加し、ユーザーが社会保障番号の代わりに姓を入力できるようにしました。

ssn による検索が失敗した場合、この部分名を持つすべての顧客が取得されます。この取得結果が 1 件だけの場合は、その結果を受け入れてその顧客を表示します。したがって、Ro% などの部分名を入力して、Rohr という顧客を検索することができます。

Web アプリケーションの実行

Web アプリケーションを実行する前に、ITSOBANK データベースのデータ・ソースが構成されている必要があります。詳しくは、「ITSOBANK データベースのセットアップ」 (24 ページ ) を参照してください。Enhanced EAR を RAD75EJBWebEAR アプリケーションで構成するか、サーバーにデータ・ソースを定義することができます。「付録 B: Additional material」の「Configuring the data source in WebSphere Application Server」で説明されているように、サーバーにデータ・ソースを定義する方法をお勧めします。

Web アプリケーションを実行するには、次の手順に従います。

� 「サーバー」ビューでサーバーを右クリックし、「プロジェクトの追加および除去」を選択します。RAD75EJBEAR アプリケーションを削除し、RAD75EJBWebEAR アプリケーションを追加して、「終了」をクリックします。

� RAD75EJBWeb プロジェクトを右クリックし、「実行」→ 「サーバーで実行」を選択します。

� プロンプトが表示されたら、「WebSphere Application Server v7.0」を選択します。

� ホーム・ページが表示されます。「Redbank」をクリックしてログイン・ページに移動します ( 図 14-20)。

第 14 章 EJB アプリケーションの開発 43

Page 50: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

図 14-20 RedBank: ログイン

� 顧客番号「222-22-2222」を入力し、「Submit」をクリックします。顧客の詳細と、口座のリストが表示されます ( 図 14-21)。

図 14-21 RedBank: 顧客と口座

� 口座「002-222001」をクリックすると、詳細とアクションが表示されます (図 14-22)。

222-22-2222

44 Rational Application Developer V7.5 プログラミング・ガイド

Page 51: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

図 14-22 RedBank: 口座の詳細

� 「List Transactions」を選択し、「Submit」をクリックします。トランザクションの一覧が表示されます ( 図 14-23)。

図 14-23 RedBank: トランザクション

� 「Account Details」をクリックして、口座に戻ります。

� 「Deposit」を選択し、金額「.33」を入力して「Submit」をクリックします。残高が「65,485.00」に更新されます。

� 「Withdraw」を選択し、金額「485」を入力して「Submit」をクリックします。残高が「65,000.00」に更新されます。

� 「Transfer」を選択し、金額「1000」と送金先口座「002-222002」を入力して「Submit」をクリックします。残高が「64,000.00」に更新されます。

� 「List Transactions」を選択し、「Submit」をクリックします。トランザクションが一覧で表示され、エントリーが 3 件追加されています ( 図 14-24)。

第 14 章 EJB アプリケーションの開発 45

Page 52: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

図 14-24 RedBank: 追加されたトランザクション

� 「Account Details」をクリックして、口座に戻ります。「Customer Details」をクリックして、顧客に戻ります。

� 2 番目の口座をクリックして「Submit」をクリックすると、2 番目の口座に送金操作のトランザクションが存在することが確認できます。

� 顧客の詳細に戻り、姓を変更して「Update」をクリックします。顧客情報が更新されます。

� 名前を「Julia Roberts」と上書きし、「New Customer」をクリックします。

� 「Add Account」をクリックすると、口座が顧客に追加されます ( 図 14-25)。

46 Rational Application Developer V7.5 プログラミング・ガイド

Page 53: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

図 14-25 RedBank: 新規顧客と新規口座

� 新しい口座に対して、いくつかのトランザクションを実行します。

� 顧客の詳細に戻り、「Delete Customer」をクリックします。

� ログイン・パネルで、「Ro%」と入力し、「Submit」をクリックします。Rohr という名前の顧客が見つかり、表示されます。

� ログイン・パネルで不正な値を入力し、「Submit」をクリックします。顧客の詳細パネルが表示され、姓の部分に「NOT FOUND」と表示されます。

� 「Logout」をクリックします。

クリーンアップ

サーバーから RAD75EJBWebEAR アプリケーションを削除します。

リモート・インターフェースの追加

JUnit およびいくつかの Web アプリケーションを使用するテストのため、EJBBankBean セッション Bean のリモート・インターフェースも作成します。

� RAD75EJB プロジェクトの itso.bank.service パッケージに、EJBBankService ビジネス・インターフェースを拡張する EJBBankRemote という名前のインターフェースを作成します。

� インターフェースに、すべての顧客を取得する getCustomersAll というメソッドを追加します。

� @Remote 注釈 ( アノテーション ) を追加します。

� このリモート・インターフェースを 例 14-19 に示します。

例 14-19 セッション Bean のリモート・インターフェース

package itso.bank.service;import itso.bank.entities.Customer;import javax.ejb.Remote;@Remote

第 14 章 EJB アプリケーションの開発 47

Page 54: Front cover Rational Application Developer V7public.dhe.ibm.com/software/dw/jp/rational/library/am/cms/rsdp/radr… · JDK、JMX、JNI、JRE、JSP、JVM、MySQL、Sun、Sun Java、およびすべての

public interface EJBBankRemote extends EJBBankService {public Customer[] getCustomersAll();

}

� EJBBankBean セッション Bean を開きます。

– EJBBankRemote インターフェースを実装リストに追加します。

– getCustomers メソッドと類似の getCustomersAll メソッドを、getCustomers 名前付き照会を使用して ( パラメーターなしで ) 実装します。

public class EJBBankBean implements EJBBankService, EJBBankRemote {............public Customer[] getCustomersAll() {

System.out.println("getCustomers:all");Query query = null;try {

query = entityMgr.createNamedQuery("getCustomers");List<Customer> beanlist = query.getResultList();Customer[] array = new Customer[beanlist.size()];return beanlist.toArray(array);

} catch (Exception e) {System.out.println("Exception:" + e.getMessage());return null;

}}

}

EJB アプリケーション交換ファイルの完成

完成したエンタープライズ・アプリケーションは次の場所にあります。

C:\7672codesolution\ejb

その他の情報

EJB の詳細については、次のリソースをお勧めします。

� WebSphere Application Server Version 6.1 Feature pack for EJB 3.0 ( 英文 ) (Redbooks: SG24-7611)http://www.redbooks.ibm.com/abstracts/sg247611.html

� EJB 2.0 Development with WebSphere Studio Application Developer ( 英文 ) (Redbooks: SG24-6819)http://www.redbooks.ibm.com/abstracts/sg246819.html

� Java EE Enterprise JavaBeans technology ( 英文 )http://java.sun.com/products/ejb/

� Mastering Enterprise JavaBeans 3.0 ( 英文 )http://www.theserverside.com/tt/books/wiley/masteringEJB3/index.tss

48 Rational Application Developer V7.5 プログラミング・ガイド