Java EE アプリケーション入門
このドキュメントでは、Java EE 5 プラットフォームの一部である EJB 3.0 テクノロジを使用したエンタープライズアプリケーション開発の基本事項を説明します。このドキュメントは、EJB 3.0 テクノロジによってエンタープライズアプリケーション開発のプロセスがどれだけ簡単になるかを示しています。
このドキュメントでは NetBeans IDE 6.1 リリースを使用します。このドキュメントに示す手順は IDE の version 6.0 にも使用できますが、NetBeans IDE 6.1 の一部のオプションは旧リリースでは使用できません。
予想される所要時間: 30 分
チュートリアルの課題
このチュートリアルに従うには、次のソフトウェアとリソースが必要です。
| NetBeans IDE |
Web および Java EE の version 6.1 または
version 6.0 |
| Java Developer Kit (JDK) |
version 6 または
version 5 |
| GlassFish アプリケーションサーバー |
V2 |
前提条件
このドキュメントは、次のテクノロジについて基本的な知識またはプログラミング経験を持つ読者を想定して書かれています。
- Java プログラミング
- NetBeans IDE
エンタープライズアプリケーションプロジェクトの設定
この課題の目標は、EJB モジュールと Web モジュールが含まれた NewsApp エンタープライズアプリケーションプロジェクトを作成することです。NewsApp アプリケーションは、メッセージ駆動型 Bean を使用して、サーブレットがキューに送信するメッセージの受信および処理を行います。このアプリケーションは、サーブレットを使用して、メッセージ駆動型 Bean へのメッセージの送信およびメッセージの表示を行います。
エンタープライズアプリケーションの作成
- メインメニューから「ファイル」>「新規プロジェクト」(Ctrl-Shift-N) を選択します。
- 「エンタープライズ」カテゴリから「エンタープライズアプリケーション」を選択し、「次へ」をクリックします。
- プロジェクト名を NewsApp にし、プロジェクトの場所を設定します。
- 専用フォルダを使用するオプションが選択されている場合は選択を解除します。
(このオプションは、NetBeans IDE 6.1 を使用している場合に使用できます。このチュートリアルでは、ほかのユーザーやプロジェクトとライブラリを共有しないので、プロジェクトライブラリを専用フォルダにコピーする理由はほとんどありません。)
「次へ」をクリックします。
- サーバーを GlassFish に設定し、Java EE バージョンを Java EE 5 に設定します。
- 「EJB モジュールを作成」と「Web アプリケーションモジュールを作成」が選択されていない場合は選択します。
- 「完了」をクリックします。
まとめ
この課題では、EJB モジュールおよび Web モジュールを含む Java EE 5 エンタープライズアプリケーションを作成しました。
EJB モジュールのコーディング
この課題では、EJB モジュール内のオブジェクトを作成します。作成するのは、エンティティークラス、メッセージ駆動型 Bean、およびセッションファサードです。また、エンティティーを管理するための情報をコンテナに提供するための持続性ユニット、およびメッセージ駆動型 Bean が使用する Java Message Service (JMS) リソースも作成します。
持続性ユニットの作成
まず、アプリケーションで使用されるデータソースおよびエンティティーマネージャーを定義する持続性ユニットを作成します。
- EJB モジュールを右クリックし、「新規」>「その他」を選択します。
- 「持続性」カテゴリから「持続性ユニット」を選択し、「次へ」をクリックします。
- 持続性ユニットの名前はデフォルトのままにしておきます。
- 「持続性プロバイダ」には「 TopLink 」(デフォルト) を選択します。
- 「データソース」にはデータソースを選択します (たとえば JavaDB を使用する場合は jdbc/sample を選択します)。
- 持続性ユニットが Java Transaction API を使用していること、アプリケーション配備時にエンティティークラスに基づいた表が作成されるように「Table Generation Strategy」が「作成」に設定されていることを確認します。
- 「完了」をクリックします。
「完了」をクリックすると、IDE によって persistence.xml が作成され、ソースエディタの「デザイン」ビューに表示されます。persistence.xml を閉じます。
NewsEntity エンティティークラスの作成
この課題では、NewsEntity エンティティークラスを作成します。エンティティークラスは、通常はデータベース内の表を表す簡単な Java クラスです。このエンティティークラスを作成すると、クラスをエンティティークラスとして定義するための @Entity という注釈が IDE によって追加されます。このクラスを作成したあとで、表に必要なデータを表すフィールドを、クラス内に作成します。
各エンティティークラスは主キーを持つ必要があります。エンティティークラスを作成すると、IDE によって、どのフィールドを主キーとして使用するかを宣言するための @Id という注釈が追加されます。また、主 ID のキー生成方法を指定するための @GeneratedValue という注釈も IDE によって追加されます。
NewsEntity クラスを作成するには、次の手順を実行します。
- 「プロジェクト」ウィンドウで EJB モジュールを右クリックし、「新規」>「その他」を選択して「新規ファイル」ウィザードを開きます。
- 「持続性」カテゴリから「エンティティークラス」を選択し、「次へ」をクリックします。
- クラス名に「NewsEntity」を、パッケージに「ejb」をそれぞれ入力し、「主キーの型」は Long のままにしておきます。「完了」をクリックします。
「完了」をクリックすると、エンティティークラス NewsEntity.java がソースエディタに表示されます。ソースエディタで次の手順を実行します。
- このクラスに次のフィールド宣言を追加します。
private String title;
private String body;
- ソースエディタ内を右クリックし、「コードを挿入」を選択し、「取得メソッドおよび設定メソッド」を選択して、各フィールドの取得メソッドと設定メソッドを生成します。
- 「取得メソッドおよび設定メソッドの生成」ダイアログで body フィールドと title フィールドを選択し、「生成」をクリックします。
- 変更を保存します。
次の手順では、NewMessage というメッセージ駆動型 Bean を作成します。
NewMessage メッセージ駆動型 Bean の作成
今度は、EJB モジュールの NewMessage メッセージ駆動型 Bean を作成します。この Bean と必要な JMS リソースの作成には、「新規メッセージ駆動型 Bean」ウィザードを使用します。
NewMessage メッセージ駆動型 Bean を作成するには、次の手順を実行します。
- 「プロジェクト」ウィンドウで EJB モジュールを右クリックし、「新規」>「その他」を選択して「新規ファイル」ウィザードを開きます。
- 「エンタープライズ」カテゴリから、「メッセージ駆動型 Bean」を選択して「次へ」をクリックします。
- クラス名に「 NewMessage 」と入力します。
- 「パッケージ」ドロップダウンリストから「 ejb 」を選択します。
- 「プロジェクトの送信先」フィールドの横の「追加」ボタンをクリックして「メッセージ送信先を追加」ダイアログを開きます。
- 「メッセージ送信先を追加」ダイアログで「jms/NewMessage」と入力し、送信先タイプに「キュー」を選択します。「閉じる」をクリックします。
- プロジェクトの送信先が正しいことを確認し、「完了」をクリックします。
「完了」をクリックすると、新しいメッセージ駆動型 Bean クラス NewMessage.java がソースエディタに表示されます。@MessageDriven 注釈と構成プロパティーがクラスに追加されます。
@MessageDriven(mappedName = "jms/NewMessage", activationConfig = {
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
この注釈は、コンテナに対して、コンポーネントがメッセージ駆動型 Bean であることと、この Bean が使用する JMS リソースを示しています。IDE によってクラスが生成されるとき、リソースのマップされた名前 (jms/NewMessage) は、クラスの名前 (NewMessage.java) から取得されます。この JMS リソースは送信先の JNDI 名にマッピングされていて、そこから Bean がメッセージを受信します。「新規メッセージ駆動型 Bean」ウィザードによって、JMS リソースの情報がすでに sun-resources.xml に追加されています。EJB 3.0 API を使用すると、Bean クラスの内部から JNDI 名前空間のオブジェクトを検索できるため、JMS リソースを指定するための配備記述子を設定する必要はありません。
EJB 3.0 仕様では、注釈を使用してクラスに直接リソースを導入できます。ここで、注釈を使用して、クラスに MessageDrivenContext リソースを導入し、持続性エンティティーのインスタンス管理のために EntityManager API によって使用されることになる PersistenceContext リソースを注入します。クラスへの注釈の追加は、ソースエディタで行います。
- 次の注釈済みフィールド (太字部分) をクラスに追加することで、 MessageDrivenContext リソースをクラスに注入します。
public class NewMessage implements MessageListener {
@Resource
private MessageDrivenContext mdc;
- コードを右クリックし、ポップアップメニューから「持続性」>「エンティティーマネージャーを使用」を選択して、クラスにエンティティーマネージャーを導入します。
これにより、次の注釈がソースコードに追加されます。
@PersistenceContext
private EntityManager em;
また、コード内に次のメソッドが生成されます。
public void persist(Object object) {
em.persist(object);
}
- persist メソッドを修正して名前を save に変更します。メソッドは次のようになります。
public void save(Object object) {
em.persist(object);
}
- 次のコードを onMessage メソッドの本体に追加します。
public void onMessage(Message message) {
ObjectMessage msg = null;
try {
if (message instanceof ObjectMessage) {
msg = (ObjectMessage) message;
NewsEntity e = (NewsEntity) msg.getObject();
save(e);
}
} catch (JMSException e) {
e.printStackTrace();
mdc.setRollbackOnly();
} catch (Throwable te) {
te.printStackTrace();
}
- Ctrl-Shift-I キーを押して、必要なインポート文を生成します。
注: インポート文の生成時に、jms と javax.annotation.Resource の各ライブラリをインポートします。
- ファイルを保存します。
セッション Bean の作成
次に、NewsEntity エンティティークラスのためのセッションファサードを作成します。セッションファサードを作成するには、次の手順を実行します。
- EJB モジュールを右クリックし、「新規」>「その他」を選択します。
- 「持続性」カテゴリから「エンティティークラスのセッション Bean」を選択し、「次へ」をクリックします。
- 利用可能なエンティティークラスの一覧から、「ejb.NewsEntity」を選択し、「追加」をクリックしてから「次へ」をクリックします。
- 「パッケージ」が ejb に設定されていること、およびローカルインタフェースが作成されることを確認します。
- 「完了」をクリックします。
「完了」をクリックすると、セッションファサードクラス NewsEntityFacade.java が作成され、ソースエディタに表示されます。また、IDE によってローカルインタフェース NewsEntityFacadeLocal.java が作成されます。
EJB 3.0 テクノロジは、必要なコードの量を減らすことによって、セッション Bean の作成を簡素化しています。このクラスをステートレスセッション Bean コンポーネントとして宣言するために @Stateless という注釈が使用されていること、およびクラスに javax.ejb.SessionBean を実装する文が必要ないことがわかります。また、EJB 3.0 テクノロジでコードがかなり削除されたのは、チェックされた例外をスローするように宣言するコードが、ビジネスメソッドで必要なくなったためです。
セッションファサードを作成したときに、 PersistenceContext リソースが直接このセッション Bean コンポーネントに注入されたことが確認できます。
まとめ
この課題では、EJB モジュール内にエンティティークラスとメッセージ駆動型 Bean をコーディングしました。続いて、このエンティティークラスのためのセッションファサードを作成しました。また、アプリケーションで使用される JMS リソースも作成しました。
Web モジュールのコーディング
今度は、Web モジュール内に ListNews および PostMessage というサーブレットを作成します。これらのサーブレットは、メッセージの読み取りと追加に使用されます。
ListNews サーブレットの作成
この課題では、データを表示するための簡単なサーブレットを作成します。注釈を使用して、サーブレットからエンティティー Bean を呼び出します。
- Web モジュールプロジェクトを右クリックし、「新規」>「サーブレット」を選択します。
- 「クラス名」には「 ListNews 」と入力します。
- パッケージ名に「 web 」と入力し、「完了」をクリックします。
「完了」をクリックすると、 ListNews.java というクラスがソースエディタに表示されます。ソースエディタで次の手順を実行します。
- ソースコードを右クリックし、「エンタープライズリソース」>「エンタープライズ Bean を呼び出し」を選択します。
- 「エンタープライズ Bean を呼び出し」ダイアログで「NewsEntityFacade」を選択して「了解」をクリックします。「了解」をクリックすると、 @EJB という注釈を使用して、このエンティティー Bean リソースがサーブレットに注入されます。
- processRequest メソッドで、コードのコメントを解除し、次に示す太字の行をメソッド本文に追加して、メソッドを変更します。
out.println("<h1>Servlet ListNews at " + request.getContextPath () + "</h1>");
List news = newsEntityFacade.findAll();
for (Iterator it = news.iterator(); it.hasNext();) {
NewsEntity elem = (NewsEntity) it.next();
out.println(" <b>"+elem.getTitle()+" </b><br />");
out.println(elem.getBody()+"<br /> ");
}
out.println("<a href='PostMessage'>Add new message</a>");
out.println("</body>");
- Ctrl-Shift-I キーを押し、このクラスに必要なインポート文を生成します。インポート文を生成するときは、java.util ライブラリをインポートする必要があります。
- 変更内容をファイルに保存します。
PostMessage サーブレットの作成
この課題では、メッセージの投稿に使用される PostMessage サーブレットを作成します。注釈を使用して、作成した JMS リソースを直接このサーブレットに注入します。このとき、変数名と、この JMS リソースがマッピングされる名前を指定します。次に、JMS メッセージを送信するためのコードと、メッセージを追加するための HTML 形式のコードを追加します。
- Web モジュールプロジェクトを右クリックし、「新規」>「サーブレット」を選択します。
- 「クラス名」には「 PostMessage 」と入力します。
- パッケージ名に「 web 」と入力し、「完了」をクリックします。
「完了」をクリックすると、 PostMessage.java というクラスがソースエディタに表示されます。ソースエディタで次の手順を実行します。
- 次のフィールド宣言 (太字部分) を追加することにより、注釈を使用して ConnectionFactory および Queue リソースを注入します。
public class PostMessage extends HttpServlet {
@Resource(mappedName="jms/NewMessageFactory")
private ConnectionFactory connectionFactory;
@Resource(mappedName="jms/NewMessage")
private Queue queue;
- 今度は、次に示すボールドのコードを processRequest メソッドに追加し、JMS メッセージを送信するためのコードの追加を行います。
response.setContentType("text/html;charset=UTF-8");
// JMS メッセージを送信する次のコードを追加
String title=request.getParameter("title");
String body=request.getParameter("body");
if ((title!=null) && (body!=null)) {
try {
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(queue);
ObjectMessage message = session.createObjectMessage();
// ここで JMS メッセージに送信される NewsEntity を作成
NewsEntity e = new NewsEntity();
e.setTitle(title);
e.setBody(body);
message.setObject(e);
messageProducer.send(message);
messageProducer.close();
connection.close();
response.sendRedirect("ListNews");
} catch (JMSException ex) {
ex.printStackTrace();
}
}
PrintWriter out = response.getWriter();
- 続いて、HTML を出力するコードのコメントを解除し、メッセージ追加するための Web フォームを追加します。processRequest メソッドに次の太字の行を追加します。
out.println("Servlet PostMessage at " + request.getContextPath() + "</h1>");
// 次のコードで Web ページにフォームを追加
out.println("<form>");
out.println("Title: <input type='text' name='title'><br/>");
out.println("Message: <textarea name='body'></textarea><br/>");
out.println("<input type='submit'><br/>");
out.println("</form>");
out.println("</body>");
- Ctrl-Shift-I キーを押し、このクラスに必要なインポート文を生成します。
注: Connection、ConnectionFactory、Session、および Queue 用にインポートするライブラリを選択するときは、必ずjava.jms ライブラリをインポートしてください。
- 変更内容をファイルに保存します。
プロジェクトの実行
これでプロジェクトを実行できるようになりました。プロジェクトを実行すると ListNews サーブレットのページがブラウザで開かれるようにします。エンタープライズアプリケーションの「プロパティー」ダイアログで URL を指定することによって、この操作を行います。この URL はアプリケーションのコンテキストパスを基準にしたものです。この相対 URL を入力したあと、「プロジェクト」ウィンドウからアプリケーションの構築、配備、および実行を行うことができます。
相対 URL を設定し、アプリケーションを実行するには、次の手順を実行します。
- 「プロジェクト」ウィンドウで、NewsApp エンタープライズアプリケーションノードを右クリックし、ポップアップメニューの「プロパティー」を選択します。
- 「カテゴリ」区画で、「実行」を選択します。
- 「相対 URL」テキストフィールドに「/ListNews」と入力します。
- 「閉じる」をクリックします。
- 「プロジェクト」ウィンドウで NewsApp エンタープライズアプリケーションノードを右クリックし、「プロジェクトを実行」を選択します。
プロジェクトを実行すると、 ListNews サーブレットがブラウザで開き、データベース内のメッセージの一覧が表示されます。初めてプロジェクトを実行したときは、データベースは空ですが、「メッセージを追加」をクリックしてメッセージを追加できます。
PostMessage サーブレットを使ってメッセージを追加すると、持続ストレージに書き込むためのメッセージ駆動型 Bean にそのメッセージが送信され、ListNews サーブレットが呼び出されてデータベース内のメッセージが表示されます。このメッセージサービスは非同期のため、 ListNews によって取得されるデータベース内のメッセージ一覧には、新しいメッセージがまだ含まれていないことがよくあります。
トラブルシューティング
プロジェクト作成時に発生する可能性がある問題の一部を次に示します。
JMS リソースの問題
ウィザードを使用して JMS リソースを作成するとき、出力ウィンドウに次のサーバーエラーメッセージが表示される場合があります。
[com.sun.enterprise.connectors.ConnectorRuntimeException:
JMS resource not created : jms/Queue]
このメッセージは、JMS リソースが作成されなかったか、アプリケーションサーバーに登録されなかったことを示している可能性があります。アプリケーションサーバーの管理コンソールを使用すると、JMS リソースを確認、作成、および編集できます。
管理コンソールを開くには、次の手順を実行します。
- IDE の「実行時」ウィンドウにある「サーバー」ノードを展開して、アプリケーションサーバーが実行中であることを確認します。アプリケーションサーバーのノードの横に小さな緑の矢印が表示されていれば、サーバーは実行中です。
- アプリケーションサーバーのノードを右クリックし、「管理コンソールを表示」を選択して、ブラウザでログインウィンドウを開きます。
- サーバーにログインします。デフォルトのユーザー名とパスワードは、それぞれ admin と adminadmin です。
- ブラウザの管理コンソールで、左側フレームにある「リソース」ノードと「JMS リソース」ノードを展開します。
- 左側フレームの「接続ファクトリ」および「接続先リソース」リンクをクリックして、リソースがサーバーに登録されているかどうかを確認し、必要に応じてリソースを変更します。リソースが存在しない場合は、管理コンソールで作成できます。
Sun Java System Application Server に登録されている JMS 接続ファクトリリソースの正しい JNDI 名に、PostMessage サーブレットの JMS 接続ファクトリリソースがマッピングされていることを確認する必要があります。
Sun Java System Application Server には、次のリソースが登録されている必要があります。
- JNDI 名が jms/NewMessage で、型が javax.jms.Queue の接続先リソース
- JNDI 名が jms/NewMessageFactory で、型が javax.jms.QueueConnectionFactory の接続ファクトリリソース
関連項目
NetBeans IDE 6.0 を使用した Java EE アプリケーションの開発方法についての詳細は、次のリソースを参照してください。
EJB 3.0 エンタープライズ Bean の使用方法については、 Java EE 5 チュートリアル を参照してください。
nbj2ee メーリングリストに登録する ことによって、NetBeans IDE Java EE 開発機能に関するご意見やご提案を送信したり、サポートを受けたり、最新の開発情報を入手したりできます。