レベル: 中級 T.Rob Wyatt (t.rob.wyatt@us.ibm.com), IT Specialist, IBM Bobby Woolf, ISSW WebSphere J2EE Consultant, IBM Kulvir Singh Bhogal (kbhogal@us.ibm.com), Senior IT Specialist, IBM
2006年 10月 25日 IBM® WebSphere® MQ V6.0 でメッセージを送受信する J2SE アプリケーションの開発方法を学んでください。この方法で開発するアプリケーションは J2EE™ の標準 JMS と JNDI API を使用しますが、J2EE アプリケーション・サーバーでのデプロイメントは必要ありません。
IBM WebSphere 開発者向け技術ジャーナルより。
はじめに
記事「Developing a standalone Java application for WebSphere MQ」では、IBM WebSphere MQ V5.3 を、J2SE (Java 2 Standard Edition) アプリケーション (具体的には、J2EE (Java 2 Enterprise Edition) アプリケーション・サーバーでは実行しないアプリケーション) の JMS (Java™ Messaging Service) および JNDI (Java Naming and Directory Interface) プロバイダーとして使用する方法を紹介しました。この記事でも同じ話題を取り上げますが、今回の主役は WebSphere MQ V6.0 です。WebSphere MQ V6.0 には現在、基本製品の一部として JMS アプリケーションの作成に必要な JMS クラスが組み込まれているだけでなく、パブリッシュ/サブスクライブ・ブローカーとして JMS トピックをインプリメントする固有の機能も備わっています。その結果、アプリケーション開発が一層単純化され、デプロイメントの時間もされ、管理しやすいプラットフォームとなっています。
この記事に記載するサンプル・コードと構成は、上記の変更内容を考慮して見直されています。また、この記事には、JSM 1.1 の統一ドメイン・クラス、例外処理、トランスポート・バインディング、そしてその他のベスト・プラクティスに関するセクションも追加されています。最初の記事を読んだ読者にとっても、有益な情報が豊富に追加された記事となっているはずです。
なぜスタンドアロン JMS アプリケーションなのか
何故 J2EE 環境の外で動作する JMS メッセージング・プログラムを作成する必要があるのだろうかと疑問に思う方もいることでしょう。J2EE がメッセージング機能として大きな脚光を浴びていることは確かですが、メッセージングは J2EE が登場する以前にもあり、その頃のメッセージングを使用していたタスクの多くは今でも行う必要があります。バッチ・ジョブ、ブリッジ、変換、ユーティリティー、管理、インスツルメンテーション、監視、そして実際のイベントの通知をはじめとするこのようなタスクには、J2EE 環境は大げさすぎるか、あるいは単に不適切です。ただし J2EE 環境外でコードを作成しても、JMS を使用できなくなるわけではありません。Java がプログラミング言語として好まれ、JMS が Java の標準メッセージング API であることを考えると、本来の疑問は、どうして JMS を使用してこれらのメッセージ要件に適合させようとしないのか、ということになります。
JMS アプリケーションの層
実行中の JMS アプリケーションには、図 1 に示すように以下の 3 つのコード層があります。
-
JMS アプリケーション - プロバイダーに依存しません。JNDI を使用した JMS を介してプロバイダーにアクセスします。
-
JMS インプリメンテーション - プロバイダー固有の JMS オブジェクトです。
-
メッセージング・プロバイダー - メッセージング・システム自体で、この例では WebSphere MQ です。
図 1. JMS アプリケーションの層
図 1 に示されているように、アプリケーション・コードはメッセージング・プロバイダーに直接アクセスしません。アクセスは、プロバイダー固有のコード層によって実現されます。アプリケーション・コードとプロバイダー固有のコード層の間では、個々のオブジェクトが JNDI を介してアクセスします。
JMS では JMS インプリメンテーション層とプロバイダー層の詳細がほとんど隠されているため、Java 開発者は通常、プロバイダーに依存しない JMS アプリケーションを作成できます。ただし、このアプリケーションはプロバイダーと連動するように構成しなければならないため、JMS プロバイダーの管理者は当然、JMS インプリメンテーション層を理解する必要があります。JMS 仕様では、プログラミング API については記述していますが、インプリメンテーションの詳細はベンダーに任せています。標準 JMS API はインプリメンテーションの詳細を Java 開発者には見せませんが、JMS プロバイダーの管理者は、ベンダーの製品によって異なる構成の詳細を知っていなければなりません。
JMS アプリケーション、JMS インプリメンテーション、そしてメッセージング・プロバイダーがどのように相互作用するかを理解することは重要なので、ここからは、それぞれについて順に説明していきます。まずは、プロバイダーから始めましょう。
メッセージング・プロバイダー
メッセージング・プロバイダーは、プロセス間での信頼性の高いメッセージ転送をネットワーク接続全体で行います。メッセージング・プロバイダーが JMS をサポートする必要は必ずしもありません。例えば、WebSphere MQ は JMS 仕様のはるか以前からあり (旧称 IBM MQSeries)、今でも Java 以外の多数のアプリケーションでは、JMS を使用せずに WebSphere MQ を使用しています。ただしこの記事では、メッセージング・プロバイダーは WebSphere MQ で、アプリケーションはそのオプションの JMS インターフェースを使ってアクセスすることを前提とします。
WebSphere MQ は 1 つ以上のキュー・マネージャーとして稼動します。それぞれのキュー・マネージャーは一連のプロセスで、これらのプロセスがキュー・セットの定義、キュー内に含まれるメッセージの編成、メモリーおよびディスクでのメッセージの保管、そしてメッセージング・クライアントとその他のキュー・マネージャー間でのメッセージ転送を行います。WebSphere MQ はキューを使ってポイント・ツー・ポイント・メッセージングをインプリメントします。パブリッシュ/サブスクライブ・ブローカーとして知られる WebSphere MQ プロセスは、ネイティブ WebSphere MQ キューをデータ・ストアとして使用して、パブリッシュ/サブスクライブ機能を実行します。WebSphere MQ はこれらの機能によって、JMS キューおよびトピックをインプリメントします。
WebSphere MQ キュー・マネージャーに相当する JMS オブジェクトはありません。また、キュー・マネージャーの起動と停止、WebSphere MQ オブジェクトの定義と削除などの管理タスクや構成タスク、あるいはその他の WebSphere MQ 固有の管理タスクをプログラマチックに実行する JMS API もありません。そのため、基本的な WebSphere MQ 管理を十分理解して、キュー・マネージャーが実行中であること、そしてキュー・マネージャーが JMS アプリケーションに適切なリソースで構成されていることを確実にする必要があります。これは、ご使用の環境では WebSphere MQ Administrator によって実行できます。
パブリッシュ/サブスクライブ・メッセージング・ドメインに興味がある場合、WebSphere MQ では、パブリッシュ/サブスクライブ・ブローカーはキュー・マネージャーの起動時に自動的に起動しないことを覚えておいてください。キュー・マネージャーを起動した後、ブローカーも起動しておかないと、アプリケーションはパブリッシュ/サブスクライブ・メッセージングを実行できません。WebSphere MQ V6 以降では、キュー・マネージャーが起動と停止を制御するようにブローカーを構成することも可能です。
クライアント・モードとバインディング・モード
WebSphere MQ では、アプリケーションは 2 通りの方法で WebSphere MQ キュー・マネージャーに接続できます。この 2 つの方法はそれぞれ、バインディング・モード、クライアント・モードと呼ばれます。2 つのモードの違い、そして各モードの利点と欠点を理解しておくことが重要です。
-
バインディング・モードは WebSphere MQ 固有の接続モードです。バインディング・モードでは、JMS アプリケーションをキュー・マネージャーと同じホスト・マシンで実行して、この 2 つを IPC (Inter-Process Communication) プロトコルで通信させます。
-
クライアント・モードでは通常 TCP/IP 上で、JMS アプリケーションがキュー・マネージャーのエージェント・プロセスによってネットワーク・セッションを確立します。セッションが確立すると、エージェントはバインディング・モードでキュー・マネージャーと対話し、アプリケーションに代わって API 呼び出しを実行します。
メッセージング・クライアント API については、バインディング・モードとクライアント・モードの間に違いはありません。JMS では、この 2 つのモードのすべての接続パラメーターが接続ファクトリー・オブジェクトに保管され、アプリケーションには見えないようになっています。ただし、動作については以下の重要な点を認識しておかなければなりません。
- クライアント・モードのすべての API 呼び出しは、次の 3 つのステップで実行されます。
- API 呼び出しがクライアント・アプリケーションからエージェントに送信されます。
- エージェントがキュー・マネージャーでその呼び出しを実行します。
- 呼び出しの結果がエージェントからクライアント・アプリケーションに送信されます。
上記の送受信中にネットワーク接続が切断された場合、クライアント・アプリケーションは接続が最初のステップ (API 呼び出しがエージェント・プロセスに送信される前) で切断されたのか、3 番目のステップ (呼び出し結果の送信時) で切断されたのかを判断できません。続いてクライアント・モード接続が切断されると、最後の API 呼び出しの結果が不確定になります。このためクライアント・モードを使用する (または使用する可能性がある) 場合には、処理済みセッションを使用して、明示的 commit() および rollback() メソッド呼び出しをコーディングすることが推奨されています。この方法では、アプリケーションは接続の切断後に重複したメッセージを受信することになりますが、メッセージを失うことは一切ありません。
- 基本 WebSphere MQ クライアントを使用している場合、クライアント・モードでは XA トランザクションを使用できません。IBM では、クライアント・モード接続で XA 機能を提供する Extended Transactional Client という拡張バージョンを用意しています。この拡張バージョンは別途ライセンスが必要な有料の製品なので、無料の WebSphere MQ 基本クライアントとは混同しないようにしてください。
- バインディング・モード接続では共用メモリーを使用するため、ネットワーク接続で転送した場合に伴うオーバーヘッドはありません。一方、クライアント・モードのパフォーマンスはネットワーク負荷によって変わり、接続の切断に至ることさえあります。ファイアウォールとルーターがタイムアウトによってクライアント・セッションを切断することもあります。
上記に概説した理由により、可能な限りバインディング・モードを使用しなければなりません。一方、バインディング・モードではアプリケーションと同じホスト・マシンにキュー・マネージャーがインストールされていなければなりませんが (これは常に可能だとは限りません)、クライアント・モードではアプリケーションから別のホスト・マシン上にあるキュー・マネージャーにアクセスできます。つまり、一般的にはバインディング・モードが優先されますが、クライアント・モードにも利点があるということです。原則としては、J2SE JMS アプリケーションをホストするマシンにキュー・マネージャーをインストールし、アプリケーションのアクセスにはバインディング・モードを使用するのが適切です。サンプル・コードに記載したクライアント・モードとバインディング・モード両方の接続ファクトリーを見ると、両方をインプリメントする方法がわかります。
クライアント・モード接続を許容するには、WebSphere MQ 構成の詳細がいくつか必要になります。まず、リスナー・プロセスを開始しなければなりません。WebSphere MQ には、runmqlsr という実行可能プログラムがあります。これはデフォルトでポート 1414 をリッスンします。また、クライアント・モードにはキュー・マネージャーの SVRCONN チャネル定義も必要です。接続が機能するには、接続ファクトリーにチャネル名、リスナー・ポート、そしてキュー・マネージャーのマシンのホスト名または IP アドレスが含まれていなければなりません。サンプル・コードを実行するためのリスナーとチャネルの構成については、次のセクションで説明します。
さらに、WebSphere MQ クライアントの機能を提供するには、サーバー・バージョンあるいはクライアント・バージョンのいずれにしても、最新の WebSphere MQ ソフトウェア・パッケージをインストールすることが最善であるという点にも注意してください。単にシステムから Java JAR ファイルを取り出してクライアント・マシンに再配置するという方法も可能で、現に大勢の人がこのようにしていますが、この方法ではアプリケーションは実行できても、フル・パッケージに提供されている便利なユーティリティーや診断機能の多くがインストールされません。とくに、WebSphere MQ クライアントの完全インストールによってメンテナンスやパッチの適用、そしてインストール・バージョンの照会が容易になります。この記事では、キュー・マネージャーをローカル側で作成できるように WebSphere MQ サーバーがインストールされていること、そしてクライアント・サポートも同じくインストールするオプションが選択されていることを前提とします (「参考文献」を参照して、この記事の例で使用する WebSphere MQ の試用版をダウンロードしてください)。
JMS インプリメンテーション
各プロバイダーは、そのプロバイダーの動作に特有の JMS API をインプリメントします。このプロバイダー固有のインプリメンテーションによって、JMS プログラム内のプロバイダーに依存しないコードを特定の JMS プロバイダーに接続することが可能になります。このインプリメンテーションはプロバイダーによって異なるため、JMS オブジェクトまたはメッセージング・プロバイダーの管理者は、インプリメンテーション層の構成方法を理解しておく必要があります。この記事のサンプルでのプロバイダーは WebSphere MQ なので、以下に記載するのは WebSphere MQ 固有の説明です。
JMS 管理対象オブジェクト
管理対象オブジェクトは、JMS インターフェースをインプリメントするルート・プロバイダー固有のオブジェクトで、アプリケーションが直接アクセスするものです。JMS アプリケーションは JNDI (Java Naming and Directory Interface) を使用して、レジストリーから名前を基準に管理対象オブジェクトを取得します。エントリーには、オブジェクト・タイプ (インスタンスのキューまたはトピック) など、JMS アプリケーションが使用する共通属性と、プロバイダーの JMS インプリメンテーション・クラスが使用する専用属性の両方が含まれます。レジストーで表現できるリソースのタイプはさまざまですが、JMS が主に対象とするのは、3 つのタイプの管理対象オブジェクト、接続ファクトリー、キュー、そしてトピックです。JMS アプリケーションは、この 3 つの管理対象オブジェクトを介して WebSphere MQ キュー・マネージャーと通信します。
JMS プログラムは接続ファクトリーによってキュー・マネージャーとの接続をオープンし、メッセージの送受信を行えるようにします。メッセージは、キュー・オブジェクトまたはトピック・オブジェクトを使用して作成、あるいは利用されます。JMS キューとキューの WebSphere MQ インプリメンテーションには 1 対 1 の関係がありますが、JMS トピックに直接対応する WebSphere MQ オブジェクトはありません。WebSphere MQ はパブリッシュ/サブスクライブ・ブローカーによってトピックをインプリメントします。このブローカーはブローカー制御キュー、そしてメッセージのパブリッシュ対象となるストリーム・キューを使用します。これらのランタイム詳細は WebSphere MQ の JMS インプリメンテーションの一部で、JMS アプリケーションには完全に隠されます。アプリケーションから見た WebSphere MQ のキューとトピックのインプリメンテーションは、どちらも JMS 管理対象オブジェクトとして JNDI を介してアクセスするもので、JMS 仕様に記述されているとおりに動作します。
プロバイダー固有オブジェクトが持つもう 1 つの重要な機能は、管理ポリシーあるいはビジネス要件を設定して実施することです。例えば、アプリケーション・コードにはメッセージ優先順位を指定できますが、管理対象オブジェクトでの設定によって、この優先順位をオーバーライドすることもできます。キュー、トピック、および接続ファクトリーに関するプロバイダー固有オブジェクトのプロパティーには、理解しておく価値のあるものがその他にも数多くあります。
一見すると、これらのプロバイダー固有オブジェクトは、単純なコードを実行したいだけの場合には別途学んで管理すればいいように見えますが、その底力は、コードをプロバイダーから切り離し、残りのコードを環境に依存しない移植可能なものにするところにあります。例えば、環境 (開発、テスト、実動など) やアプリケーションのリリースによってキューの名前が異なるのは一般的なことですが、WebSphere MQ 名は JMS 管理対象オブジェクト内にカプセル化されるため、アプリケーション・コードはキュー名が違っても影響を受けません。実際、ほとんどのアプリケーション・コードでは、オブジェクトがキューまたはトピックのどちらを表しているのか、あるいはどのベンダーのプロバイダーが使用されているかを既知である必要は一切ありません。プロバイダー固有オブジェクトによって、これらすべてのインプリメンテーション詳細がコードから切り離されるためです。
管理対象オブジェクトのレジストリー
JMS 管理対象オブジェクトは、JNDI API をインプリメントするディレクトリー内に登録される必要があります。JNDI によって、Java コンポーネントはリソースの保管場所、インプリメント方法、あるいはコンテナーとその JNDI プロバイダーが実際にリソースへのアクセスを可能にする方法に関わらず、固有の名前によってリソースにアクセスできるようになります。リソースはプログラムがグローバルにアクセスする必要があるオブジェクトで、JDBC (Java Database Connectivity) データ・ソース、EJB (Enterprise JavaBean) ホーム、J2EE Connector Architecture コネクターなどの場合があります。
配送時の WebSphere MQ には、WebSphere Application Server などの J2EE 環境、LDAP、そしてファイル・システム・ベースのインプリメンテーションの 3 種類のディレクトリー・サービスに対する JNDI サポートが備わっています。ファイル・システム・ベースのサービスには WebSphere MQ インストールに含まれているソフトウェアまたはハードウェア以外のコンポーネントが必要ないため、この記事ではこのサービスを使用します。JMS アプリケーションには、少なくとも 1 つの接続ファクトリーと 1 つのキューまたはトピックが必要です。次に、これらのオブジェクトを WebSphere MQ がJNDI アクセス可能レジストリー・エントリーとして表す方法について説明します。
接続ファクトリーには、アプリケーションが WebSphere MQ キュー・マネージャーに接続するために必要とするすべての情報が含まれます。アプリケーション・コードは、クライアント・モードとバインディング・モードのどちらで接続しているかということも、キュー・マネージャーの名前も知る必要はありません。アプリケーション・コードは JNDI を使用して名前を基準に接続ファクトリーを検索するだけで、キュー・マネージャーへのアクセスと接続の作成に関する下位レベルの詳細は、WebSphere MQ 固有のオブジェクトによって処理されます。
接続ファクトリーのインプリメンテーションには、20 を超える WebSphere MQ 固有のプロパティーが含まれます。デフォルト設定ではもっとも保守的なオプションが使用されますが、この記事に記載するサンプルのような単純なプログラムには十分機能します。ただし、JMS オブジェクトや WebSphere MQ を効果的に管理するには、この 2 つがどのように相互作用するかを理解しなければなりません。
JMS 1.1 では、JMS アプリケーションがキューとオブジェクトを区別する必要はありません。アプリケーション・コードでは、キューとオブジェクトはどちらもメッセージを作成または利用する単なる宛先です。ただし、キューとトピックはトランスポート・レベルでは本質的に異なるため、特定宛先のレジストリー・エントリーは、キューまたはトピックのいずれかとして明確に定義されなければなりません。JMS アプリケーションが宛先の JNDI 検索を実行すると、名前を基準として正しいオブジェクトが検出され、キューのインスタンス、またはトピックのインスタンスのどちらか一方が結果として戻されます。アプリケーションはほとんどの場合、それがキューまたはトピックのどちらを表すかに関わらず、宛先オブジェクトを使用して適宜メッセージを作成あるいは利用します。必要な場合は、instanceof 演算子を使用して特定の宛先のサブタイプを判別できます。
接続ファクトリーと同様に、キューおよびトピックのレジストリー・エントリーには、WebSphere MQ 固有のプロパティーが数多くあります。この場合も同じく、この記事の単純なデモ・アプリケーションにはデフォルト設定で十分ですが、管理者はすべてのプロパティーとその影響をよく理解してから実動アプリケーションをデプロイしなければなりません。
JMS アプリケーション
JMS アプリケーション・スタックの最上位にあるのは、JMS アプリケーション自体です。このアプリケーションは JNDI を使用して必要な各種の JMS 管理対象オブジェクトを参照し、これらのオブジェクトによって WebSphere MQ メッセージング・プロバイダーに接続します。アプリケーションが知る必要があるのは、リソースの JNDI 名だけです。JNDI 名はケース・センシティブで、完全に一致していなければなりません。
前にも述べたように、JMS の観点からすると、ポイント・ツー・ポイントのメッセージングとパブリッシュ/サブクスライブを単一のドメインに結合することがもっとも顕著な変更内容の 1 つとなっています。Queue、Topic、QueueConnectionFactory、そして TopicConnectionFactory などのドメイン固有のクラスは今でも使用できますが、これらのクラスはキューとトピックの両方に適した Destination および ConnectionFactory などの中立クラスに置き換えられています。
キュー・ドメインとトピックドメインの統合には大きな意味があるため、もう少し詳しく説明しましょう。以前の仕様では、クラス自体がドメイン固有のものであったため、アプリケーション・コードはキューまたはトピック専用に作成しなければなりませんでした。そのため、キューをトピックに変更するには、アプリケーションの記録、再コンパイル、そして再デプロイという作業が伴いました。これが言外に示す重要な意味は、宛先がキューであるかトピックであるかを設計時に把握していなければならないということです。JMS 1.1 では、実行時になるまで、どのような種類のオブジェクトが宛先になるかを知る必要がないことは珍しくありません。つまり、メッセージ・フローの概要さえわかっていれば、プログラムをコーディングできます。
この記事に記載するサンプル・コードでは、これらの統一ドメイン・クラスを使用します。このデモではキュー・マネージャーでキューとトピックを使用し、JNDI バインディングを使ってキューとトピックを切り替えます。プログラムの実行中に JNDI バインディングを変更しても、プログラムがキューとトピックに動的に切り替わらないことに注意してください。変更は、オブジェクトが JNDI で検索されないと有効になりません。この検索は通常、プログラムの初期化時に一度行われます。
サンプル・アプリケーション
JMS アプリケーションが WebSphere MQ に接続する方法が理解できたところで、今度はサンプル JMS プログラムを実行するように WebSphere MQ を構成する手順について説明します。手順の流れは、以下のとおりです。
-
WebSphere MQ を構成する
-
サンプル・コードを入手する
-
管理対象オブジェクトを構成する
-
サンプル・コードを実行する
1. WebSphere MQ を構成する
サンプル・コード用の WebSphere MQ 構成するには、以下の手順が必要です。
-
キュー・マネージャーを作成する
サンプル・コードを実行するには、キュー・マネージャーが必要です。キュー・マネージャーを作成する際に使用できるオプションは各種ありますが、ここで関心のあるキュー・マネージャーは、デッド・レター・キューで構成されるものと、デフォルト・キュー・マネージャーとして構成されるものです。
-
デッド・レター・キューは、キュー・マネージャーと Java クラスが目的の宛先に送信できないメッセージを保持するために使用します。キュー・マネージャーごとにデッド・レター・キューを持たせることがベスト・プラクティスとされています。
-
キュー・マネージャーがデフォルト・キュー・マネージャーとして構成されている場合、アプリケーションはその名前を知らなくてもアクセスできます。そのためサンプル・コードの作成が簡単になりますが、原則として、アプリケーションはこの設定に依存してはなりません。
キュー・マネージャーを新規に作成する方法はいくつかありますが、このサンプル用にもっとも簡単に作成できる方法はおそらく、以下の GUI、WebSphere MQ Explorer を使用することです。
-
Windows® のスタート・メニューから、すべてのプログラム => IBM WebSphere MQ => WebSphere MQ Explorer にナビゲートします。WebSphere MQ Explorer が実行中になったら、Queue Managers フォルダーを右クリックし、New => Queue Manager を選択して New Queue Manager ウィザードを開始します (図 2)。
図 2. 新規キュー・マネージャーの作成
-
ウィザードが開いたら、キュー・マネージャー名として JMSDEMO と入力し、Make this the default queue manager ボックスにチェック・マークを付けます。次に、デフォルトの Dead Letter Queue の名前として SYSTEM.DEAD.LETTER.QUEUE と入力します。この名前はすべて大文字で入力してください (図 3)。
図 3. キュー・マネージャーの定義
-
この時点で Finish ボタンをクリックすると、キュー・マネージャーがすべてデフォルト設定で作成されます (図 4)。デフォルト設定には、以下の設定が含まれます。
- キュー・マネージャーを即時起動させる。
- キュー・マネージャーをコンピューターのリブート時に起動するように設定する。
- 新規リスナーを作成してポート 1414 で開始する。
以上の手順で、WebSphere MQ Explorer ウィンドウに新規キュー・マネージャーが表示されます。
図 4. キュー・マネージャーのリスト
-
キューを作成する
WebSphere MQ Explorer では、キューを定義するのも至って簡単です (図 5)。
-
JMSDEMO キュー・マネージャーの横にあるプラスの記号をクリックしてフォルダー・ツリーを展開し、Queues フォルダーをクリックします。システム・キューはデフォルトでフィルタリングされますが、このキュー・マネージャーは作成したばかりなので、右側のペインに表示されるキューはありません。
-
Queues フォルダーを右クリックし、コンテキスト・メニューで New => Local Queue を選択して Local Queue ウィザードを開きます。
図 5. 新規キューの作成
-
ウィザードで、キューの名前として JMSDEMO.QL と入力し、Finish ボタンをクリックします。後で作成する JNDI ディレクトリーのエントリーは、この特定のキュー名を検索するため、この名前は図に示したとおりに入力してください (図 6)。
図 6. 新規キューの定義
ウィザードが完了すると、新規キューが Queues ウィンドウに表示されます (図 7)。
図 7. キューのリスト
-
パブリッシュ/サブスクライブを設定する
ここまでのところで、キュー・マネージャーを定義して起動し、ポイント・ツー・ポイント・メッセージングのキューを作成しました。ここで、いくつかの追加手順を実行してパブリッシュ/サブスクライブ用の設定を行います。ブローカーはその内部状態をキューに保管するため、ブローカーを起動する前にこれらのキューを作成しなければなりません。IBM ではコマンド・スクリプトにすべての定義を提供しているため、必要な作業はこのスクリプトを runmqsc コマンド・インタープリターで実行するだけです。スクリプトが完了したら、キュー・マネージャーの制御で起動および終了するパブリッシュ/サブスクライブ・ブローカーを設定します。
-
コマンド・ウィンドウを開いて、WebSphere MQ がインストールされているディレクトリーまでナビゲートします。このディレクトリーから、MQJMS_PSQ.mqsc スクリプトがある Java/bin ディレクトリーまで進みます。runmqsc を実行して、このスクリプトを入力としてリダイレクトします (図 8 を参照)。出力をファイルにリダイレクトして、後で参照できるようにします。
図 8. runmqsc スクリプトのリダイレクト
-
次に、ブローカーをサービスとして構成する必要があります。WebSphere MQ サービスはバージョン 6 の新しい機能で、これらのサービスの 1 つとして SYSTEM.BROKER という名前のサービスが提供されています。ここで必要なのは、以下のように、このサービスをキュー・マネージャーの制御下に置いてから開始することだけです。
まず始めに、WebSphere MQ コマンド・インタープリター runmqsc を開始します。コマンド alter service(SYSTEM.BROKER) control(qmgr) を実行して、SYSTEM.BROKER サービスをキュー・マネージャーの制御下に置きます。キュー・マネージャーはすでに実行中なので、最初はブローカーを手動で起動する必要があります。起動するには、コマンド start service(system.broker) を実行します (引用符で囲まれていない限り、runmqsc パラメーターは大文字・小文字の区別はしないことに注意してください)。CTRL-C で runmqsc を終了します。
このサンプルでは JMSDemo というトピックを使いますが、デフォルト設定を使用している場合は、トピックを事前に定義する必要はありません。これで、JMSDemo アプリケーションを実行するために必要な構成が完了しました。
2. サンプル・コードを入手する
デモ・アプリケーションは、zip 形式で提供されます。お好みの unzip ユーティリティーを使って、ファイルをローカル・ディスクに解凍してください。ディレクトリーを維持するオプションを選択して、ファイルがローカル・ディスクの JMSDEMO という新規ディレクトリーに解凍されるようにします。このディレクトリー内に、プログラムを実行するために必要なすべてのファイルが置かれます。これらのファイルを以下にリストするので、ひと通り把握してください。
- JMSAdmin.config - JMSAdmin ツールが JNDI レジストリー・サービスにファイル・システムを使用するように指定します。
- JMSAdmin.bat - WebSphere MQ JMS Administration ツールを実行します。
- JMSDemoPub.bat - サンプル・プログラムをパブリッシャーとして実行します。
- JMSDemoReceive.bat - サンプル・プログラムを実行してキューにあるメッセージを利用します。
- JMSDemoSend.bat - サンプル・プログラムを実行してキューにメッセージを作成します。
- JMSDemoSub.bat - サンプル・プログラムをサブスクライバーとして実行します。
- jmsdemoJNDIbindings.scp - 接続ファクトリーがバインディング・モードを使用するように設定された管理対象オブジェクト定義
- jmsdemoJNDIclient.scp - 接続ファクトリーがクライアント・モードを使用するように設定された管理対象オブジェクト定義
3. 管理対象オブジェクトを構成する
サンプル・アプリケーションで使用するすべての接続ファクトリーまたは宛先は、固有の名前で JNDI ディレクトリーに登録されなければなりません。サンプル・アプリケーションはこの名前を使用して、JMS 管理対象オブジェクトを検索します。プロバイダー固有オブジェクトは、基礎となる WebSphere MQ オブジェクトの名前とプロパティーで構成されます。サンプル定義は、ダウンロード・ファイルに付属している .scp ファイルに含まれています。
管理対象オブジェクトのプロパティーによって JMS アプリケーションと WebSphere MQ 間の相互作用が制御されるため、これらのプロパティーを理解しておかなければなりません。さまざまなオブジェクト・プロパティーの設定が、JMS アプリケーションの動作とパフォーマンスに大きな影響を与えます。この構成は JMS アプリケーションの一部ではなく、実行方法の詳細は WebSphere MQ 固有のものです。
必要な管理対象オブジェクトを構成する手順は、以下のとおりです。
-
接続ファクトリーを構成する
接続ファクトリーには、キュー・マネージャー名のパラメーターを宣言する必要がありますが、パラメーターに値を含める必要はありません。このパラメーターに値を入力する場合、指定する値がキュー・マネージャー名と一致しないと接続が失敗します。値をブランクにすると、ローカル・キュー・マネージャーがデフォルト・キュー・マネージャーとして構成されている場合はバインディング・モードによって、それ以外のキュー・マネージャーの場合はクライアント・モードによって接続が成功します。サンプルでは、この値をブランクのままにしています。
トランスポート・パラメーターも同じく必須で、このパラメーターによって、JMS がクライアント・モードとバインディング・モードのどちらの接続を使用するかを指定します。クライアント・モードを使用する場合は、host、chan、および port パラメーターを指定します。
-
host - キュー・マネージャーが常駐するマシンのホスト名または IPアドレス
-
chan - キュー・マネージャーとの接続に使用する SVRCONN チャネルの名前
-
port - キュー・マネージャーがリッスンしているポート番号
接続ファクトリーの以下のパラメーターは必ず必要というわけではありませんが、ここで説明するに値する重要な役割を持ちます。
-
FAILIFQUIESCE - キュー・マネージャーが API 呼び出しを解釈してシャットダウンできるようにします。このパラメーターはデフォルトで有効に設定されます。これを無効に設定すると、キュー・マネージャーに悪影響を及ぼす可能性があります。とくに、クライアント・モード接続を使用している場合、この影響は顕著です。
-
SYNCPOINTALLGETS - アプリケーションがメッセージを損失しないようにするためのパラメーターです。クライアント・モードでアプリケーションを実行している場合、メッセージがキューから除去された後、ネットワークでアプリケーションに送信されるまでには遅延があるため、このパラメーターが特に重要になります。ネットワーク接続がこの間に切断されると、メッセージは同期点 (syncpoint) にない限り回復不可能です。接続ファクトリーでSYNCPOINTALLGETS を設定すると、確認応答されないメッセージは確実にロールバックされます。確認応答は自動的に行われるため、これによってプログラム・コードが影響されることはありません (同期点操作の詳細については、「WebSphere MQ Application Programming Guide」と「WebSphere MQ Using Java」マニュアルを参照してください)。
デモ・プログラムでは、バインディング・モード用とクライアント・モード用に構成された 2 つの接続ファクトリーのディレクトリーが定義されています。以下を参照してください。
バインディング・モードの接続ファクトリー定義は以下のとおりです (jmsdemoJNDIbindings.scp ファイルからの抜粋)。
#---------------------------------------------------------------
# Connection Factory for Bindings mode
# Delete the Connection Factory if it exists
DELETE CF(JMSDEMOCF)
# Define the Connection Factory
DEFINE CF(JMSDEMOCF) +
SYNCPOINTALLGETS(YES) +
TRAN(bind) +
QMGR( )
# Display the resulting definition
DISPLAY CF(JMSDEMOCF) |
クライアント・モードの接続ファクトリー定義は以下のとおりです (jmsdemoJNDIclient.scp ファイルからの抜粋)。
#---------------------------------------------------------------
# Connection Factory for Client mode
# Delete the Connection Factory if it exists
DELETE CF(JMSDEMOCF)
# Define the Connection Factory
DEFINE CF(JMSDEMOCF) +
SYNCPOINTALLGETS(YES) +
TRAN(client) +
HOST(localhost) CHAN(SYSTEM.DEF.SVRCONN) PORT(1414) +
QMGR( )
# Display the resulting definition
DISPLAY CF(JMSDEMOCF) |
SYSTEM.DEF.SVRCONN チャネルは、デフォルトですべてのキュー・マネージャーに存在します。このデモではこのチャネルを便宜上使用しますが、通常は SYSTEM.* オブジェクトを使用しないのがベスト・プラクティスであることを覚えておいてください。他の誰かが管理しているキュー・マネージャーでサンプルを実行する場合は、使用可能な SVRCONN チャネルを WebSphere MQ 管理者に定義してもらわなければならない場合があります。その場合は、jmsdemoJNDIclient.scp ファイルに正しいチャネル名が入力されていることを確認してください。
-
宛先を構成する
残りの定義は、jmsdemoJNDIclient.scp ファイルと jmsdemoJNDIbindings.scp ファイルに共通です。
ご存知のとおり、すべての JMS 管理対象オブジェクトは、JNDI を介してアクセス可能なディレクトリーに登録しなければなりません。ディレクトリー名をキュー名またはトピック名にマッピングするには、ディレクトリー名は WebSphere MQ には既知なので、キューまたはトピックのプロパティーを設定する必要があります。このプロパティーにはデフォルト値はなく、また、ケース・センシティブです。
FAILIFQUIESCE プロパティーは、キュー・オブジェクトとトピック・オブジェクトの両方に有効です。このプロパティーは接続ファクトリーを継承しませんが、デフォルトで正しい値である「YES」に設定されるため、サンプル定義には組み込んでいません。キュー名の WebSphere MQversion を除き、その他すべてのプロパティーも同じくデフォルト値を使用します。
キュー定義は以下のとおりです (jmsdemoJNDIclient.scp ファイルと jmsdemoJNDIclient.scp ファイルで共通)。
#---------------------------------------------------------------
# Queue Object
# Delete the Queue if it exists
DELETE Q(JMSDEMOQueue)
# Define the Queue object
DEFINE Q(JMSDEMOQueue) QUEUE(JMSDEMO.QL)
# Display the resulting Queue object definition
DISPLAY Q(JMSDEMOQueue) |
キュー関連のプロパティーの他、WebSphere MQ トピック定義にはパブリッシュ/サブスクライブ・ブローカーとの通信を容易にする多数のプロパティーが含まれます。例えば、異なるクラスのサービス、サブスクリプションの耐久性、メッセージのパブリッシュ先または読み取り元となるキューなどです。これらのプロパティーについては、自分で作成したキュー・マネージャーでデモを実行している場合はデフォルト値で十分です。他の誰かが管理しているキュー・マネージャーで実行している場合、BROKERPUBQ および BROKERSUBQ をはじめ、いくつかのプロパティーに管理者が値を指定できます。サンプル定義では、すべてデフォルト値を使っています。
トピック定義は以下のとおりです (jmsdemoJNDIclient.scp ファイルと jmsdemoJNDIclient.scp ファイルで共通)。
#---------------------------------------------------------------
# Topic Object
# Delete the Topic if it exists
DELETE T(JMSDEMOTopic)
# Define the Topic
DEFINE T(JMSDEMOTopic) TOPIC(JMSDEMOtopic)
# Display the resulting Topic definition
DISPLAY T(JMSDEMOTopic) |
-
管理対象オブジェクトをバインドする
前の手順で作成した管理対象オブジェクトは、ディレクトリーに登録してからでないと、JMS アプリケーションで使用できるようになりません。レジストリー・エントリーによって、JNDI 名をプロバイダー固有のリソースに「バインド」するように警告されます。WebSphere MQ には、JNDI がアクセス可能なディレクトリー・サービスで管理対象オブジェクトを作成および管理する管理ツールが用意されています。サンプル・コードには、WebSphere MQ JMS 管理ツールを起動するスクリプトと、使用する管理対象オブジェクトの定義スクリプトが組み込まれています。
- コマンド・プロンプトを開いて、JMSDEMO ディレクトリーに移動します。
- 図 9 に示すように、バインディング定義で JMSAdmin スクリプトを実行します。
図 9. JMSAdmin の実行
この時点で次の手順を続けてコードを実行してください。バインディング・モードでサンプルを正常に実行した後、この手順に戻って今度はクライアント・モード定義で JMSAdmin スクリプトを実行します。この場合、サンプル・コードは IPC ではなく、TCP/IP でキュー・マネージャーに接続されます。このように、サンプル・アプリケーションに影響を与えることなくバインディング・モードとクライアント・モードを自由に切り替えられます。クライアント・モードを使用しているときには、SVRCONN チャネルの状況が ACTIVE として WebSphere MQ Explorer に表示されます。
4. サンプル・コードを実行する
WebSphere MQ の構成と、JNDI ディレクトリーでの管理対象オブジェクトの定義が完了したので、この記事のサンプルをいよいよ実行できます。次の手順に従って、サンプルを実行してください。
-
ポイント・ツー・ポイントの実行例
- 3 つのコマンド・プロンプト・ウィンドウを開き、それぞれのウィンドウで JMSDEMO ディレクトリーに移動します。
- ポイント・ツー・ポイントのサンプルを実行するには、ウィンドウのうちの 1 つで JMSDemoSend.bat を実行し (図 10)、別のウィンドウで JMSDEMOReceive.bat を実行します (図 11)。この 2 つのプログラムは診断情報を表示した後、入力を待機する状態になります。
- T任意のメッセージを JMSDemoSend.bat ウィンドウに入力すると、JMSDemoReceive.bat ウィンドウにそのメッセージが表示されます。終了するには、ブランク行を入力します。
図 10. JMSDemoSend.bat ウィンドウ
図 11. JMSDemoReceive.bat ウィンドウ
最初のウィンドウ (図 10) では、「Test message」というコンテンツのメッセージを送信すると、2 つ目のウィンドウ (図 11) で、「Test message」というコンテンツのメッセージを受信したことがわかります。
-
パブリッシュ/サブスクライブの実行例
以下の手順に従って、パブリッシュ/サブスクライブのサンプルを実行します。
- strmqbrk コマンドを実行して、パブリッシュ/サブスクライブ・ブローカーが実行中であることを確認します。
- 1 つのウィンドウで JMSDemoPub.bat を実行し (図 12)、他の 2 つのウィンドウで JMSDemoSub.bat を実行します (図 13)。
- 任意のメッセージを JMSDemoPub.bat ウィンドウに入力すると、両方の JMSDemoSub.bat ウィンドウにそのメッセージが表示されます。終了するには、ブランク行を入力します。
図 12.JMSDemoPub.bat ウィンドウ
図 13. 同じ 2 つの JMSDemoSub.bat ウィンドウ
最初のウィンドウ (図 12) で「Test publication」というコンテンツのメッセージを送信すると、2 つ目と 3 つ目のウィンドウ (図 13 ) の両方で「Test publication」というコンテンツのメッセージを受信します。"
まとめ
この記事では、J2SE アプリケーションを J2EE アプリケーション・サーバー (WebSphere Application Server など) でデプロイすることなく、JMS と JNDI を使用してメッセージング・プロバイダーとしての WebSphere MQ にアクセスする方法を紹介しました。
説明した内容は、以下のとおりです。
- JMS アプリケーションの以下の 3 つの層の構成
- プロバイダーに依存しない JMS アプリケーション
- プロバイダー固有の JMS インプリメンテーション
- JMS プロバイダー
- アプリケーションがバインディング・モードまたはクライアント・モードのいずれか使用して WebSphere MQ に接続する方法
- アプリケーションが JNDI を使用して JMS インプリメンテーション層の JMS 管理対象オブジェクトにアクセスする方法
- WebSphere MQ の構成方法
- JNDI を使用して JMS 管理対象オブジェクトとしてアクセスできるように WebSphere MQ リソースを管理する方法
これで、新規および既存の Java アプリケーションをデプロイして WebSphere MQ を使用する方法がわかったはずです。
謝辞
この記事の作成を支援してくれた Graham Oakes 氏と Emir Garza 氏に感謝します。
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| Code sample | JMSDEMO.zip | 10 KB | HTTP |
|---|
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | 
|  |
T. Rob Wyatt は、IBM Software Services for WebSphere の IT スペシャリストとして、カスタマーを WebSphere MQ の管理、アーキテクチャー、セキュリティーの分野で支援しています。WebSphere MQ 管理に関する彼のこれまでの記事は Xephon MQ Update で公開されています。T. Rob は NY/NJ WebSphere MQ User Group の代表者を務め、Mid Atlantic MQSeries User Group の活動中はこのグループの統括責任者でした。現在、
MQSeries Listserv コミュニティー
で活躍しており、複数の SupportPac に貢献しています。 |
 | 
|  |
Kulvir Singh Bhogal は、IBM Software Services for WebSphere のコンサルタントとして、アメリカ全土のカスタマーのサイトで J2EE ソリューションの考案とインプリメントを行っています。 |
記事の評価
|