感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

JBoss4でJndi lookup、キュー(Queue)の取得、JMSメッセージを送信するexample

<スポンサーリンク>

登録されているJNDI名を調べる

jmx-consoleで「service=JNDIView」をクリックする。
java.lang.String listXML()をinvokeする。
すると、JBossに登録されているJNDIの一覧がブラウザに表示される。
たとえば、こんな感じ。
これらを使ってJNDIのルックアップ処理を行う。

testQueue
org.jboss.mq.SpyQueue

QueueConnectionFactory
org.jboss.naming.LinkRefPair

たとえば、Agent Viewで「QueueConnectionFactory」を検索したら、
「alias=QueueConnectionFactory」が見つかるだろう。
こいつをクリックしてみると、

JndiName	java.lang.String	QueueConnectionFactory

みたいにJBossでQueueConnectionを見つけるためのJNDI名がvalueとして書かれているはずだ。
素直にこいつを使ってあげればいい。

jbossmq-destinations-service.xmlを編集する

$JBOSS_HOME\deploy\jms以下に、jbossmq-destination-service.xmlというのがある。
これに、JBossでJMSを使うために必要なQueueを定義する必要がある。
デフォルトで色々書いてあるが、今回はわかりやすいように、

  <mbean code="org.jboss.mq.server.jmx.Queue"
	 name="jboss.mq.destination:service=Queue,name=testQueue">
    <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
    <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends>
    <attribute name="MessageCounterHistoryDayLimit">-1</attribute>
    <attribute name="SecurityConf">
      <security>
        <role name="guest" read="true" write="true"/>
        <role name="publisher" read="true" write="true" create="false"/>
        <role name="noacc" read="false" write="false" create="false"/>
      </security>
    </attribute>
  </mbean>

を使う。
name=testQueueのところがJNDI名となる。

queueにメッセージを送るサンプル

さて、ここまでJBossのJMSキューを使う準備をしてきたので、実際に使ってみよう。
MBeanサービスとして、JMSにメッセージを送信するサンプルを作る。
MBeanの作り方とかsarファイルについては、このブログに以前にも書いたので、ブログ内検索で「MBean」とか「sar」とかで調べてみてほしい。

まずはinterfaceの部分。

package sample.jndi;

public interface JndiLookupSampleServiceMBean {
	void setJndiName(String name);
	void jndiLookupSample();
}

次に、interfaceを実装する部分。

package sample.jndi;

import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JndiLookupSampleService implements JndiLookupSampleServiceMBean {
	private String jndiName;
	private Queue queue;
	private QueueSender queueSender;
	private QueueSession queueSession;
	private QueueConnection queueConnection;

	public void jndiLookupSample() {
		try {
			//キューを取得する
			if("".equals(jndiName) || jndiName == null) {
				jndiName = "queue/testQueue";
			}
			String msg = "Hello JBoss JMS!";

			System.out.println("JNDI名:" + jndiName);
			InitialContext ic = new InitialContext();
			QueueConnectionFactory queueFactory = (QueueConnectionFactory)ic.lookup("QueueConnectionFactory");

			System.out.println("コネクションファクトリ:" + queueFactory.toString());

			queueConnection = queueFactory.createQueueConnection();
			queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

			queue = (Queue) ic.lookup(jndiName);
			System.out.println(jndiName + "=" + queue.toString());
			queueSender = queueSession.createSender(queue);

			//メッセージ送信してみる
			System.out.println("キューにメッセージを送信します");
			TextMessage message = queueSession.createTextMessage();
			message.setText(msg);
			queueSender.send(message);

			//close処理
			System.out.println("キューへの接続を閉じます");
			//メッセージの終了を表す非テキスト制御メッセージを送信する
			queueSender.send(queueSession.createMessage());
			queueSender.close();
			queueSession.close();
			queueConnection.close();


		} catch (NamingException e) {
			e.printStackTrace();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}

	public String getJndiName() {
		return jndiName;
	}

	public void setJndiName(String jndiName) {
		this.jndiName = jndiName;
	}
}

これを\deploy\test.sar\META-INF\jboss-service.xmlにサービスとして登録する。

<?xml version="1.0" encoding="UTF-8"?>

<server>
  <mbean code="sample.jndi.JndiLookupSampleService" name="sample.jndi:service=JndiLookupSample">
    <attribute name="JndiName">queue/testQueue</attribute>
  </mbean>
</server>

さて、ここまでやったところでJBossを再起動する。

jmx-consoleから「service=JndiLookupSample」を探して、
「void jndiLookupSample()」をinvokeする。
すると、以下のように、キューのコネクションがとれたり、キューが取得できたことが確認できる。

22:34:46,745 INFO  [Server] JBoss (MX MicroKernel) [4.2.3.GA (build: SVNTag=JBoss_4_2_3_GA date=200807181417)] Started in 8s:950ms
22:34:57,901 INFO  [STDOUT] JNDI名:queue/testQueue
22:34:57,910 INFO  [STDOUT] コネクションファクトリ:org.jboss.resource.adapter.jms.JmsConnectionFactoryImpl@108c1b7
22:34:57,974 INFO  [STDOUT] queue/testQueue=QUEUE.testQueue
22:34:57,979 INFO  [STDOUT] キューにメッセージを送信します
22:34:57,985 INFO  [STDOUT] キューへの接続を閉じます

次にやることは、キューのメッセージを受け取る側(取り出す)の実装。
長くなったので、続きはこちらに書いた。次はキューに突っ込んだメッセージを取り出すサンプル。
http://programming-10000.hatenadiary.jp/entry/20131031/1383152680

読んだ本

標準J2EEテクノロジー〈1〉基礎から学ぶEJB (Super Java Books)

標準J2EEテクノロジー〈1〉基礎から学ぶEJB (Super Java Books)

  • 作者: マーティンボンド,デビーロー,ピーターロクスバーグ,ダンヘイウッド,アンディロングショー,Martin Bond,Debbie Law,Peter Roxburgh,Dan Haywood,Andy Longshaw,ウルシステムズ株式会社,千菊健,トップスタジオ
  • 出版社/メーカー: 翔泳社
  • 発売日: 2003/03
  • メディア: 単行本
  • クリック: 5回
  • この商品を含むブログ (3件) を見る
JBossでJMSをどうやって実装するかはめちゃくちゃ手こずった。
リファレンスが英語だけ、というか英語だけにしてもサンプルが少ない&J2EEが難しいなど色々と苦しい場面があったけど、この本に救われた。
というか、市販されたEJBとかJ2EE系の本はだいたい買って調べた。
少しずつだけど、前進してる気がする。技術の道は、深く険しい。