- メッセージング操作の場合は、
Sun の javax.jms パッケージで定義されているインターフェースへの参照のみを使用するアプリケーション・プログラムを作成する必要があります。
JMS は、基礎となるトランスポートにマップするメッセージングの一般的な視点を定義します。
JMS を使用するエンタープライズ・アプリケーションは、
Sun の javax.jms パッケージで定義されている以下のインターフェースを利用します。
- Connection
- 基礎となるトランスポートへのアクセスを提供し、
Session の作成に使用されます。
- Session
- メッセージを作成および利用するためのコンテキストを提供します。
MessageProducers および MessageConsumers の作成に使用されるメソッドも含みます。
- MessageProducer
- メッセージの送信に使用します。
- MessageConsumer
- メッセージの受信に使用します。
一般 JMS インターフェースは、
Point-to-Point および Publish/Subscribe の振る舞いの、
より特化された以下のバージョンにサブクラス化されます。
JMS 共通インターフェース
|
Point-to-Point |
パブリッシュ/サブスクライブ |
ConnectionFactory |
QueueConnectionFactory |
TopicConnectionFactory |
Connection |
QueueConnection
|
TopicConnection
|
Destination |
キュー |
トピック |
Session |
QueueSession、
|
TopicSession、
|
MessageProducer |
QueueSender
|
TopicPublisher |
MessageConsumer |
QueueReceiver、
QueueBrowser
|
TopicSubscriber |
これらの JMS インターフェースの使用に関する詳細は、
「Java Message Service Documentation」および
WebSphere MQ の「Java の使用」資料 (SD88-7163-03) を参照してください。
J2EE
specification のセクション『
"Java Message Service (JMS) Requirements"』
には、Web コンテナーおよび EJB コンテナーで呼び出してはならないメソッドのリストが記載されています。
javax.jms.Session method setMessageListener
javax.jms.Session method getMessageListener
javax.jms.Session method run
javax.jms.QueueConnection method createConnectionConsumer
javax.jms.TopicConnection method createConnectionConsumer
javax.jms.TopicConnection method createDurableConnectionConsumer
javax.jms.MessageConsumer method getMessageListener
javax.jms.MessageConsumer method setMessageListener
javax.jms.Connection setExceptionListener
javax.jms.Connection stop
javax.jms.Connection setClientID
このメソッド制限は、
javax.jms.IllegalStateException をスローすることによって IBM WebSphere Application Server で実行されます。
- アプリケーションは、管理対象オブジェクトとして
WebSphere Application Server に事前定義された JMS リソースを参照します。
エンタープライズ・アプリケーションが使用する JMS リソースの詳細は、
WebSphere Application Server に定義され、
WebSphere 管理サポートによって JNDI ネーム・スペースにバインドされます。
エンタープライズ・アプリケーションは、インプリメンテーションに関する知識がなくても、
JNDI ネーム・スペースからこれらのオブジェクトを検索し、使用することができます。
この結果、エンタープライズ・アプリケーションを変更しなくても、
JMS リソースが定義した、基礎となるメッセージング・アーキテクチャーを変更できるようになります。
エンタープライズ・アプリケーションを設計する際には、
JMS リソースの以下のタイプについて、詳細を確認する必要があります。
Point-to-Point |
パブリッシュ/サブスクライブ |
ConnectionFactory (または QueueConnectionFactory)
キュー
|
ConnectionFactory (または TopicConnectionFactory)
トピック
|
接続ファクトリーは、JMS プロバイダーからメッセージング・システムへの接続を作成するために使用され、
接続を作成するために必要な構成パラメーターをカプセル化します。
これらの JMS リソースのプロパティーの詳細については、
JMS プロバイダー・リソースの構成を参照してください。
- アプリケーション・サーバーは、JMS プロバイダーとの接続とセッションをプールすることで、
パフォーマンスを向上させます。
アプリケーションの接続とセッションのプール・プロパティーを適切に構成する必要があります。
構成が適切でないと、接続とセッションが正しく動作しない場合があります。
- アプリケーションは、JMS 接続、セッション、
およびプロデューサーまたはコンシューマーをキャッシュに入れることができます。
前述のプーリングが行われるため、
これによって期待するほどのパフォーマンスの改善は得られないこともあります。
Bean のクライアントによって開始されたトランザクションで動作する Stateless Session Bean では、
セッション・ハンドルをキャッシュに入れないでください。
この方法でハンドルをキャッシュに入れると、
Bean は、セッションがまだトランザクションに関与している間にプールに戻されます。
また前述の制限があるため、
非永続的なサブスクライバーをキャッシュに入れるべきではありません。
- 非永続サブスクライバーは、
そのサブスクライバーが作成されたときに存在していたものと同じトランザクション・コンテキスト (例えば、
グローバル・トランザクションまたは指定解除されたトランザクション・コンテキスト) でしか使用できません。
このコンテキストの制約事項について詳しくは、非永続的なサブスクライバーに対するトランザクション・コンテキストの影響を参照してください。
- デフォルトのメッセージング・プロバイダーで永続サブスクリプションを使用します。
JMS トピック上の永続サブスクリプションにより、サブスクライバーがそのサーバーに接続されていない期間の後でも、
サブスクライバーは、そのトピックにパブリッシュされるすべてのメッセージのコピーを受け取ることができます。
このため、サブスクライバー・アプリケーションは長期間サーバーと切断された状態で稼働することができ、
その後サーバーに再接続して、接続されていなかった期間にパブリッシュされたメッセージを処理できます。
アプリケーションが永続サブスクリプションを作成する場合、これは、
管理者が管理コンソールを介して表示および処理できるランタイム・リストに追加されます。
各永続サブスクリプションには、固有 ID
clientID##subName が指定されます。各部の意味は次のとおりです。
- clientID
- 接続およびそのオブジェクトを、(JMS プロバイダーのクライアントとして) アプリケーション用に保守された
メッセージと関連付けるために使用されるクライアント ID。ランタイム管理のために、永続サブスクリプションを関連アプリケーションと関連付ける必要がある場合は、
アプリケーションの識別に役立つ命名規則を使用する必要があります。
- subName
- 指定されたクライアント ID 内の永続サブスクリプションを一意的に識別するために
使用されるサブスクリプション名。
メッセージ駆動型 Bean が作成する永続サブスクリプションの場合、
これらの値は JMS activationSpec で設定されます。その他の永続サブスクリプションの場合、
クライアント ID は JMS 接続ファクトリーで設定され、サブスクリプション名は
createDurableSubscriber オペレーション上でアプリケーションによって設定されます。
トピックに対する永続サブスクリプションを
作成するために、アプリケーションは JMS API で定義される createDurableSubscriber オペレーションを使用します。
public TopicSubscriber createDurableSubscriber(Topic topic,
java.lang.String subName,
java.lang.String messageSelector,
boolean noLocal)
throws JMSException
- トピック (topic)
- サブスクライブする JMS トピックの名前。これは、適切な JNDI 項目のルックアップなどによって検出され、
javax.jms.Topic インターフェースをサポートするオブジェクトの名前です。
- subName
- このサブスクリプションを識別するために使用される名前。
- messageSelector
- メッセージ・セレクター式と一致するプロパティーを持つメッセージのみが、コンシューマーに配信されます。
ヌルの値または空ストリングは、すべてのメッセージが配信されることを示します。
- noLocal
- true に設定されている場合、永続サブスクライバーと同じ接続でパブリッシュされるメッセージの配信が妨げられます。
アプリケーションは、topic パラメーターおよび subName パラメーターのみを
取る createDurableSubscriber の 2 つの引数形式を使用することができます。この代替呼び出しは、
上記の 4 つの引数バージョンを直接呼び出しますが、messageSelector をヌルに設定し
(すべてのメッセージが配信される)、noLocal を false に設定します (この接続でパブリッシュされたメッセージが
配信される)。例えば、mySubscription というサブスクリプション名で、
myTopic と呼ばれるトピックに対して永続サブスクリプションを作成するには、次のようにします。
session.createDurableSubscriber(myTopic,"mySubscription");
createDurableSubscription オペレーションが失敗した場合は、メッセージを提供する JMS 例外、およびリンクされた例外が
スローされ、問題の原因についての詳細を示します。
永続サブスクリプションを削除するために、
アプリケーションは JMS API で定義される非サブスクライブ・オペレーションを使用します。
通常の操作では、永続サブスクリプションのアクティブな (接続された) サブスクライバーは同時に 1 つしかありません。ただし、サブスクライバー・アプリケーションは、フェイルオーバーおよびロード・バランシングの目的で、
複製されたアプリケーション・サーバーで実行することができます。
この場合、"1 つのアクティブ・サブスクライバー"の制限は、
複数の同時コンシューマーを持つことができる共用永続サブスクリプションを提供するために解除されます。
アプリケーションによる永続サブスクリプションの使用について詳しくは、
JMS 仕様のセクション『"Using Durable Subscriptions"』を参照してください。
- 必要なメッセージ・セレクターを決定します。 JMS メッセージ・セレクターのメカニズムを使用して、
キュー上のメッセージのサブセットを選択し、
そのサブセットが受信呼び出しにより戻されるようにすることができます。
セレクターは、
JMS メッセージ・ヘッダー内のフィールドとメッセージ・プロパティー内のフィールドを参照することができます。
- 受信したメッセージに基づいた処理をします。 メッセージを受信すると、
アプリケーションのビジネス・ロジックに必要な処理を行うことができます。
一般的な JMS アクションの中には、メッセージが正しいタイプであるかどうかを検査し、
そのメッセージの内容を抽出するものがあります。
メッセージの本文から内容を抽出するには、
一般的な Message クラス (受信メソッドの宣言済みの戻りの型) から、
TextMessage などの、より特化されたサブクラスへキャストする必要があります。
キャストする前に必ずメッセージ・クラスをテストすることをお勧めします。
そうすることで、予期しないエラーを慌てずに処理することができます。
この例では、オペレーターのインスタンスは、
受信したメッセージが TextMessage タイプであるかどうかを検査するために使用されます。
検査の後で、メッセージの内容は、TextMessage サブクラスへキャストすることによって抽出されます。
if ( inMessage instanceof TextMessage )
...
String replyString = ((TextMessage) inMessage).getText();
- デフォルトのメッセージング・プロバイダーを使用している JMS アプリケーションは、
WebSphere Application Server バージョン 5 の組み込みメッセージングまたは WebSphere
MQ から受け取ったメッセージの内容に、制限なしでアクセスすることができます。
- JMS アプリケーションは、JMS_IBM* プロパティーの完全なセットにアクセスすることができます。
これらのプロパティーは、
デフォルトのメッセージング・プロバイダー、V5 デフォルト・メッセージング・プロバイダー、または
WebSphere MQ プロバイダーで提供されるリソースを使用する JMS アプリケーションにとって重要です。
WebSphere MQ によって処理
されるメッセージの場合、JMS_IBM* プロパティーは同等の WebSphere MQ Message Descriptor
(MQMD) フィールドにマップされます。JMS_IBM* プロパティーおよび MQMD フィールドについて詳しくは、
「WebSphere WebSphere MQ Using Java」資料 (SQ02-2685) を参照してください。
- JMS アプリケーションでは、送信操作の結果およびそれらのメ
ッセージの結果に関するリモート・フィードバックをプロデューサー
に提供するために、レポート・メッセージを管理対象要求/応答処理の形で使用できます。
JMS アプリケーションは、
JMS_IBM_Report_Xxxx メッセージ・プロパティーを使用するレポート・オプションの全範囲を要求することができます。
JMS レポート・メッセージの使用について詳しくは、JMS レポート・メッセージを参照してください。
- JMS アプリケーションは JMS_IBM_Report_Discard_Msg プロパティーを使用して、
要求メッセージを宛先キューに配信することができない場合に、その廃棄方法を制御することができます。
- MQRO_Dead_Letter_Queue
- これはデフォルトです。要求メッセージは、送達不能キューに書き込まれます。
- MQRO_Discard
- 要求メッセージは廃棄されます。これは通常、
配信不能な要求メッセージを送信側に戻すために MQRO_Exception_With_Full_Data と一緒に使用されます。
- リスナーを使用して、非同期にメッセージを受信します。 サーブレットまたは Enterprise Bean ではなく、クライアントで、
QueueReceiver.receive() への呼び出しに代わる方法は、適切なメッセージが使用可能になると自動的に呼び出されるメソッドを登録することです。
以下に例を示します。
...
MyClass listener =new MyClass();
queueReceiver.setMessageListener(listener);
//application continues with other application-specific behavior.
...
メッセージが使用可能になると、
リスナー・オブジェクト上の onMessage() メソッドがそれを検出します。
import javax.jms.*;
public class MyClass implements MessageListener
{
public void onMessage(Message message)
{
System.out.println("message is "+message);
//application specific processing here
...
}
}
非同期メッセージ配信の場合、
アプリケーション・コードは、メッセージの受信に失敗したことにより発生した例外をキャッチできません。
これは、アプリケーション・コードが receive()methods を明示的に呼び出さないことが原因です。
この状態を処理するために、ExceptionListener を登録することができます。
これは、onException()method をインプリメントするクラスのインスタンスです。
エラーが発生すると、このメソッドは、
このメソッドの唯一のパラメーターとして渡される JMSException により呼び出されます。
メッセージを非同期的に受信するリスナーの使用の詳細については、Java
Message Service Documentation を参照してください。
- WebSphere MQ またはバージョン 5 組み込みメッセージング・サポートで認証を使用する場合は、
12 文字よりも長いユーザー ID を使用することはできません。
例えば、デフォルトの Windows NT のユーザー ID administrator は、13 文字なので、WebSphere 内部メッセージングには使用できません。
- EJB 仕様で定義されているように、
createxxxSession 呼び出しでのフラグの使用には以下の点が当てはまります。
- createxxxSession で渡されるトランザクション処理済みのフラグは、
グローバル・トランザクション内では無視され、
すべての作業がトランザクションの一環として実行されます。
トランザクション外ではトランザクション処理済みフラグが使用されます。
フラグが true に設定されている場合、
アプリケーションは session.commit() および session.rollback() を使用して、
作業の完了を制御する必要があります。
EJB2.0 モジュールでは、
トランザクション処理済みフラグが true に設定されて、XA トランザクション外にある場合、
セッションは WebSphere ローカル・トランザクションに関与しており、
メソッドの未解決のアクション属性は、アプリケーションによってコミットまたはロールバックされない場合に JMS 作業に適用されます。
- クライアントは、Message.acknowledge() を使用してメッセージを確認することはできません。
CLIENT_ACKNOWLEDGE の値が createxxxSession 呼び出しに渡されると、
メッセージは、アプリケーション・サーバーによって自動確認され、Message.acknowledge() は使用されません。
- アプリケーションで、WebSphere MQ を外部 JMS プロバイダーとして使用する場合、コンテナー管理トランザクション内でメッセージを送信します。
WebSphere MQ を外部 JMS プロバイダーとして使用する場合、ユーザー管理トランザクション内で送信されたメッセージは、トランザクションのコミット前に到達することが可能です。このことは、WebSphere MQ を外部 JMS プロバイダーとして使用し、
メッセージをユーザー管理トランザクション内の WebSphere MQ キューに送信する場合に限り発生します。トランザクションがコミットする前に、メッセージは宛先キューに到達します。
この問題の原因は、WebSphere MQ リソース・マネージャーがユーザー管理トランザクション内でリストされていないためです。
解決方法は、コンテナー管理トランザクションを使用することです。