|
以下の節では、基本的な JMS アプリケーションの開発に必要な手順について説明します。
上記のアプリケーション開発手順の他にも、設計開発時に以下の手順を任意に行うことができます。
注意 : | この章で説明する JMS クラスの詳細については、Sun Microsystems の Java Web サイトにある JMS の Javadoc を参照してください。 |
次の表に、WebLogic JMS アプリケーションで一般に使用されるパッケージを示します。
メッセージを送受信するには、あらかじめ JMS アプリケーションを設定しておく必要があります。次の図に、JMS アプリケーションの設定に必要な手順を示します。
以下の節では、この設定手順について説明します。また、ポイント ツー ポイント (PTP) およびパブリッシュ/サブスクライブ (Pub/Sub) アプリケーションの詳しい例も示します。これらの例は、WL_HOME
\samples\server\examples\src\examples\jms
ディレクトリ (WL_HOME
は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms
パッケージからの抜粋です。
設定手順に進む前に、WebLogic Server のコンフィグレーションを担当するシステム管理者が必要な JMS リソース (接続ファクトリ、JMS サーバ、送り先など) をコンフィグレーションしたことを確認してください。
接続ファクトリをルックアップするには、あらかじめ接続ファクトリをコンフィグレーション情報の一部として定義しておく必要があります。WebLogic JMS には、コンフィグレーションの一部として組み込まれているデフォルト接続ファクトリが 2 つ用意されています。このファクトリは、JNDI 名 weblogic.jms.ConnectionFactory
と weblogic.jms.XAConnectionFactory
でルックアップできます (これらは JTA トランザクションを有効化します)。管理者はコンフィグレーション時に新しい接続ファクトリをコンフィグレーションできますが、これらのファクトリにはユニークな名前を付ける必要があります。そうしないとサーバが起動しません。接続ファクトリのコンフィグレーションおよび使用できるデフォルトについては、Administration Console オンライン ヘルプの「接続ファクトリのコンフィグレーション」を参照してください。
接続ファクトリを定義したら、その接続ファクトリをルックアップするために、まず InitialContext() メソッドを使用して JNDI コンテキスト (context
) を確立します。サーブレット アプリケーション以外のアプリケーションの場合は、初期コンテキストの作成に使用する環境を渡す必要があります。
コンテキストを定義したら、JNDI で接続ファクトリをルックアップするために、以下のコマンド (PTP または Pub/Sub メッセージング用) のいずれかを実行します。
QueueConnectionFactory queueConnectionFactory =
(QueueConnectionFactory) context.lookup(CF_name
);
TopicConnectionFactory topicConnectionFactory =
(TopicConnectionFactory) context.lookup(CF_name
);
CF_name
引数には、コンフィグレーション時に定義した接続ファクトリ名を指定します。
ConnectionFactory
クラスの詳細については、「ConnectionFactory」または javax.jms.ConnectionFactory の Javadoc を参照してください。
メッセージング システムにアクセスするための接続を作成するには、次節で説明する ConnectionFactory
メソッドを使用します。
Connection
クラスの詳細については、「Connection」または javax.jms.Connection の Javadoc を参照してください。
QueueConnectionFactory
は、キュー接続を作成するための以下の 2 つのメソッドを提供します。
public QueueConnection createQueueConnection(
) throws JMSException
public QueueConnection createQueueConnection(
String userName,
String password
) throws JMSException
最初のメソッドは QueueConnection
を作成し、2 番目のメソッドは指定されたユーザ ID を使用して QueueConnection
を作成します。どちらのケースでも、接続は停止モードで作成されます。メッセージを受け付けるには、「手順 7 : 接続を開始する」で説明するとおりに接続を開始しなければなりません。
QueueConnectionFactory
クラスのメソッドの詳細については、javax.jms.QueueConnectionFactory の Javadoc を参照してください。QueueConnection
クラスの詳細については、javax.jms.QueueConnection の Javadoc を参照してください。
TopicConnectionFactory
は、トピック接続を作成するための、以下の 2 つのメソッドを提供します。
public TopicConnection createTopicConnection(
) throws JMSException
public TopicConnection createTopicConnection(
String userName,
String password
) throws JMSException
最初のメソッドは TopicConnection
を作成し、2 番目のメソッドは指定されたユーザ ID を使用して TopicConnection
を作成します。どちらのケースでも、接続は停止モードで作成されます。メッセージを受け付けるには、「手順 7 : 接続を開始する」で説明するとおりに接続を開始しなければなりません。
TopicConnectionFactory
クラスのメソッドの詳細については、javax.jms.TopicConnectionFactory の Javadoc を参照してください。TopicConnection
クラスの詳細については、javax.jms.TopicConnection の Javadoc を参照してください。
キューまたはトピックにアクセスするために 1 つまたは複数のセッションを作成するには、以降の節で説明する Connection
メソッドを使用します。
注意 : | セッションおよびそのメッセージのプロデューサとコンシューマには、一度に 1 つのスレッドしかアクセスできません。それらに複数のスレッドが同時にアクセスした場合、それらの動作は定義されません。 |
注意 : | WebLogic JMS では、単一のセッションで QueueConsumer 型と TopicSubscriber 型の MessageConsumer を一緒に使用することはできません。ただし、単一のセッションで QueueSender 型と TopicSubscriber 型 (または QueueConsumer 型と TopicPublisher 型) を 1 つずつ使用することは可能です。また、MessageProducer は型に関係なく複数使用できます。 |
Session
クラスの詳細については、「Session」または javax.jms.Session の Javadoc を参照してください。
QueueConnection
クラスは、キュー セッション作成用のメソッドを次のとおり定義します。
public QueueSession createQueueSession(
boolean transacted,
int acknowledgeMode
) throws JMSException
このメソッドでは、セッションをトランザクション処理するか (true
)、またはトランザクション処理しないか (false
) を示す boolean 型の引数と、表 2-7 で説明した非トランザクション セッションの確認応答モードを示す整数値を指定する必要があります。トランザクション セッションの場合、acknowledgeMode
属性は無視されます。この場合、メッセージは commit()
メソッドでトランザクションがコミットされたときに確認応答されます。
QueueConnection
クラスのメソッドの詳細については、javax.jms.QueueConnection の Javadoc を参照してください。QueueSession
クラスの詳細については、javax.jms.QueueSession の Javadoc を参照してください。
TopicConnection
クラスは、トピック セッション作成用のメソッドを次のとおり定義します。
public TopicSession createTopicSession(
boolean transacted,
int acknowledgeMode
) throws JMSException
このメソッドでは、セッションをトランザクション処理するか (true
)、またはトランザクション処理しないか (false
) を示す boolean 型の引数と、「非トランザクション セッションで使用する確認応答モード」で説明した非トランザクション セッションの確認応答モードを示す整数値を指定する必要があります。トランザクション セッションの場合、acknowledgeMode
属性は無視されます。この場合、メッセージは commit()
メソッドでトランザクションがコミットされたときに確認応答されます。
TopicConnection
クラスのメソッドの詳細については、javax.jms.TopicConnection の Javadoc を参照してください。TopicSession
クラスの詳細については、javax.jms.TopicSession の Javadoc を参照してください。
送り先をルックアップする場合、事前に WebLogic JMS システム管理者によって送り先がコンフィグレーションされている必要があります。送り先のコンフィグレーションについては、Administration Console オンライン ヘルプの「トピックのコンフィグレーション」および「キューのコンフィグレーション」で説明されています。Destination
クラスの詳細については、「Destination」または javax.jms.Destination の Javadoc を参照してください。
送り先がコンフィグレーションされていれば、以下のいずれかの手順を実行して送り先をルックアップできます。
JNDI コンテキスト (context
) を確立し (「手順 1 : JNDI で接続ファクトリをルックアップする」で実行済み)、以下のコマンド (PTP または Pub/Sub メッセージング用) のいずれかを実行することによって、送り先をルックアップできます。
Queue queue = (Queue) context.lookup(Dest_name
);
Topic topic = (Topic) context.lookup(Dest_name
);
Dest_name
引数には、コンフィグレーション時に定義された送り先の JNDI 名を指定します。
JNDI ネームスペースを使用しない場合は、以下の QueueSession
または TopicSession
メソッドを使用してキューまたはトピックをそれぞれ参照できます。
注意 : | createQueue() メソッドと createTopic() メソッドでは送り先が動的には作成されず、すでに存在する送り先への参照が作成されるだけです。送り先の動的な作成については、「JMS モジュール ヘルパーを使用したアプリケーションの管理」を参照してください。 |
public Queue createQueue(
String queueName
) throws JMSException
public Topic createTopic(
String topicName
) throws JMSException
queueName
または topicName
文字列の値は、以下で定義されます。
CreateDestinationIdentifier
。「JMS キュー : コンフィグレーション : 全般」および「JMS トピック : コンフィグレーション : 全般」を参照してください。これらのメソッドの詳細については、それぞれ javax.jms.QueueSession および javax.jms.TopicSession の Javadoc を参照してください。 A
string is defined by JMS_Server_Name/Module_Name!Destination_Name
(例 : myjmsserver/myModule-jms!mydestination
). Interop モジュールの送り先を参照する場合、文字列は JMS_Server_Name/interop-jms!Destination_Name
(例 : myjmsserver/interop-jms!mydestination
) で定義されます。 注意 : | WebLogic Server 9.0 より前のリリースで送り先を参照する場合は、JMS_Server_Name!Destination_Name (例 : myjmsserver!mydestination ) で定義される文字列を使用してください。 |
送り先を定義したら、以下の Queue メソッドまたは Topic メソッドを使用してキューまたはトピックにそれぞれアクセスできます。
public String getQueueName(
) throws JMSException
public String getTopicName(
) throws JMSException
キュー名とトピック名が印刷可能なフォーマットで返されるようにするには、toString()
メソッドを使用します。
createTopic()
および createQueue()
メソッドでは、「./Destination_Name
」構文を使用して、送り先をルックアップする場合のサーバ アフィニティを示すこともできます。これにより、JMS 接続の接続ファクトリ ホストと同じ JVM にローカルにデプロイされた送り先の位置が指定されます。名前がローカル JVM にない場合は、同じ名前が別の JVM にデプロイされていても例外が送出されます。
アプリケーションでこの規約を利用すると、createTopic()
メソッドおよび createQueue()
メソッドを使用する場合にサーバ名をハードコード化せずに済むので、コードを変更しなくても別の JVM でコードを再利用できます。
メッセージ プロデューサとメッセージ コンシューマを作成するには、次節で説明する Session
メソッドに送り先の参照を渡します。
注意 : | 各コンシューマはメッセージの独自のローカル コピーを受信します。受信が済んだら、ヘッダ フィールド値を変更することはできますが、メッセージ プロパティとメッセージ本文は読み込み専用です。(この時点でメッセージ プロパティまたは本文を変更しようとすると、MessageNotWriteableException が発生します)。メッセージ本文を変更するには、対応するメッセージ タイプの clearbody() メソッドを実行して、既存の内容を消去し、書き込みパーミッションを有効にします。 |
MessageProducer
クラスと MessageConsumer
クラスの詳細については、「MessageProducer と MessageConsumer」、またはそれぞれ javax.jms.MessageProducer および javax.jms.MessageConsumer の Javadoc を参照してください。
QueueSession
オブジェクトは、キュー センダとキュー レシーバを作成するための、以下のメソッドを定義します。
public QueueSender createSender(
Queue queue
) throws JMSException
public QueueReceiver createReceiver(
Queue queue
) throws JMSException
public QueueReceiver createReceiver(
Queue queue,
String messageSelector
) throws JMSException
作成するキュー センダまたはキュー レシーバに関連付けるキュー オブジェクトを指定しなければなりません。また、メッセージをフィルタ処理するためのメッセージ セレクタを指定できます。メッセージ セレクタの詳細については、「メッセージのフィルタ処理」を参照してください。
createSender()
メソッドに null 値を渡すと、匿名プロデューサが作成されます。この場合、「メッセージの送信」で説明するように、メッセージの送信時にキュー名を指定しなければなりません。
キュー センダまたはキュー レシーバの作成が済んだら、以下の QueueSender
メソッドまたは QueueReceiver
メソッドを使用して、そのキュー センダまたはレシーバに関連付けられているキュー名にアクセスできます。
public Queue getQueue(
) throws JMSException
QueueSession
クラスのメソッドの詳細については、javax.jms.QueueSession の Javadoc を参照してください。QueueSender
クラスおよび QueueReceiver
クラスの詳細については、それぞれ javax.jms.QueueSender および javax.jms.QueueReceiver の Javadoc を参照してください。
TopicSession
オブジェクトは、トピック パブリッシャとトピック サブスクライバを作成するための、以下のメソッドを定義します。
public TopicPublisher createPublisher(
Topic topic
) throws JMSException
public TopicSubscriber createSubscriber(
Topic topic
) throws JMSException
public TopicSubscriber createSubscriber(
Topic topic,
String messageSelector,
boolean noLocal
) throws JMSException
注意 : | この節で説明するメソッドでは、非恒久サブスクライバが作成されます。非恒久トピック サブスクライバは、アクティブな間だけメッセージを受信します。恒久サブスクリプションを作成して、すべてのメッセージが恒久サブスクライバに届けられるまでメッセージを保持できるようにするためのメソッドについては、「恒久サブスクリプション用のサブスクライバの作成」を参照してください。この場合、恒久サブスクライバはサブスクライバがサブスクライブした後にパブリッシュされたメッセージのみを受信します。 |
作成するパブリッシャまたはサブスクライバに関連付けるトピック オブジェクトを指定しなければなりません。また、メッセージをフィルタ処理するためのメッセージ セレクタ、および noLocal
フラグ (この節で後述) を指定することもできます。メッセージ セレクタの詳細については、「メッセージのフィルタ処理」を参照してください。
createPublisher()
メソッドに null 値を渡すと、匿名プロデューサが作成されます。この場合、「メッセージの送信」で説明するように、メッセージの送信時にトピック名を指定しなければなりません。
アプリケーションは、JMS 接続を使用して同じトピックに対してパブリッシュとサブスクライブの両方を行う場合があります。トピック メッセージはすべてのサブスクライバに届けられるので、アプリケーションは自身がパブリッシュしたことを示すメッセージを受信する可能性があります。この動作を防ぐために、JMS アプリケーションは noLocal
フラグを true
に設定できます。
トピック パブリッシャまたはトピック サブスクライバの作成が済んだら、以下の TopicPublisher
メソッドまたは TopicSubscriber
メソッドを使用して、そのトピック パブリッシャまたはサブスクライバに関連付けられているトピック名にアクセスできます。
Topic getTopic(
) throws JMSException
また、次の TopicSubscriber
メソッドを使用すると、トピック サブスクライバに関連付けられる noLocal
変数の設定値にアクセスできます。
boolean getNoLocal(
) throws JMSException
TopicSession
クラスのメソッドの詳細については、javax.jms.TopicSession の Javadoc を参照してください。TopicPublisher
クラスおよび TopicSubscriber
クラスの詳細については、それぞれ javax.jms.TopicPublisher および javax.jms.TopicSubscriber の Javadoc を参照してください。
注意 : | この手順は、メッセージ プロデューサだけに適用されます。 |
メッセージ オブジェクトを作成するには、以下の Session
クラス メソッドまたは WLSession
クラス メソッドのいずれかを使用します。
Session
メソッド注意 : | これらのメソッドは、QueueSession サブクラスと TopicSession サブクラスの両方によって継承されます。 |
public BytesMessage createBytesMessage(
) throws JMSException
public MapMessage createMapMessage(
) throws JMSException
public Message createMessage(
) throws JMSException
public ObjectMessage createObjectMessage(
) throws JMSException
public ObjectMessage createObjectMessage(
Serializable object
) throws JMSException
public StreamMessage createStreamMessage(
) throws JMSException
public TextMessage createTextMessage(
) throws JMSException
public TextMessage createTextMessage(
String text
) throws JMSException
WLSession
メソッドpublic XMLMessage createXMLMessage(
String text
) throws JMSException
Session
クラスおよび WLSession
クラスのメソッドの詳細については、それぞれ javax.jms.Session および weblogic.jms.extensions.WLSession の Javadoc を参照してください。Message
クラスとそのメソッドの詳細については、「Message」または javax.jms.Message の Javadoc を参照してください。
注意 : | この手順は、メッセージ コンシューマだけに適用されます。 |
メッセージを非同期的に受信するには、次の手順で非同期メッセージ リスナを登録する必要があります。
onMessage()
メソッドを持つインタフェース、javax.jms.MessageListener を実装します。 注意 : | onMessage() メソッドのインタフェースの例については、「例 : PTP アプリケーションの設定」を参照してください。onMessage() メソッド呼び出し内で close() メソッドを発行する場合、システム管理者は接続ファクトリをコンフィグレーションするときに [メッセージの短縮を許可] チェック ボックスを選択しなければなりません。接続ファクトリ オプションのコンフィグレーションの詳細については、『WebLogic JMS のコンフィグレーションと管理』の「接続ファクトリのコンフィグレーション」を参照してください。 |
MessageConsumer
メソッドを使用してメッセージ リスナを設定し、リスナ情報を引数として渡します。public void setMessageListener(
MessageListener listener
) throws JMSException
メッセージ リスナの設定を解除するには、null 値を指定して MessageListener()
メソッドを呼び出します。
メッセージ リスナを定義したら、次の MessageConsumer
メソッドを呼び出してそのリスナにアクセスできます。
public MessageListener getMessageListener(
) throws JMSException
注意 : | WebLogic JMS は、同じセッションの複数の onMessage() 呼び出しが同時に実行されないことを保証します。 |
メッセージ コンシューマが管理者またはサーバのダウンによってクローズされた場合、ConsumerClosedException
がセッション例外リスナに送信されます (定義されている場合)。このように、必要な場合は新しいメッセージ コンシューマを作成できます。セッション例外リスナの定義については、「セッション例外リスナの定義」を参照してください。
MessageConsumer
クラスのメソッドは、QueueReceiver
および TopicSubscriber
クラスによって継承されます。MessageConsumer
クラスのメソッドの詳細については、「MessageProducer と MessageConsumer」または javax.jms.MessageConsumer の Javadoc を参照してください。
接続を開始するには、Connection
クラスの start()
メソッドを使用します。
接続の開始、停止、およびクローズの詳細については、「接続の開始、停止、クローズ」または javax.jms.Connection の Javadoc を参照してください。
次の例は、WL_HOME
\samples\server\examples\src\examples\jms\queue
ディレクトリ (WL_HOME
は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.queue.QueueSend
サンプルからの抜粋です。init()
メソッドは、JMS アプリケーションの QueueSession
をどのように設定して開始するかを示すものです。次に、その init()
メソッドを示し、併せて各設定手順も述べます。
必要な変数 (JNDI コンテキストなど)、JMS 接続ファクトリ、およびキュー静的変数を定義します。
public final static String JNDI_FACTORY=
"weblogic.jndi.WLInitialContextFactory";
public final static String JMS_FACTORY=
"weblogic.examples.jms.QueueConnectionFactory";
public final static String
QUEUE="weblogic.examples.jms.exampleQueue";
private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private TextMessage msg;
InitialContext ic = getInitialContext(args[0]);
.
.
.
private static InitialContext getInitialContext(
String url
) throws NamingException
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}
注意 : | EJB またはサーブレットの JNDI 初期コンテキストを設定する場合は、以下のメソッドを使用します。 |
Context ctx = new InitialContext();
JMS キューにメッセージを送信するのに必要なすべてのオブジェクトを作成します。ctx
オブジェクトは、main()
メソッドによって渡された JNDI 初期コンテキストです。
public void init(
Context ctx,
String queueName
) throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
接続を使用してセッションを作成します。次のコードでは、セッションが非トランザクションとして定義され、メッセージに対する確認応答が自動的に行われるものと指定されます。トランザクション セッションと確認応答モードの詳細については、「Session」を参照してください。
qsession = qcon.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
セッションと送り先 (キュー) を使用してメッセージ プロデューサ (キュー センダ) への参照を作成します。
qsender = qsession.createSender(queue);
msg = qsession.createTextMessage();
qcon.start();
}
examples.jms.queue.QueueReceive
の例の init()
メソッドは、前記の QueueSend
init()
メソッドとほぼ同じですが、例外が 1 つあります。手順 5 と手順 6 は、それぞれ以下のコードに置き換えられます。
qreceiver = qsession.createReceiver(queue);
qreceiver.setMessageListener(this);
最初の行では、createSender()
メソッドを呼び出してキュー センダへの参照を作成する代わりに、アプリケーションは createReceiver()
メソッドを呼び出してキュー レシーバを作成します。
2 番目の行では、メッセージ コンシューマは非同期メッセージ リスナを登録します。
メッセージがキュー セッションに届くと、そのメッセージは examples.jms.QueueReceive.onMessage()
メソッドに渡されます。次の QueueReceive
の例からの引用コードは、onMessage()
インタフェースを示したものです。
public void onMessage(Message msg)
{
try {
String msgText;
if (msg instanceof TextMessage) {
msgText = ((TextMessage)msg).getText();
} else { // TextMessage ではない場合
msgText = msg.toString();
}
System.out.println("Message Received: "+ msgText );
if (msgText.equalsIgnoreCase("quit")) {
synchronized(this) {
quit = true;
this.notifyAll(); // メイン スレッドに終了するよう通知する
}
}
} catch (JMSException jmse) {
jmse.printStackTrace();
}
}
onMessage()
メソッドは、キュー レシーバを通して受信したメッセージを処理します。このメソッドは、メッセージが TextMessage
であるかどうかを検証し、そうである場合は、そのメッセージのテキストを印刷します。onMessage()
が別のタイプのメッセージを受信した場合、そのメッセージの toString()
メソッドを使用してメッセージの内容を表示します。
注意 : | 受信したメッセージのタイプが、メッセージ ハンドラ メソッドが予期したタイプであるかどうかを検証するようにしてください。 |
この例で使用されている JMS クラスの詳細については、「JMS API について」または javax.jms の Javadoc を参照してください。
次の例は、WL_HOME
\samples\server\examples\src\examples\jms\topic
ディレクトリ (WL_HOME
は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.topic.TopicSend
サンプルからの抜粋です。init()
メソッドは、JMS アプリケーションのトピック セッションをどのように設定して開始するかを示すものです。次に、その init()
メソッドを示し、併せて各設定手順も述べます。
必要な変数 (JNDI コンテキストなど)、JMS 接続ファクトリ、およびトピック静的変数を定義します。
public final static String JNDI_FACTORY=
"weblogic.jndi.WLInitialContextFactory";
public final static String JMS_FACTORY=
"weblogic.examples.jms.TopicConnectionFactory";public final static String
TOPIC="weblogic.examples.jms.exampleTopic";
protected TopicConnectionFactory tconFactory;
protected TopicConnection tcon;
protected TopicSession tsession;
protected TopicPublisher tpublisher;
protected Topic topic;
protected TextMessage msg;
InitialContext ic = getInitialContext(args[0]);
.
.
.
private static InitialContext getInitialContext(
String url
) throws NamingException
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}
注意 : | サーブレットの JNDI 初期コンテキストを設定する場合は、以下のメソッドを使用します。 |
Context ctx = new InitialContext();
JMS キューにメッセージを送信するのに必要なすべてのオブジェクトを作成します。ctx
オブジェクトは、main()
メソッドによって渡された JNDI 初期コンテキストです。
public void init(
Context ctx,
String topicName
) throws NamingException, JMSException
{
tconFactory =
(TopicConnectionFactory) ctx.lookup(JMS_FACTORY);
tcon = tconFactory.createTopicConnection();
接続を使用してセッションを作成します。次のコードでは、セッションが非トランザクションとして定義され、メッセージに対する確認応答が自動的に行われるものと指定されます。セッションのトランザクションと確認応答モードの設定については、「Session」を参照してください。
tsession = tcon.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
JNDI を使用して送り先 (トピック) をルックアップします。
topic = (Topic) ctx.lookup(topicName);
セッションと送り先 (トピック) を使用してメッセージ プロデューサ (トピック パブリッシャ) への参照を作成します。
tpublisher = tsession.createPublisher(topic);
msg = tsession.createTextMessage();
tcon.start();
}
examples.jms.topic.TopicReceive
の例の init()
メソッドは、前記の TopicSend
init()
メソッドとほぼ同じですが、例外が 1 つあります。手順 5 と手順 6 は、それぞれ以下のコードに置き換えられます。
tsubscriber = tsession.createSubscriber(topic);
tsubscriber.setMessageListener(this);
最初の行では、createPublisher()
メソッドを呼び出してトピック パブリッシャへの参照を作成する代わりに、アプリケーションは createSubscriber()
メソッドを呼び出してトピック サブスクライバを作成します。
2 番目の行では、メッセージ コンシューマは非同期メッセージ リスナを登録します。
メッセージがトピック セッションに届くと、そのメッセージは examples.jms.TopicSubscribe.onMessage()
メソッドに渡されます。TopicReceive
の例の onMessage()
インタフェースは、QueueReceive onMessage()
インタフェース (「例 : PTP アプリケーションの設定」を参照) と同じです。
この例で使用されている JMS クラスの詳細については、「JMS API について」または javax.jms の Javadoc を参照してください。
「JMS アプリケーションの設定」の説明に従って JMS アプリケーションを設定すると、メッセージを送信できるようになります。メッセージを送信するには、次の手順を実行する必要があります。
メッセージの送信に使用する JMS クラスとメッセージ タイプの詳細については、javax.jms.Message の Javadoc を参照してください。メッセージの受信については、「メッセージの受信」を参照してください。
この手順は、「手順 6a : メッセージ オブジェクトを作成する (メッセージ プロデューサ)」で説明したように、クライアント設定手順の一部としてすでに完了しています。
この手順は、「手順 6a : メッセージ オブジェクトを作成する (メッセージ プロデューサ)」で説明したように、アプリケーションの設定時に完了している場合もあります。この手順が完了しているかどうかは、メッセージ オブジェクトを作成するために呼び出されたメソッドによって決まります。たとえば、TextMessage タイプと ObjectMessage タイプの場合は、メッセージ オブジェクトを作成するときにオプションでメッセージを定義することができます。
すでに値が指定されており、それを変更しない場合は、そのまま手順 3 に進みます。
値が指定されていない場合、または既存の値を変更する場合は、適切な set
メソッドを使用して値を定義できます。たとえば、TextMessage
のテキストを定義するメソッドは次のとおりです。
public void setText(
String string
) throws JMSException
注意 : | メッセージは null として定義することができます。 |
それ以後は、次のメソッドを使用してメッセージを消去できます。
public void clearBody(
) throws JMSException
メッセージの定義に使用するメソッドの詳細については、javax.jms.Session の Javadoc を参照してください。
メッセージを送り先に送信するには、メッセージ プロデューサ、つまりキュー センダ (PTP) またはトピック パブリッシャ (Pub/Sub) と、以下の節で説明するメソッドを使用します。Destination
オブジェクトと MessageProducer
オブジェクトは、「JMS アプリケーションの設定」で説明したとおり、アプリケーションの設定時に作成されています。
注意 : | 複数のトピック サブスクライバが同じトピックに対して定義されている場合、各サブスクライバはメッセージの独自のローカル コピーを受信します。受信が済んだら、ヘッダ フィールド値を変更することはできますが、メッセージ プロパティとメッセージ本文は読み込み専用です。メッセージ本文を変更するには、対応するメッセージ タイプの clearbody() メソッドを実行して、既存の内容を消去し、書き込みパーミッションを有効にします。 |
MessageProducer
クラスの詳細については、「MessageProducer と MessageConsumer」または javax.jms.MessageProducer の Javadoc を参照してください。
メッセージを送信するには、以下の QueueSender
メソッドを使用します。
public void send(
Message message
) throws JMSException
public void send(
Message message,
int deliveryMode,
int priority,
long timeToLive
) throws JMSException
public void send(
Queue queue,
Message message
) throws JMSException
public void send(
Queue queue,
Message message,
int deliveryMode,
int priority,
long timeToLive
) throws JMSException
メッセージを指定する必要があります。また、キュー名 (匿名メッセージ プロデューサ用)、配信モード (DeliveryMode.PERSISTENT
または DeliveryMode.NON_PERSISTENT
)、優先度 (0-9
)、および存続時間 (ミリ秒単位) も指定できます。指定しない場合、配信モード、優先度、および存続時間の各属性は以下のいずれかに設定されます。
注意 : | WebLogic JMS では、以下に示す独自の属性も提供されています (「メッセージ プロデューサ属性の設定」を参照)。 |
配信モードを PERSISTENT
として定義した場合、Administration Console オンライン ヘルプの「永続ストアのコンフィグレーション」で説明しているように、送り先のバッキング ストアをコンフィグレーションする必要があります。
注意 : | バッキング ストアがコンフィグレーションされていない場合、配信モードは NON_PERSISTENT に変更され、メッセージは永続ストアに書き込まれません。 |
キュー センダが匿名プロデューサである場合 (つまり、キューが作成されたときにその名前が NULL に設定された場合)、キュー名を指定して (最後の 2 つのメソッドのいずれかを使用する) メッセージの配信先を指示する必要があります。匿名プロデューサの定義の詳細については、「QueueSender と QueueReceiver の作成」を参照してください。
たとえば、次のコードは、永続的メッセージを優先度 4、存続時間 1 時間で送信します。
QueueSender.send(message, DeliveryMode.PERSISTENT, 4, 3600000);
QueueSender
クラスのメソッドの詳細については、javax.jms.QueueSender の Javadoc を参照してください。
メッセージを送信するには、以下の TopicPublisher
メソッドを使用します。
public void publish(
Message message
) throws JMSException
public void publish(
Message message,
int deliveryMode,
int priority,
long timeToLive
) throws JMSException
public void publish(
Topic topic,
Message message
) throws JMSException
public void publish(
Topic topic,
Message message,
int deliveryMode,
int priority,
long timeToLive
) throws JMSException
メッセージを指定する必要があります。また、トピック名、配信モード (DeliveryMode.PERSISTENT
または DeliveryMode.NON_PERSISTENT
)、優先度 (0-9
)、および存続時間 (ミリ秒単位) を指定することもできます。指定しない場合、配信モード、優先度、および存続時間の各属性は以下のいずれかに設定されます。
注意 : | WebLogic JMS では、以下に示す独自の属性も提供されています (「メッセージ プロデューサ属性の設定」を参照)。 |
配信モードを PERSISTENT
として定義した場合、Administration Console オンライン ヘルプの「永続ストアのコンフィグレーション」で説明しているように、バッキング ストアをコンフィグレーションする必要があります。
注意 : | バッキング ストアがコンフィグレーションされていない場合、配信モードは NON_PERSISTENT に変更され、メッセージは保存されません。 |
トピック パブリッシャが匿名プロデューサである場合 (つまり、トピックが作成されたときにその名前が NULL に設定された場合)、トピック名を指定して (最後の 2 つのメソッドのいずれかを使用する) メッセージの配信先を指示する必要があります。匿名プロデューサの定義の詳細については、「TopicPublisher と TopicSubscriber の作成」を参照してください。
たとえば、次のコードは、永続的メッセージを優先度 4、存続時間 1 時間で送信します。
TopicPublisher.publish(message, DeliveryMode.PERSISTENT,
4,3600000);
TopicPublisher
クラスのメソッドの詳細については、javax.jms.TopicPublisher の Javadoc を参照してください。
前節で説明したように、メッセージを送信するときには、配信モード、優先度、および存続時間をオプションで指定できます。指定しない場合、これらの属性には接続ファクトリのコンフィグレーション属性の値が設定されます。詳細については、Administration Console オンライン ヘルプの「接続ファクトリのコンフィグレーション」を参照してください。
代わりに、メッセージ プロデューサの set メソッドを使用して、配信モード、優先度、配信時間、存続時間、再配信遅延 (タイムアウト)、および再配信制限の各属性値を動的に設定できます。次の表に、メッセージ プロデューサの set メソッドと get メソッドを、動的コンフィグレーション可能な属性ごとに示します。
注意 : | 配信モード、優先度、存続時間、配信時間、再配信遅延 (タイムアウト)、および再配信制限の各属性値は、[配信モードのオーバーライド]、[優先順位のオーバーライド]、[生存時間のオーバーライド]、[配信時間のオーバーライド、[再配信遅延のオーバーライド]、および [再配信の制限] の各コンフィグレーション属性を使用して送り先によってオーバーライドできます。詳細については、Administration Console オンライン ヘルプの「メッセージ配信のオーバーライドのコンフィグレーション」および「トピック メッセージ配信のオーバーライドのコンフィグレーション」を参照してください。 |
注意 : | JMS では、メッセージ ID とタイムスタンプ情報を無効にするための MessageProducer メソッドを定義することもできます。ただし、これらのメソッドは WebLogic JMS では無視されます。 |
MessageProducer
クラスのメソッドの詳細については、javax.jms.MessageProducer または weblogic.jms.extensions.WLMessageProducer の Javadoc を参照してください。
次の例は、WL_HOME
\samples\server\examples\src\examples\jms\queue
ディレクトリ (WL_HOME
は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.queue.QueueSend
サンプルからの抜粋です。この例では、TextMessage
を作成し、メッセージのテキストを設定してキューに送信するために必要なコードを示してあります。
msg = qsession.createTextMessage();
.
.
.
public void send(
String message
) throws JMSException
{
msg.setText(message);
qsender.send(msg);
}
QueueSender
クラスとそのメソッドの詳細については、javax.jms.QueueSender の Javadoc を参照してください。
次の例は、WL_HOME
\samples\server\examples\src\examples\jms\topic
ディレクトリ (WL_HOME
は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.topic.TopicSend
サンプルからの抜粋です。この例では、TextMessage
を作成し、メッセージのテキストを設定してトピックに送信するために必要なコードを示してあります。
msg = tsession.createTextMessage();
.
.
.
public void send(
String message
) throws JMSException
{
msg.setText(message);
tpublisher.publish(msg);
}
TopicPublisher
クラスとそのメソッドの詳細については、javax.jms.TopicPublisher の Javadoc を参照してください。
「JMS アプリケーションの設定」の説明に従って JMS アプリケーションを設定すると、メッセージを受信できるようになります。
メッセージを受信するには、以下の節で説明するとおりレシーバ オブジェクトを作成し、メッセージを同期受信するか非同期受信するかを指定する必要があります。
メッセージを受信する順序は、以下の要素によって設定できます。
send()
メソッドの一部として定義するメッセージ配信属性 (配信モードとソート条件)。詳細については、「メッセージの送信」を参照してください。
受信が済んだら、ヘッダ フィールド値を変更することはできますが、メッセージ プロパティとメッセージ本文は読み込み専用です。メッセージ本文を変更するには、対応するメッセージ タイプの clearbody()
メソッドを実行して、既存の内容を消去し、書き込みパーミッションを有効にします。
メッセージの受信に使用する JMS クラスとメッセージ タイプの詳細については、javax.jms.Message の Javadoc を参照してください。メッセージの送信については、「メッセージの送信」を参照してください。
この手順については、アプリケーションの設定手順の中で説明されています。詳細については、「手順 6b : 非同期メッセージ リスナを登録する (メッセージ コンシューマ) (オプション)」を参照してください。
注意 : | 接続ファクトリのコンフィグレーション時に [セッションあたりの最大メッセージ数] 属性を設定すると、非同期コンシューマに存在し、メッセージ リスナにまだ渡されていないメッセージの最大数を指定できます。 |
メッセージの生成速度が非同期メッセージ リスナ (コンシューマ) によるそれらの消費速度を上回る場合、JMS サーバは複数の未消費メッセージをまとめ、別の使用可能な非同期メッセージ リスナのセッションに送ります。こうした処理中のメッセージはメッセージ パイプラインと呼ばれ、JMS ベンダによってはメッセージ バックログとも呼ばれます。パイプラインまたはバックログのサイズは、非同期コンシューマで蓄積され、メッセージ リスナに渡されていないメッセージの数です。
クライアントの最大パイプライン サイズを設定するには、クライアントの接続ファクトリの [セッションあたりの最大メッセージ数] 属性をコンフィグレーションします。この属性は、非同期コンシューマに存在し、メッセージ リスナにまだ渡されていないメッセージの最大数です。デフォルト値は 10 です。JMS 接続ファクトリのコンフィグレーションの詳細については、Administration Console オンライン ヘルプの「接続ファクトリのコンフィグレーション」を参照してください。
コンフィグレーションされたメッセージ パイプラインは、次のように動作します。
注意 : | 接続ファクトリの [セッションあたりの最大メッセージ数] パイプライン サイズは、JMS サーバおよび送り先の最大メッセージ割り当ての設定とは関係ありません。 |
注意 : | パイプライン メッセージは、ネットワーク転送で単一のメッセージに集約される場合があります。パイプライン メッセージのサイズが大きい場合、書き込まれるデータの集約サイズが最大転送値を超え、望ましくない動作が発生する場合があります。たとえば、t3 プロトコルでは、デフォルトの最大メッセージ サイズは 10 MB に設定されており、サーバの MaxT3MessageSize 属性でコンフィグレーションできます。このため、10 通の 2 MB メッセージがパイプライン処理される場合、t3 の制限を上回る場合があります。 |
メッセージを同期的に受信するには、以下の MessageConsumer
メソッドを使用します。
public Message receive(
) throws JMSException
public Message receive(
long timeout
) throws JMSException
public Message receiveNoWait(
) throws JMSException
どのケースでも、アプリケーションは次に生成されるメッセージを受信します。receive()
メソッドを引数なしで呼び出した場合、その呼び出しはメッセージが生成されるか、またはアプリケーションがクローズされるまで無期限にブロックされます。代わりに、タイムアウト値を渡してメッセージの待ち時間を指定することもできます。値 0 を指定して receive()
メソッドを呼び出した場合、その呼び出しは無期限にブロックされます。receiveNoWait()
メソッドは、次のメッセージが存在する場合はそれを受信し、それ以外の場合は null を返します。この場合、呼び出しはブロックされません。
MessageConsumer
クラスのメソッドは、QueueReceiver
および TopicSubscriber
クラスによって継承されます。MessageConsumer
クラスのメソッドの詳細については、javax.jms.MessageConsumer の Javadoc を参照してください。
WebLogic Server 9.1 より前のバージョンでは、同期コンシューマで各メッセージに対し双方向のネットワーク呼び出しが必要でした。この方法は同期コンシューマで複数のメッセージを受け取れないので非効率的であり、また同期コンシューマで利用可能なメッセージ用にサーバのポーリングが続けられるのでネットワーク トラフィック リソースが増加するおそれがありました。WebLogic 9.1 以降では、Administration Console または JMSClientParamsBean
MBean を介して JMS 接続ファクトリの [同期コンシューマのプリフェッチ モード] オプションを有効にすることにより、同期コンシューマでも非同期コンシューマと同じ効率的な動作を利用できるようになります。
JMS クライアントの接続ファクトリでプリフェッチ モードが有効な場合、非同期メッセージのパイプラインのように、その接続ファクトリに対象指定された JMS サーバが未消費のメッセージのバッチを積極的に同期メッセージ コンシューマに送信します。この際、バッチごとにプリフェッチされるメッセージの最大数を定義するために、その接続ファクトリの [セッションあたりの最大メッセージ数] パラメータが使用されます。これにより、同期コンシューマでさらにメッセージを処理する準備ができたときに、そのコンシューマに対してメッセージが用意され待機している状態になるため、パフォーマンスが向上する場合があります。さらに、コンシューマでメッセージのポーリングが続けられることがなく、コンシューマからの同期呼び出し数が減るので、ネットワーク トラフィックが減少することもあります。
同期メッセージ プリフェッチは、同期メッセージ受信に対するユーザ (XA) トランザクションも、(キューであるかトピックであるかに関係なく) セッションごとの複数の同期コンシューマもサポートしていません。上記に該当するほとんどの場合、WebLogic JMS では何の通知もなく [同期コンシューマのプリフェッチ モード] フラグは無視されます。ただし、無視されない場合、アプリケーションの同期受信呼び出しは失敗します。
パイプライン メッセージの動作の詳細については、「非同期メッセージ パイプライン」を参照してください。JMS 接続ファクトリのコンフィグレーションの詳細については、Administration Console オンライン ヘルプの「接続ファクトリのコンフィグレーション」を参照してください。
次の例は、WL_HOME
\samples\server\examples\src\examples\jms\queue
ディレクトリ (WL_HOME
は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.queue.QueueReceive
サンプルからの抜粋です。メッセージ リスナを設定するのではなく、各メッセージに対して qreceiver.receive()
を呼び出します。次に例を示します。
qreceiver = qsession.createReceiver(queue);
qreceiver.receive();
最初の行では、キューに対するキュー レシーバが作成されます。2 番目の行では、receive()
メソッドが実行されます。receive()
メソッドは、ブロックしてメッセージを待ちます。
次の例は、WL_HOME
\samples\server\examples\src\examples\jms\topic
ディレクトリ (WL_HOME
は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.topic.TopicReceive
サンプルからの抜粋です。メッセージ リスナを設定するのではなく、各メッセージに対して tsubscriber.receive()
を呼び出します。
tsubscriber = tsession.createSubscriber(topic);
Message msg = tsubscriber.receive();
msg.acknowledge();
最初の行では、トピックに対するトピック サブスクライバが作成されます。2 番目の行では、receive()
メソッドが実行されます。receive()
メソッドは、ブロックしてメッセージを待ちます。
注意 : | この節の説明は、表 2-7 で説明したように、確認応答モードが CLIENT_ACKNOWLEDGE に設定されている非トランザクション セッションだけに適用されます。同期受信される AUTO_ACKNOWLEDGE メッセージは確認応答済みのため、回復されないことがあります。 |
アプリケーションは、次のメソッドを使用して、JMS にメッセージの再配信 (未確認) を要求できます。
public void recover(
) throws JMSException
注意 : | キュー内のメッセージは、必ずしも元の配信順序と同じ順序で、または同じキュー コンシューマに再配信されるとは限りません。再配信メッセージの正しい配信順序の保証については、「メッセージの再配信の順序付け」を参照してください。 |
注意 : | この節の説明は、表 2-7 で説明したように、確認応答モードが CLIENT_ACKNOWLEDGE に設定されている非トランザクション セッションだけに適用されます。 |
受信したメッセージの確認応答を行うには、次の Message
メソッドを使用します。
public void acknowledge(
) throws JMSException
acknowledge()
メソッドは、接続ファクトリの [確認応答ポリシー] 属性のコンフィグレーションによって次のように異なります。
このメソッドは、確認応答モードが CLIENT_ACKNOWLEDGE
に設定されている非トランザクション セッションに対してだけ有効です。それ以外の場合、このメソッドは無視されます。
JMS アプリケーションに代わって作成した接続、セッション、メッセージ プロデューサ/コンシューマ、接続コンシューマ、またはキュー ブラウザを使い終えたら、それらを明示的にクローズしてリソースを解放する必要があります。
JMS オブジェクトをクローズするには、close()
メソッドを次のとおり入力します。
public void close(
) throws JMSException
オブジェクトをクローズするときには、以下の処理が行われます。
各オブジェクトについての close()
メソッドの影響については、該当する javax.jms の Javadoc を参照してください。また、接続またはセッションの close()
メソッドの詳細については、それぞれ「接続の開始、停止、クローズ」、「セッションのクローズ」を参照してください。
次の例は、WL_HOME
\samples\server\examples\src\examples\jms\queue
ディレクトリ (WL_HOME
は WebLogic Platform のインストール先の最上位ディレクトリ) にある WebLogic Server 付属の examples.jms.queue.QueueSend
サンプルからの抜粋です。この例では、メッセージ コンシューマ、セッション、および接続オブジェクトをクローズするのに必要なコードを示してあります。
public void close(
) throws JMSException
{
qreceiver.close();
qsession.close();
qcon.close();
}
この QueueSend
の例では、main()
の最後に close()
メソッドが呼び出され、オブジェクトのクローズとリソースの解放が行われます。