Java Message Serviceのメッセージ受信時のトラブルシューティング
対象プラットフォーム Windows/Solaris/Linux
Java Message Service (以後JMS)は、Javaアプリケーションが作成したトピック、またはキュー (以後、キューに統一)の非同期による送受信を可能にします。Interstage
Application Serverではイベントチャネルを使用します。
JMSを利用したプログラムにおいて、メッセージ受信時にトラブルが発生することがあります。本記事では、以下のようなメッセージ受信時に発生するトラブルの回避方法を紹介します。
・キューからメッセージを受信できない場合の回避方法
・メッセージ受信時の無限ループに対する回避方法
キューからメッセージを受信できない場合の回避方法
メッセージ送受信の基本的な構成を図-1に示します。送信元からのメッセージは、キューを通じて受信先に渡します。しかし、場合によってはキューから受信できない場合があります。
ここでは、キューから受信できない場合の回避方法を説明します。

図-1 メッセージ送受信の基本構成
この構成においてメッセージの送受信を行うプログラムの例を、リスト-1、リスト-2に示します。
リスト-1 送信プログラム(Send.java)
1 try {
2 // InitialContextを作成しています
3 Context ctx = new InitialContext()
4 // QueueConnectionFactoryをJNDIから取得します
5 QueueConnectionFactory qcf = (QueueConnectionFactory)ctx.lookup(
"java:comp/env/jms/QueueFactory");
6 // QueueをJNDIから取得します
7 Queue queue = (Queue)ctx.lookup("java:comp/env/jms/Queue1");
8 // QueueConnectionFactoryからQueueConnectionを作成します
9 QueueConnection connection = qcf.createQueueConnection();
10 // QueueConnectionからQueueSessionを作成します
11 QueueSession session = connection.createQueueSession(
false, Session.AUTO_ACKNOWLEDGE);
12 // QueueSessionからQueueSender を作成します
13 QueueSender send = session.createSender(queue);
14 // QueueSessionからMessageを作成します
15 TextMessage message = session.createTextMessage("TEST");
16 // MessageをQueueに送信します
17 send.send(message);
18 // Connection を閉じます
19 connection.close();
20 System.out.println("Message is sent.");
21 } catch (NamingException ex) {
22 // JNDIのエラーを処理します
23 //(INTERSTAGEが停止している時もここで処理します)
24 System.out.println(ex.getMessage());
25 } catch (JMSException jex) {
26 // JMSのエラーを処理します
27 System.out.println(jex.getMessage());
28 }
|
リスト-2 受信プログラム(Receive.java)
1 try {
2 // InitialContextを作成しています
3 Context ctx = new InitialContext()
4 // QueueConnectionFactoryをJNDIから取得します
5 QueueConnectionFactory qcf = (QueueConnectionFactory)ctx.lookup(
"java:comp/env/jms/QueueFactory");
6 // QueueをJNDIから取得します
7 Queue queue = (Queue)ctx.lookup("java:comp/env/jms/Queue1");
8 // QueueConnectionFactoryからQueueConnectionを作成します
9 QueueConnection connection = qcf.createQueueConnection();
10 // QueueConnectionからQueueSessionを作成します
11 QueueSession session = connection.createQueueSession(
false, Session.AUTO_ACKNOWLEDGE);
12 // QueueSessionからQueueReceiver を作成します
13 QueueReceiver receive = session.createReceiver(queue);
14 // MessageをQueueから受信します。
15 TextMessage message = (TextMessage)receive.receive();
16 // 受信したメッセージを表示します
17 System.out.println(message.getText());
18 // Connection を閉じます
19 connection.close();
20 } catch (NamingException ex) {
21 // JNDIのエラーを処理します
22 //(INTERSTAGEが停止している時もここで処理します)
23 System.out.println(ex.getMessage());
24 } catch (JMSException jex) {
25 // JMSのエラーを処理します
26 System.out.println(jex.getMessage());
27 }
|
上記の送信プログラム、受信プログラムの実行結果をリスト-3に示します。
リスト-3 実行例
1 C:\>java Send 2 Message is sent. 3 4 C:\>java Recieve(応答がない状態です)
|
リスト-3の1行目で、キューに対しメッセージを送信します。正常終了した時点でメッセージはキューに蓄えられていますが、このプログラムでは4行目のメッセージ受信が復帰しない状態です。
原因は、受信側のプログラムでConnection#startメソッドを呼び出していないためです。Interstage JMSでは、Connection#startメソッドを呼び出した後、Receiver#receiveメソッドを呼び出すことで、メッセージ受信が可能になります。受信可能なプログラムの例をリスト-4に示します。
リスト-4 Connection#startメソッドの追加
<省略>
1 // QueueConnectionからQueueSessionを作成します
2 QueueSession session = connection.createQueueSession(
false, Session.AUTO_ACKNOWLEDGE);
3 // メッセージ配信を開始します
4 connection.start();
5 // QueueSessionからQueueReceiverを作成します
6 QueueReceiver receive = session.createReceiver(queue);
<省略>
|
リスト-4のように、受信プログラムの4行目にConnection#startメソッドを追加します。
また、リスト-4の実行結果をリスト-5に示します。
リスト-5 実行例
1 C:\>java Send 2 Message is sent. 3 4 C:\>java Recieve 5 TEST 6 7 C:\>
|
プログラムを実行すると、5行目に「TEST」が表示され、正常にメッセージ受信できたことが分かります。