このタスクについて
このトピックでは、JMS クライアント・アプリケーションを開発するために必要なステップが概説されています。
このトピックでは、JMS 関連の考慮事項についてのみ説明しています。
一般的なクライアント・プログラミングについては、既に精通しているものと見なし、ここでは説明しません。
これらのステップに関する詳細や、JMS クライアントの開発例については、「Java Message Service Documentation」および WebSphere MQ の「Java の使用」資料 (SD88-7163) を参照してください。
JMS クライアントは、JMS リソース (キュー接続ファクトリーおよびキュー宛先など) が既存であることを前提としています。
クライアント・アプリケーションでは、サーバーと同一マシン上で実行されているか、
リモートで実行されているかに関係なく、
アプリケーション・サーバーまたはクライアント・コンテナーによって管理されている JMS リソースを使用することができます。
クライアント・アプリケーションの開発およびそれらの JMS リソースの構成について詳しくは、J2EE アプリケーション・クライアント・コードの開発およびその関連タスクを参照してください。
通常の JMS クライアント・プログラムが JMS を使用するための一般的なステップは、以下のとおりです。
- JMS パッケージをインポートします。
JMS を使用するエンタープライズ・アプリケーションは、JMS に関する複数のインポート・ステートメントで開始します。
以下に例を示します。
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.jms.*;
- 初期コンテキストを取得します。
try {
ctx = new InitialContext(env);
...
- クライアントが使用するパラメーターを定義します。
例えば、キュー接続ファクトリーを識別するパラメーターや、送信するメッセージをアセンブルするパラメーターなどがあります。
public class JMSppSampleClient
{
public static void main(String[] args)
throws JMSException, Exception
{
String messageID = null;
String outString = null;
String qcfName = "java:comp/env/jms/ConnectionFactory";
String qnameIn = "java:comp/env/jms/Q1";
String qnameOut = "java:comp/env/jms/Q2";
boolean verbose = false;
QueueSession session = null;
QueueConnection connection = null;
Context ctx = null;
QueueConnectionFactory qcf = null;
Queue inQueue = null;
Queue outQueue = null;
...
- JNDI ネーム・スペースから管理オブジェクトを検索します。
InitialContext.lookup() メソッドを使用して、管理オブジェクト (キュー接続ファクトリーおよびキュー宛先) を検索します。
qcf = (QueueConnectionFactory)ctx.lookup( qcfName );
...
inQueue = (Queue)ctx.lookup( qnameIn );
outQueue = (Queue)ctx.lookup( qnameOut );
...
- メッセージング・サービス・プロバイダーへの接続を作成します。
この接続により、基礎となるトランスポートへのアクセスが提供され、セッションの作成に使用されます。
ファクトリー・オブジェクトの createQueueConnection() メソッドを使用して、接続を作成します。
connection = qcf.createQueueConnection();
JMS 仕様では、接続が停止状態で作成されなければならないことが定義されています。
この接続に関連付けられた MessageConsumers は、接続が開始されるまでメッセージを受信することはできません。
接続を開始するには、以下のコマンドを発行します。
connection.start();
- メッセージを送受信するためのセッションを作成します。
このセッションは、メッセージを作成および利用するためのコンテキストを提供します。
MessageProducers および MessageConsumers の作成に使用するメソッドも含まれます。
createQueueSession メソッドは、この接続でセッションを取得するために使用します。
このメソッドは、次の 2 つのパラメーターを取ります。
- セッションが処理されるかどうかを決定するブール値。
- 応答モードを決定するパラメーター。
boolean transacted = false;
session = connection.createQueueSession( transacted,
Session.AUTO_ACKNOWLEDGE);
この例では、セッションは処理されず、受信メッセージを自動的に確認するはずです。
これらの設定では、メッセージは、システム・エラーの後か、またはクライアント・アプリケーションが予期せずに終了された場合にのみバックアウトされます。
- メッセージを送信します。
- メッセージを作成する MessageProducer を作成します。
Point-to-Point の場合、MessageProducer は、出力キュー・オブジェクト (以前に検索されたもの) をセッションの createSender メソッドに渡すことによって作成された QueueSender です。
QueueSender は、通常、特定のキューを対象に作成されます。
そのため、この送信側を使用して送信されたすべてのメッセージは同じ宛先に送信されます。
QueueSender queueSender = session.createSender(inQueue);
- メッセージを作成します。
セッションを使用して、空のメッセージを作成し、渡されたデータを追加します。
JMS は、いくつかのメッセージ・タイプを提供します。各メッセージ・タイプが、その内容の知識の一部を具体化します。
ベンダー固有のクラス名でメッセージ・タイプを参照しないようにするために、
メッセージ作成のセッション・オブジェクトにメソッドが提供されます。
この例では、テキスト・メッセージが outString プロパティーから作成されます。
これは、クライアント・プログラムの起動時に入力パラメーターとして提供されるか、
それ以外の何らかの方法で構成されます。
TextMessage outMessage = session.createTextMessage(outString);
- メッセージを送信します。
メッセージを送信するため、QueueSender の送信メソッドにメッセージが渡されます。
queueSender.send(outMessage);
- 応答を受信します。
- 何らかの応答を伴って送信されたメッセージをリンクする相関 ID を作成します。
この例では、クライアントは、JMSCorrelationID にプロバイダー固有のメッセージ ID を使用して、
送信済みのメッセージに関連する応答メッセージを受信します。
messageID = outMessage.getJMSMessageID();
メッセージ・セレクターでこの相関 ID を使用して、
この ID を持つメッセージのみを選択します。
String selector = "JMSCorrelationID = '"+messageID+"'";
- メッセージを受信する MessageReceiver を作成します。
Point-to-Point の場合、MessageReceiver は、入力キュー・オブジェクト (以前に検索されたもの) およびメッセージ・セレクターを、セッションの createReceiver に渡すことによって作成された QueueReceiver です。
QueueReceiver queueReceiver = session.createReceiver(outQueue, selector);
- 応答メッセージを検索します。
応答メッセージを検索するには、受信メソッドで QueueReceiver を使用します。
Message inMessage = queueReceiver.receive(2000);
受信呼び出しのパラメーターは、ミリ秒単位のタイムアウトです。
このパラメーターは、即時に使用可能なメッセージがない場合の、メソッドの待ち時間を定義します。
このパラメーターを省略すると、この呼び出しは無期限にブロックします。
遅延を避けるには、receiveNoWait() メソッドを使用します。
この例では、受信呼び出しは、メッセージの到着時か、2000 ミリ秒後 (いずれか早い方) に戻ります。
- 受信したメッセージに基づいた処理をします。 受信したメッセージは、クライアントのビジネス・ロジックの必要に応じて処理できます。
一般的な JMS アクションの中には、メッセージが正しいタイプであるかどうかを検査し、
そのメッセージの内容を抽出するものがあります。
メッセージの本文から内容を抽出するには、
一般的な Message クラス (受信メソッドの宣言済みの戻りの型) から、
TextMessage などの、より特化されたサブクラスへキャストする必要があります。
キャストする前に必ずメッセージ・クラスをテストすることをお勧めします。
そうすることで、予期しないエラーを慌てずに処理することができます。
この例では、オペレーターのインスタンスは、
受信したメッセージが TextMessage タイプであるかどうかを検査するために使用されます。
検査の後で、メッセージの内容は、TextMessage サブクラスへキャストすることによって抽出されます。
if ( inMessage instanceof TextMessage )
...
String replyString = ((TextMessage) inMessage).getText();
- 終了します。
アプリケーションが、セッション・レベル、またはそれ以下のレベルで、
多くの短命の JMS オブジェクトを作成する必要がある場合は、使用しているすべての JMS リソースを閉じることが重要です。
これは、リソースが必要なくなった時点で、さまざまなクラスの close() メソッド (QueueConnection、QueueSession、QueueSender、および QueueReceiver) を呼び出すことで行います。
queueReceiver.close();
...
queueSender.close();
...
session.close();
session = null;
...
connection.close();
connection = null;
- メッセージをパブリッシュおよびサブスクライブします。
Point-to-Point メッセージングの代わりに Publish/Subscribe サポートを使用する場合でも、
セッションや接続の作成など、一般的なクライアント・アクションは同じです。
例外は、以下のメッセージのパブリッシュ例に示すように、
キュー・リソースの代わりにトピック・リソースが使用されている (QueueSender の代わりに TopicPublisher が使用されるなど) ことです。
// Creating a TopicPublisher
TopicPublisher pub = session.createPublisher(topic);
...
pub.publish(outMessage);
...
// Closing TopicPublisher
pub.close();
- エラーを処理します。
すべての JMS ランタイム・エラーは、例外によって報告されます。
JMS 内のメソッドの大部分は、JMSExceptions をスローしてエラーを示します。
これらの例外をキャッチして適切な出力に表示するプログラミングを組むことをお勧めします。
一般的な Java 例外とは異なり、JMSException には別の例外を組み込むことができます。
JMSException のインプリメンテーションは、
組み込みの例外をこの toString() メソッドの出力に含みません。
したがって、下記の例に示すように、組み込みの例外を明示的に検査し、出力する必要があります。
catch (JMSException je)
{
System.out.println("JMS failed with "+je);
Exception le = je.getLinkedException();
if (le != null)
{
System.out.println("linked exception "+le);
}
}