ORACLE JAPAN Server Release 6.1

 

  |  

  WebLogic Server ホーム   |     JMS プログラマーズ ガイド   |   前へ   |   次へ   |   目次   |   索引   |   PDF 版

WebLogic JMS アプリケーションの開発

 

以降の節では、WebLogic Server JMS アプリケーションを開発する方法について説明します。

注意: この節で説明する JMS クラスの詳細については、Sun Microsystems の Java Web サイトにある以下の JMS Javadocを参照してください。

http://java.sun.com/products/jms/docs.html

 


アプリケーション開発フロー

WebLogic JMS アプリケーションを開発するには、次の図に示す手順を行う必要があります。

図4-1 WebLogic JMS アプリケーション開発フロー-必要な手順


 

上の図に示したアプリケーション開発手順のほかにも、設計開発時に以下の手順を任意に行うことができます。

以降の節では、すべてのアプリケーション開発手順について説明します(最後の手順を除く)。

 


必要なパッケージのインポート

次の表に、WebLogic JMS アプリケーションで一般に使用されるパッケージを示します。

表4-1 WebLogic JMS パッケージ

パッケージ

説明

javax.jms

JMS API。このパッケージは常に WebLogic JMS アプリケーションで使用される。

java.util

日付や時刻機能などのユーティリティ API。

java.io

システム入力および出力 API。

javax.naming

weblogic.jndi

サーバおよび送り先ルックアップに必要な JNDI パッケージ。

javax.transaction.UserTransaction

JTA ユーザ トランザクション サポートに必要な JTA API。

weblogic.jms.ServerSessionPoolFactory

JMS 仕様で定義されているオプションのアプリケーション サーバ機能、サーバ セッション プールを使用するための WebLogic JMS パブリック API。

weblogic.jms.extensions

追加のクラスとメソッドを提供する WebLogic 固有の JMS パブリック API( WebLogic JMS の拡張機能を参照)。

プログラムの最初に、以下のパッケージ import 文を挿入します。

import javax.jms.*;
import java.util.*;
import java.io.*;
import javax.naming.*;
import javax.transaction.*;

サーバ セッション プール アプリケーションを実装する場合は、次のクラスをインポート リストに追加します。

import weblogic.jms.ServerSessionPoolFactory;

上の表に示した WebLogic JMS 拡張クラスを使用する場合は、次の文もインポート リストに追加します。

import weblogic.jms.extensions.*;

 


JMS アプリケーションの設定

メッセージを送受信するには、あらかじめ JMS アプリケーションを設定しておく必要があります。次の図に、JMS アプリケーションの設定に必要な手順を示します。

図4-2 JMS アプリケーションの設定


 

以下の節では、この設定手順について説明します。また、ポイント ツー ポイント(PTP)およびパブリッシュ/サブスクライブ(Pub/Sub)アプリケーションの詳しい例も示します。これらの例は、samples\examples ディレクトリに収められている WebLogic Server 付属の examples.jms パッケージから引用したものです。

設定手順に進む前に、WebLogic Server のコンフィグレーションを担当するシステム管理者が必要な JMS 機能(接続ファクトリ、JMS サーバ、送り先など)をコンフィグレーションしたことを確認してください。詳細については、『管理者ガイド』の「JMS の管理」を参照してください。

これらの節で説明する JMS クラスおよびメソッドの詳細については、 WebLogic JMS のクラスか、または javax.jmsweblogic.jms.ServerSessionPoolFactoryweblogic.jms.extensions Javadoc を参照してください。

トランザクション アプリケーションと JTA ユーザ トランザクションの設定については、 WebLogic JMS によるトランザクションの使い方を参照してください。

手順 1 : JNDI で接続ファクトリをルックアップする

接続ファクトリをルックアップするには、あらかじめ接続ファクトリをコンフィグレーション情報の一部として定義しておく必要があります。WebLogic JMS には、コンフィグレーションの一部として組み込まれているデフォルト接続ファクトリが 1 つ用意されています。WebLogic JMS システム管理者は、コンフィグレーション時に接続ファクトリを追加または更新できます。接続ファクトリのコンフィグレーションと使用可能なデフォルトについては、『管理者ガイド』の「JMS の管理」を参照してください。

接続ファクトリを定義したら、その接続ファクトリをルックアップするために、まず NamingManager.InitialContext() メソッドを使用して JNDI コンテキスト(context)を定義します。サーブレット アプリケーション以外のアプリケーションの場合は、初期コンテキストの作成に使用する環境を渡す必要があります。詳細については、NamingManager.InitialContext() Javadoc を参照してください。

コンテキストを定義したら、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 を参照してください。

手順 2 : 接続ファクトリを使用して接続を作成する

キューまたはトピックにアクセスするための接続を作成するには、次節で説明する 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 を参照してください。

手順 3 : 接続を使用してセッションを作成する

キューまたはトピックにアクセスするために 1 つまたは複数のセッションを作成するには、次節で説明する Connection メソッドを使用します。

注意: セッションおよびそのメッセージのプロデューサとコンシューマには、一度に 1 つのスレッドしかアクセスできません。それらに複数のスレッドが同時にアクセスした場合、それらの動作は定義されません。

Session クラスの詳細については、 Sessionまたは javax.jms.Session Javadoc を参照してください。

キュー セッションの作成

QueueConnection クラスは、キュー セッション作成用のメソッドを次のとおり定義します。

public QueueSession createQueueSession(
boolean transacted,
int acknowledgeMode
) throws JMSException

このメソッドでは、セッションをトランザクション処理するか(true)、またはトランザクション処理しないか(false)を示す boolean 引数と、 非トランザクション セッションで説明した非トランザクション セッションの確認応答モードを示す整数値を指定する必要があります。トランザクション セッションの場合、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 を参照してください。

手順 4 : 送り先(キューまたはトピック)をルックアップする

送り先をルックアップするには、あらかじめ WebLogic JMS システム管理者によって送り先がコンフィグレーションされている必要があります。詳細については、『管理者ガイド』の「JMS の管理」を参照してください。

送り先のコンフィグレーションが済んでいれば、JNDI コンテキスト(context)を定義し( 手順 1 : JNDI で接続ファクトリをルックアップするで実行済み)、以下のコマンド(PTP または Pub/Sub メッセージング用)のいずれかを実行することによって、送り先をルックアップできます。

Queue queue = (Queue) context.lookup(Dest_name);

Topic topic = (Topic) context.lookup(Dest_name);

Dest_name 引数には、コンフィグレーション時に定義された送り先名を指定します。

JNDI ネームスペースを使用しない場合は、以下の QueueSession または TopicSession メソッドを使用してキューまたはトピックをそれぞれ参照できます。

public Queue createQueue(
String queueName
) throws JMSException

public Topic createTopic(
String topicName
) throws JMSException

queueNametopicName 文字列の構文は、JMS_Server_Name/Destination_Name (たとえば、myjmsserver/mydestination)です。この構文を使用するソース コードを参照するには、 送り先の動的作成findqueue() 例を参照してください。

注意: createQueue() メソッドと createTopic() メソッドでは送り先が動的には作成されず、既に存在する送り先への参照が作成されるだけです。送り先の動的作成については、 送り先の動的作成を参照してください。

これらのメソッドの詳細については、それぞれ javax.jms.QueueSession Javadoc と javax.jms.TopicSession Javadoc を参照してください。

送り先を定義したら、以下の Queue メソッドまたは Topic メソッドを使用してキューまたはトピックにそれぞれアクセスできます。

public String getQueueName(
) throws JMSException

public String getTopicName(
) throws JMSException

キュー名とトピック名が印刷可能なフォーマットで返されるようにするには、toString() メソッドを使用します。

Destination クラスの詳細については、 Destinationまたは javax.jms.Destination Javadoc を参照してください。

送り先ルックアップ時のサーバ アフィニティ

createTopic() メソッドおよび createQueue() メソッドも、「JMS_Server_Name./Destination_Name」構文を使って、送り先のルックアップ時にサーバ アフィニティを示すことができます。この方法は、送り先が同じ JVM 内で接続 ファクトリとしてローカルにデプロイされている場合、その接続ファクトリは一致するローカルな送り先の名前だけを返します。 その名前がローカルな JVM にない場合、たとえ、別の JVM に同じ名前でデプロイされている場合でも、例外が送出されます。

アプリケーションは、この規則を利用して、createTopic() メソッドおよび createQueue() メソッドを使用時のサーバ名のハードコード化を避けることにより、何の変更も加える必要なく、別の JMS サーバ上でもそのコードを再利用することができます。

手順 5 : セッションと送り先を使用してメッセージ プロデューサとメッセージ コンシューマを作成する

メッセージ プロデューサとメッセージ コンシューマを作成するには、次節で説明する Session メソッドに送り先の参照を渡します。

注意: 各コンシューマはメッセージの独自のローカル コピーを受信します。受信が済んだら、ヘッダ フィールド値を変更することはできますが、メッセージ プロパティとメッセージ本文は読み込み専用です。(この時点でメッセージ プロパティまたは本文を変更しようとすると、MessageNotWriteableException が発生します)。メッセージ本文を変更するには、対応するメッセージ タイプの clearbody() メソッドを実行して、既存の内容を消去し、書き込みパーミッションを有効にします。

MessageProducer クラスと MessageConsumer クラスの詳細については、 MessageProducer と MessageConsumerか、または javax.jms.MessageProducer Javadoc と javax.jms.MessageConsumer Javadoc をそれぞれ参照してください

QueueSender と QueueReceiver の作成

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 Javadoc および javax.jms.QueueReceiver Javadoc を参照してください。

TopicPublisher と TopicSubscriber の作成

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 メソッドまたは TopicSubscribe メソッドを使用して、そのトピック パブリッシャまたはサブスクライバに関連付けられているトピック名にアクセスできます。

Topic getTopic(
) throws JMSException

また、次の TopicSubscriber メソッドを使用すると、トピック サブスクライバに関連付けられる noLocal 変数の設定値にアクセスできます。

boolean getNoLocal(
) throws JMSException

TopicSession クラス メソッドの詳細については、javax.jms.TopicSession Javadoc を参照してください。TopicPublisher クラスと TopicSubscriber クラスの詳細については、javax.jms.TopicPublisher Javadoc および javax.jms.TopicSubscriber Javadoc を参照してください。

手順 6a : メッセージ オブジェクト(メッセージ プロデューサ)を作成する

注意: この手順は、メッセージ プロデューサだけに適用されます。

メッセージ オブジェクトを作成するには、以下の Session クラス メソッドまたは WLSession クラス メソッドのいずれかを使用します。

Session クラスと WLSession クラスのメソッドの詳細については、javax.jms.Session Javadoc と weblogic.jms.extensions.WLSession Javadoc をそれぞれ参照してください。Message クラスとそのメソッドの詳細については、 Messageか、または javax.jms.Message Javadoc を参照してください。

手順 6b : 非同期メッセージ リスナ(メッセージ コンシューマ)を登録する(オプション)

注意: この手順は、メッセージ コンシューマだけに適用されます。

メッセージを非同期的に受信するには、次の手順で非同期メッセージ リスナを登録する必要があります。

  1. onMessage() メソッドが組み込まれた javax.jms.MessageListener インタフェースを実装します。

    注意: onMessage() メソッドのインタフェースの例については、 例 : PTP アプリケーションの設定を参照してください。
    onMessage() メソッド呼び出し内で close() メソッドを発行する場合、システム管理者は接続ファクトリをコンフィグレーションするときに [メッセージの短縮を許可] チェックボックスを選択しなければなりません。JMS のコンフィグレーションの詳細については、『管理者ガイド』の「JMS の管理」を参照してください。

  2. 次の MessageConsumer メソッドを使用してメッセージ リスナを設定し、リスナ情報を引数として渡します。

    public void setMessageListener(
    MessageListener listener
    ) throws JMSException

  3. オプションで、 セッション例外リスナの定義で説明するように、例外を取得するためのセッションの例外リスナを実装します。

メッセージ リスナの設定を解除するには、NULL 値を指定して MessageListener() メソッドを呼び出します。

メッセージ リスナを定義したら、次の MessageConsumer メソッドを呼び出してそのリスナにアクセスできます。

public MessageListener getMessageListener(
) throws JMSException

注意: WebLogic JMS は、同じセッションの複数の onMessage() 呼び出しが同時に実行されないことを保証します。

メッセージ コンシューマが管理者またはサーバのダウンによってクローズされた場合、ConsumerClosedException がセッション例外リスナに送信されます(定義されている場合)。このように、必要な場合は新しいメッセージ コンシューマを作成できます。セッション例外リスナの定義については、 セッション例外リスナの定義を参照してください。

MessageConsumer クラスのメソッドは、QueueReceiver および TopicSubscriber クラスによって継承されます。MessageConsumer クラスのメソッドの詳細については、 MessageProducer と MessageConsumerか、または javax.jms.MessageConsumer Javadoc を参照してください。

手順 7 : 接続を開始する

接続を開始するには、Connection クラスの start() メソッドを使用します。

接続の開始、停止、およびクローズの詳細については、 接続の開始、停止、クローズまたは javax.jms.Connection Javadoc を参照してください。

例 : PTP アプリケーションの設定

次の例は、samples\examples\jms\queue ディレクトリに収められている 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;

JNDI 初期コンテキストを次のとおり設定します。

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 queueName
) throws NamingException, JMSException
{

手順 1

JNDI で接続ファクトリをルックアップします。

qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);

手順 2

接続ファクトリを使用して接続を作成します。

qcon = qconFactory.createQueueConnection();

手順 3

接続を使用してセッションを作成します。次のコードでは、セッションが非トランザクションとして定義され、メッセージに対する確認応答が自動的に行われるものと指定されます。トランザクション セッションと確認応答モードの詳細については、 Sessionを参照してください。

qsession = qcon.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);

手順 4

JNDI で送り先(キュー)をルックアップします。

queue = (Queue) ctx.lookup(queueName);

手順 5

セッションと送り先(キュー)を使用してメッセージ プロデューサ(キュー センダ)への参照を作成します。

qsender = qsession.createSender(queue);

手順 6

メッセージ オブジェクトを作成します。

msg = qsession.createTextMessage();

手順 7

接続を開始します。

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 クラスの詳細については、 WebLogic JMS のクラスまたは javax.jms Javadoc を参照してください。

例 : Pub/Sub アプリケーションの設定

次の例は、samples\examples\jms\topic ディレクトリに収められている 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;

JNDI 初期コンテキストを次のとおり設定します。

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
{

手順 1

JNDI を使用して接続ファクトリをルックアップします。

tconFactory =
(TopicConnectionFactory) ctx.lookup(JMS_FACTORY);

手順 2

接続ファクトリを使用して接続を作成します。

tcon = tconFactory.createTopicConnection();

手順 3

接続を使用してセッションを作成します。次のコードでは、セッションが非トランザクションとして定義され、メッセージに対する確認応答が自動的に行われるものと指定されます。セッション トランザクションと確認応答モードの設定については、 Sessionを参照してください。

tsession = tcon.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);

手順 4

JNDI を使用して送り先(トピック)をルックアップします。

topic = (Topic) ctx.lookup(topicName);

手順 5

セッションと送り先(トピック)を使用してメッセージ プロデューサ(トピック パブリッシャ)への参照を作成します。

tpublisher = tsession.createPublisher(topic);

手順 6

メッセージ オブジェクトを作成します。

msg = tsession.createTextMessage();

手順 7

接続を開始します。

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() メソッドに渡されます。TopicReceiveonMessage() インタフェースは、QueueReceive onMessage() インタフェース( 例 : PTP アプリケーションの設定 を参照)とほぼ同じです。

この例で使用した JMS クラスの詳細については、 WebLogic JMS のクラスまたは javax.jms Javadoc を参照してください。

 


メッセージの送信

JMS アプリケーションの設定で説明したとおり JMS アプリケーションを設定したら、メッセージを送信することができます。メッセージを送信するには、次の手順を実行する必要があります。

  1. メッセージ オブジェクトを作成する

  2. メッセージを定義する

  3. メッセージを送り先に送信する

メッセージを送信するための JMS クラスとメッセージ タイプの詳細については、javax.jms.Message Javadoc を参照してください。メッセージの受信については、 メッセージの受信を参照してください。

手順 1 : メッセージ オブジェクトを作成する

この手順は、 手順 6a : メッセージ オブジェクト(メッセージ プロデューサ)を作成するで説明したように、クライアント設定手順の一部として既に実行されています。

手順 2 : メッセージを定義する

この手順は、 手順 6a : メッセージ オブジェクト(メッセージ プロデューサ)を作成するで説明したように、アプリケーションの設定時に実行されている場合もあります。この手順が実行済みであるかどうかは、メッセージ オブジェクトを作成するために呼び出されたメソッドによって決まります。たとえば、TextMessage タイプと ObjectMessage タイプの場合は、メッセージ オブジェクトを作成するときにオプションでメッセージを定義することができます。

既に値が指定されており、それを変更したくない場合は、そのまま手順 3 に進みます。

値が指定されていないか、または既存の値を変更する場合は、適切な set メソッドを使用して値を定義できます。たとえば、TextMessage のテキストを定義するメソッドは次のとおりです。

public void setText(
String string
) throws JMSException

注意: メッセージは NULL として定義することができます。

それ以後は、次のメソッドを使用してメッセージを消去できます。

public void clearBody(
) throws JMSException

メッセージを定義するためのメソッドの詳細については、javax.jms.Session Javadoc を参照してください。

手順 3 : メッセージを送り先に送信する

メッセージを送り先に送信するには、メッセージ プロデューサ-キュー センダ(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 も、独自の TimeToDeliver 属性(生成時間)を提供します( メッセージ プロデューサ コンフィグレーション属性の動的コンフィグレーションを参照)。

配信モードを PERSISTENT として定義した場合、『管理者ガイド』の「JMS の管理」で説明してあるように、送り先のバッキング ストアをコンフィグレーションする必要があります。

注意: バッキング ストアがコンフィグレーションされていない場合、配信モードは NON_PERSISTENT に変更され、メッセージは永続ストレージに書き込まれません。

キュー センダが匿名プロデューサである場合(つまり、キューが作成されたときにその名前が NULL に設定された場合)、キュー名を指定して(最後の 2 つのメソッドのいずれかを使用する)メッセージの配信先を指示する必要があります。匿名プロデューサの定義の詳細については、 QueueSender と QueueReceiver の作成を参照してください。

たとえば、次のコードは、永続メッセージを優先度 4、存続時間 1 時間で送信します。

QueueSender.send(message, DeliveryMode.PERSISTENT, 4, 3600000);

QueueSender クラスのメソッドの詳細については、javax.jms.QueueSender Javadoc を参照してください。

TopicPublisher を使用してメッセージを送信する

メッセージを送信するには、以下の 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 も、独自の TimeToDeliver 属性(生成時間)を提供します( メッセージ プロデューサ コンフィグレーション属性の動的コンフィグレーションを参照)。

配信モードを PERSISTENT として定義した場合、『管理者ガイド』の「JMS の管理」で説明してあるようにバッキング ストアをコンフィグレーションする必要があります。

注意: バッキング ストアがコンフィグレーションされていない場合、配信モードは NON_PERSISTENT に変更され、メッセージは保存されません。

トピック パブリッシャが匿名プロデューサである場合(つまり、トピックが作成されたときにその名前が NULL に設定された場合)、トピック名を指定して(最後の 2 つのメソッドのいずれかを使用する)メッセージの配信先を指示する必要があります。匿名プロデューサの定義の詳細については、 TopicPublisher と TopicSubscriber の作成を参照してください。

たとえば、次のコードは、永続メッセージを優先度 4、存続時間 1 時間で送信します。

TopicPublisher.publish(message, DeliveryMode.PERSISTENT,
4,3600000);

TopicPublisher クラスのメソッドの詳細については、javax.jms.TopicPublisher Javadoc を参照してください。

メッセージ プロデューサ コンフィグレーション属性の動的コンフィグレーション

前節で説明したように、メッセージを送信するときには、配信モード、優先度、存続時間、および配信時間をオプションで指定できます。指定しない場合、配信モード、優先度、存続時間、および配信時間の各属性は、『管理者ガイド』の「JMS の管理」で説明しているように、プロデューサに対して定義されている接続ファクトリまたは送り先オーバーライドのコンフィグレーション属性に設定されます。

代わりに、メッセージ プロデューサ set メソッドを使用して配信モード、優先度、および存続時間を動的に設定することによって、コンフィグレーション済みの属性値をオーバーライドすることもできます。

次の表に、メッセージ プロデューサの set メソッドと get メソッドを、動的コンフィグレーション可能な属性ごとに示します。

注意: 配信モード、優先度、存続時間、配信時間の各属性値は、[配信モードのオーバライド]、[優先順位オーバライド]、[生存時間オーバライド]、および [送信時間オーバライド] 送り先コンフィグレーション属性を使用して、送り先によってオーバーライドできます。詳細については、Administration Console オンライン ヘルプを参照してください。

表4-2 メッセージ プロデューサの set メソッドおよび get メソッド

属性

set メソッド

get メソッド

配信モード

public void setDeliveryMode(
  int deliveryMode
) throws JMSException

public int getDeliveryMode(
) throws JMSException

優先度

public void setPriority(
  int defaultPriority
) throws JMSException

public int getPriority(
) throws JMSException

存続時間

public void setTimeToLive(
  long timeToLive
) throws JMSException

public long getTimeToLive(
) throws JMSException

配信時間

public void setTimeToDeliver(
  long timeToDeliver
) throws JMSException

public long getTimeToDeliver(
) throws JMSException

注意: JMS では、メッセージ ID とタイムスタンプ情報を無効にするための MessageProducer メソッドを定義することもできます。ただし、これらのメソッドは WebLogic JMS では無視されます。

MessageProducer クラス メソッドの詳細については、javax.jms.MessageProducer Javadoc を参照してください。

例 : PTP アプリケーション内でのメッセージの送信

次の例は、samples\examples\jms\queue ディレクトリに収められている 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 を参照してください。

例 : Pub/sub アプリケーション内でのメッセージの送信

次の例は、samples\examples\jms\topic ディレクトリに収められている 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 アプリケーションを設定したら、メッセージを受信することができます。

メッセージを受信するには、以下の節で説明するとおりレシーバ オブジェクトを作成し、メッセージを同期受信するか非同期受信するかを指定する必要があります。

メッセージを受信する順序は、以下の要素によって設定できます。

受信が済んだら、ヘッダ フィールド値を変更することはできますが、メッセージ プロパティとメッセージ本文は読み込み専用ですメッセージ本文を変更するには、対応するメッセージ タイプの clearbody() メソッドを実行して、既存の内容を消去し、書き込みパーミッションを有効にします。

メッセージを受信するための JMS クラスとメッセージ タイプの詳細については、javax.jms.Message Javadoc を参照してください。メッセージの送信については、 メッセージの送信を参照してください。

メッセージの非同期受信

この手順については、アプリケーションの設定手順の中で説明されています。詳細については、 手順 6b : 非同期メッセージ リスナ(メッセージ コンシューマ)を登録する(オプション)を参照してください。

注意: 接続ファクトリのコンフィグレーション時に [最大メッセージ] 属性を設定すると、非同期セッションの間に存在し、メッセージ リスナにまだ渡されていないメッセージの最大数を指定できます。

メッセージの同期受信

メッセージを同期的に受信するには、以下の 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 を参照してください。

例 : PTP アプリケーション内でのメッセージの同期受信

次の例は、samples\examples\jms\queue ディレクトリに収められている WebLogic Server 付属の examples.jms.queue.QueueReceive サンプルからの引用です。メッセージ リスナを設定するのではなく、各メッセージに対して qreceiver.receive() を呼び出します。次に例を示します。

qreceiver = qsession.createReceiver(queue);
qreceiver.receive();

最初の行では、キューに対するキュー レシーバが作成されます。2 番目の行では、receive() メソッドが実行されます。receive()メソッドは、ブロックしてメッセージを待ちます。

例 : Pub/sub アプリケーション内でのメッセージの同期受信

次の例は、samples\examples\jms\topic ディレクトリに収められている WebLogic Server 付属の examples.jms.topic.TopicReceive サンプルからの引用です。メッセージ リスナを設定するのではなく、各メッセージに対して tsubscriber.receive() を呼び出します。

次に例を示します。

tsubscriber = tsession.createSubscriber(topic);
Message msg = tsubscriber.receive();
msg.acknowledge();

最初の行では、トピックに対するトピック サブスクライバが作成されます。2 番目の行では、receive() メソッドが実行されます。receive()メソッドは、ブロックしてメッセージを待ちます。

受信メッセージの回復

注意: この節は、 非トランザクション セッションで説明したように、確認応答モードが CLIENT_ACKNOWLEDGE に設定されている非トランザクション セッションだけに適用されます。同期受信される AUTO_ACKNOWLEDGE メッセージは確認応答済みのため、受信されないことがあります。

アプリケーションは、次のメソッドを使用して、JMS にメッセージの再配信(未確認)を要求できます。

public void recover(
) throws JMSException

recover() メソッドは、次の手順を実行します。

キュー内のメッセージは、必ずしも元の配信順序と同じ順序で、または同じキュー コンシューマに再配信されるとは限りません。

 


受信メッセージの確認応答

注意: この節は、 非トランザクション セッションで説明したように、確認応答モードが CLIENT_ACKNOWLEDGE に設定されている非トランザクション セッションだけに適用されます。

受信したメッセージの確認応答を行うには、次の Message メソッドを使用します。

public void acknowledge(
) throws JMSException

acknowledge() メソッドは、現在のメッセージと、クライアントの最後の確認応答時から受信した過去のすべてのメッセージの確認応答を行います。確認応答が行われないメッセージは、クライアントに再配信できます。

このメソッドは、確認応答モードが CLIENT_ACKNOWLEDGE に設定されている非トランザクション セッションに対してだけ有効です。それ以外の場合、このメソッドは無視されます。

 


オブジェクト リソースの解放

JMS アプリケーションに代わって作成した接続、セッション、メッセージ プロデューサ/コンシューマ、接続コンシューマ、またはキュー ブラウザを使い終えたら、それらを明示的にクローズしてリソースを解放する必要があります。

JMS オブジェクトをクローズするには、close() メソッドを次のとおり定義します。

public void close(
) throws JMSException

オブジェクトをクローズするときには、以下の処理が行われます。

各オブジェクトについての close() メソッドの影響については、適切な javax.jms Javadoc を参照してください。また、接続またはセッションの close() メソッドの詳細については、 接続の開始、停止、クローズまたは セッションのクローズをそれぞれ参照してください。

次の例は、samples\examples\jms\queue ディレクトリに収められている WebLogic Server 付属の examples.jms.queue.QueueSend サンプルからの引用です。この例を見れば、メッセージ コンシューマ、セッション、および接続オブジェクトをどのようにクローズするかが分かります。

public void close(
) throws JMSException
{
qreceiver.close();
qsession.close();
qcon.close();
}

この QueueSend の例では、main() の最後に close() メソッドが呼び出され、オブジェクトのクローズとリソースの解放が行われます。

 


ロールバックまたは回復したメッセージの管理

以下の節では、ロールバックまたは回復したメッセージを管理する以下の方法について説明します。

メッセージの再配信遅延の設定

一時的または外部的な要因でアプリケーションがメッセージを正しく処理できない場合に、メッセージの再配信を遅延させることができます。これによって、アプリケーションは、現時点では処理できない「有害な」メッセージを一時的に受信できないようにすることができます。メッセージがロールバックまたは回復される場合、再配信遅延は、メッセージが止められてから再配信が試行されるまでの間隔です。

JMS でメッセージをすぐに再配信すると、エラーの原因が解決されず、アプリケーションはメッセージを処理できないままの場合があります。ただし、アプリケーションが再配信遅延用にコンフィグレーションされている場合、メッセージがロールバックまたは回復されると、メッセージは再配信の遅延が過ぎるまで止められます。遅延の期間を過ぎた時点でエラーが解決されていれば、メッセージを再配信できるようになります。

セッションによって消費された結果、ロールバックまたは回復したすべてのメッセージは、ロールバックまたは回復時にそのセッションの再配信遅延を受信します。単一のユーザ トランザクションの一部として複数のセッションで消費されたメッセージは、個々のメッセージを消費したセッションの機能として異なる再配信遅延を受信します。意識的か、または失敗の結果、クライアントによる確認応答またはコミットされていないメッセージには、再配信遅延が割り当てられません。

再配信遅延の設定

セッションは、作成時に接続ファクトリから再配信遅延を継承します。接続ファクトリの RedeliveryDelay 属性は、Administration Console でコンフィグレーションします。詳細については、Administration Console オンライン ヘルプの「JMS 接続ファクトリ」を参照。

セッションを作成するアプリケーションは、javax.jms.Session インタフェースに対する WebLogic 固有の拡張を使用して接続ファクトリ設定をオーバーライドできます。セッション属性は動的なので、いつでも変更できます。セッションの再配信遅延を変更すると、変更後にそのセッションで消費およびロールバック(または回復)されるすべてのメッセージに影響します。

セッションに対して再配信遅延を設定するメソッドは、javax.jms.Session インタフェースの拡張である weblogic.jms.extensions.WLSession インタフェースを介して提供されます。セッションの再配信遅延を定義するには、以下のメソッドを使用します。

public void setRedeliveryDelay(
long redeliveryDelay
) throws JMSException;

public long getRedeliveryDelay(
) throws JMSException;

WLSession クラスの詳細については、weblogic.jms.extensions.WLSession Javadoc を参照してください。

送り先での再配信遅延のオーバーライド

再配信遅延がセッションで設定されているかどうかに関係なく、メッセージがロールバックまたは回復される送り先で再配信遅延の設定をオーバーライドできます。メッセージの再配信に割り当てられた再配信遅延のオーバーライドは、メッセージがロールバックまたは回復されるときに有効になります。

送り先の RedeliveryDelayOverride 属性は、Administration Console でコンフィグレーションします。詳細については、Administration Console オンライン ヘルプの「JMS の送り先」を参照してください。

メッセージの再配信制限の設定

WebLogic JMS によるアプリケーションへのメッセージ再配信の試行回数に対して制限を設けることができます。WebLogic JMS が送り先へのメッセージ再配信を指定した回数だけ試みて失敗すると、メッセージの送り先に関連付けられたエラー送り先にメッセージをリダイレクトできます。エラー送り先がコンフィグレーションされていない場合、メッセージは自動的に削除されます。

メッセージの再配信制限のコンフィグレーション

送り先によるコンシューマへのメッセージ再配信の試行が指定した再配信制限に達すると、送り先はメッセージを配信不能にします。RedeliveryLimit 属性は、送り先で設定され、Administration Console でコンフィグレーションできます。詳細については、Administration Console オンライン ヘルプの「JMS の送り先」を参照してください。

配信されなかったメッセージに対するエラー送り先のコンフィグレーション

配信されなかったメッセージのエラー送り先をコンフィグレーションすると、メッセージが配信不能になったときに、指定したエラー送り先にリダイレクトされます。エラー送り先は、キューでもトピックでもかまいませんが、定義した送り先と同じ JMS サーバでコンフィグレーションする必要があります。エラー送り先がコンフィグレーションされていない場合、配信されなかったメッセージは自動的に削除されます。

送り先の ErrorDestination 属性は、Administration Console でコンフィグレーションします。詳細については、Administration Console オンライン ヘルプの「JMS の送り先」を参照してください。

メッセージの再配信試行が既に指定した制限に達しているものの、エラー送り先も最大割り当てに達している場合、メッセージは配信不能になり、削除されます。永続メッセージは格納され、サーバを再起動すると元の送り先(エラー送り先ではない)に再表示される一方で、非永続メッセージは削除されます。いずれの場合も、ログ メッセージが生成されます。ログ ファイルへの書き込みが滞るのを防ぐために、エラーが解決されるまで、ログ メッセージは、エラー送り先ごとに 5 分おきに 1 回だけ生成されます。

 


メッセージ配信時間の設定

アプリケーションへのメッセージ配信を、将来の指定した時間にスケジューリングできます。メッセージ配信は、短期間(秒や分など)でも長期間(数時間単位でバッチ処理する場合など)でもかまいません。また、相対配信時間(ミリ秒単位)で指定することもできます。この時間は、後でメッセージの絶対配信時間に計算されます。その配信時間になって配信されるまでメッセージは表示されないため、将来の特定の時間に作業をスケジューリングできます。

メッセージが送信されるのは 1 回だけで、繰り返し送信されることはありません。メッセージが繰り返し送信されるようにするには、受信したスケジューリング済みのメッセージを元の送信先に戻す必要があります。1 度のみというセマンティクスを保証するため、受信、送信、およびこれらに関連する作業は同じトランザクションのもとで行われます。

プロデューサに対する配信時間の設定

個々のプロデューサに対する配信時間の設定および取得のサポートは、javax.jms.MessageProducer インタフェースの拡張である weblogic.jms.extensions.WLMessageProducer インタフェースを介して提供されます。個々のプロデューサに対して配信時間を定義するには、以下のメソッドを使用します。

public void setTimeToDeliver(
long timeToDeliver
) throws JMSException;

public long getTimeToDeliver(
) throws JMSException;

WLMessageProducer クラスの詳細については、weblogic.jms.extensions.WLMessageProducer Javadoc を参照してください。

メッセージに対する配信時間の設定

注意: ここで説明するメッセージ メソッドは、プロデューサを介して設定する他の JMS メッセージ メソッドと似ています。特に、配信時間の設定は JMS プロバイダ用に予約されます。アプリケーションはメッセージの値を設定できますが、プロデューサは、メッセージが送信またはパブリッシュされたときにその値をオーバーライドします。

DeliveryTime は、メッセージを配信できる最も早い絶対時間を定義する JMS メッセージ ヘッダです。つまり、メッセージはメッセージング システムによって保持され、その時間になるまでどのコンシューマにも配信されません。

DeliveryTime は、JMS ヘッダ フィールドとして送り先でのメッセージのソート、またはメッセージの選択に使用できます。データ型変換の目的で、配信時間は長整数として保存されます。

個々のメッセージに対する配信時間の設定および取得のサポートは、javax.jms.Message インタフェースの拡張である weblogic.jms.extensions.WLMessage インタフェースを介して提供されます。メッセージの配信時間を定義するには、以下のメソッドを使用します。

public void setJMSDeliveryTime(
long deliveryTime
) throws JMSException;

public long getJMSDeliveryTime(
) throws JMSException;

WLMessage クラスの詳細については、weblogic.jms.extensions.WLMessage Javadoc を参照してください。

配信時間のオーバーライド

作成されたプロデューサは、接続の作成に使用する接続ファクトリ(プロデューサもそこに含まれます)から TimeToDeliver 属性(ミリ秒)を継承します。配信時間がプロデューサで設定されているかどうかに関係なく、メッセージが送信またはパブリッシュされる送り先で配信時間の設定をオーバーライドできます。管理者は、相対形式またはスケジューリング済み文字列形式のいずれかで送り先に対する TimeToDeliverOverride 属性を設定できます。

相対配信時間のオーバーライドの設定

相対 TimeToDeliverOverride は、整数で指定した文字列で、Administration Console でコンフィグレーション可能です。詳細については、Administration Console オンライン ヘルプの「JMS の送り先」を参照してください。

スケジューリング済み配信時間のオーバーライドの設定

スケジューリング済み TimeToDeliverOverrideweblogic.jms.extensions.schedule クラスを使用して指定できます。このクラスは、スケジュールを取得し、指定されたメッセージ配信時間を返すメソッドを提供します。cron に似た文字列がスケジュールの定義に使用されます。書式は、次の BNF 構文で定義されます。

schedule := millisecond second minute hour dayOfMonth month
dayOfWeek

second フィールドを指定するための BNF 構文は次のとおりです。

second := * | secondList
secondList := secondItem [, secondList]
secondItem := secondValue | secondRange
SecondRange := secondValue - secondValue

ミリ秒、分、時、日、月、曜日に対する同様の BNF 文を 2 番目の構文から取得できます。各フィールドの値は、以下の範囲の正の整数で指定します。

milliSecondValue := 0-999
milliSecondValue := 0-999
secondValue := 0-59
minuteValue := 0-59
hourValue := 0-23
dayOfMonthValue := 1-31
monthValue := 1-12
dayOfWeekValue := 1-7

注意: これらの値は、monthValue を除いて、java.util.Calendar クラスで使用するのと同じ範囲です。monthValuejava.util.Calendar の範囲は、1-12 ではなく 0-11 です。

この構文を使用すると、2 つの時間の間のすべての時間を示す値の範囲で各フィールドを表すことができます。たとえば、dayOfWeek フィールドの 2-6 は、月曜から金曜まで(双方の曜日を含む)を示します。また、カンマ区切りのリストで各フィールドを指定することもできます。たとえば、分フィールドの 0,15,30,45 は、1 時間内の 15 分おきの値を示します。さらに、個々の値と値の範囲の組み合わせで各フィールドを定義することもできます。たとえば、時フィールドの 9-17,0 は、午前 9 時と午後 5 時の間と深夜 12 時を示します。

補足のセマンティクスは以下のとおりです。

注意: このクラスの静的メソッドのいずれか 1 つに対するメソッド パラメータとして Calendar が指定されない場合、使用されるカレンダーは、デフォルトの java.util.TimeZone およびデフォルトの java.util.Locale がある java.util.GregorianCalendar です。

表4-3 配信時間のスケジュールの例

説明

0 0 0,30 * * * *

次の最も近い 30 分

* * 0,30 4-5 * * *

午前 4 時から午前 5 時までの 30 分の任意の最初の分

* * * 9-16 * * *

午前 9 時と午後 5 時の間(9:00.00 A.M. 〜 4:59.59 P.M.)

* * * * 8-14 * 2

その月の第 2 火曜日

* * * 13-16 * * 0

日曜日の午後 1 時と午後 5 時の間

* * * * * 31 *

その月の最後の日

* * * * 15 4 1

次に日曜日になる 4 月 15 日

0 0 0 1 * * 2-6;0 0 0 2 * * 1,7

平日の午前 1 時および週末の午前 2 時

JMS スケジュール インタフェース

weblogic.jms.extensions.schedule クラスには、反復時間式に一致する次のスケジュール時間を返すメソッドがあります。この式は、TimeToDeliverOverride と同じ構文を使用します。ミリ秒で返される時間は、相対でも絶対でもかまいません。

WLSession クラスの詳細については、weblogic.jms.extensions.Schedule Javadoc を参照してください。

次のメソッドを使用すると、指定した時間の後の次のスケジュール時間を定義できます。

public static Calendar nextScheduledTime(
String schedule,
Calendar calendar
) throws ParseException {

次のメソッドを使用すると、現在の時間の後の次のスケジュール時間を定義できます。

public static Calendar nextScheduledTime(
String schedule,
) throws ParseException {

次のメソッドを使用すると、指定した時間の後の次のスケジュール時間を絶対ミリ秒で定義できます。

public static long nextScheduledTimeInMillis(
String schedule,
long timeInMillis
) throws ParseException

次のメソッドを使用すると、指定した時間の後の次のスケジュール時間を相対ミリ秒で定義できます。

public static long nextScheduledTimeInMillisRelative(
String schedule,
long timeInMillis
) throws ParseException {

次のメソッドを使用すると、現在の時間の後の次のスケジュール時間を相対ミリ秒で定義できます。

public static long nextScheduledTimeInMillisRelative(
String schedule
) throws ParseException {

存続時間の値との関係

指定した存続時間の値(JMSExpiration)が指定した配信時間と同じかそれより少ない場合、メッセージの配信は成功します。ただし、メッセージは通知されずに期限切れになります。

 


接続の管理

以下の節では、接続を管理する方法について説明します。

接続例外リスナの定義

例外リスナは、接続に問題が発生するとアプリケーションに非同期的に通知します。このメカニズムは、通知されない限り接続がメッセージの消費を待ち続ける場合に役立ちます。

注意: 例外リスナの目的は、接続によって送出されたすべての例外をモニタすることではなく、本来なら配信されない例外を配信することです。

接続に対する例外リスナを定義するには、次の Connection メソッドを使用します。

public void setExceptionListener(
ExceptionListener listener
) throws JMSException

接続に対する ExceptionListener オブジェクトを指定しなければなりません。

JMS プロバイダは、接続の問題を発見すると、次の ExceptionListener メソッドを使用して例外リスナ(定義されている場合)に通知します。

public void onException(
JMSException exception
)

JMS プロバイダは、このメソッドを呼び出すときに、問題を説明する例外を指定します。

接続に対する例外リスナにアクセスするには、次の Connection メソッドを使用します。

public ExceptionListener getExceptionListener(
) throws JMSException

接続メタデータへのアクセス

特定の接続に関連付けられているメタデータにアクセスするには、次の Connection メソッドを使用します。

public ConnectionMetaData getMetaData(
) throws JMSException

このメソッドは、JMS メタデータへのアクセスに使用する ConnectionMetaData オブジェクトを返します。次の表に、JMS メタデータのタイプと、それらにアクセスするために使用できる get メソッドを示します。

表4-4 接続メタデータ get メソッド

JMS メタデータ

get メソッド

バージョン

public String getJMSVersion(
) throws JMSException

メジャー バージョン

public int getJMSMajorVersion(
) throws JMSException

マイナー バージョン

public int getJMSMinorVersion(
) throws JMSException

プロバイダ名

public String getJMSProviderName(
) throws JMSException

プロバイダ バージョン

public String getProviderVersion(
) throws JMSException

プロバイダ メジャー バージョン

public int getProviderMajorVersion(
) throws JMSException

プロバイダ マイナー バージョン

public int getProviderMinorVersion(
) throws JMSException

JMSX プロパティ名

public Enumeration getJMSXPropertyNames(
) throws JMSException

ConnectionMetaData クラスの詳細については、javax.jms.ConnectionMetaData Javadoc を参照してください。

接続の開始、停止、クローズ

メッセージの流れを制御するために、以下の start() メソッドと stop() メソッドをそれぞれ使用して、接続を一時的に開始および停止できます。

start() メソッドと stop() メソッドの詳細は以下のとおりです。

public void start(
) throws JMSException

public void stop(
) throws JMSException

新しく作成された接続は停止しています − 接続が開始するまで、メッセージは受信されません。一般に、他の JMS オブジェクトは、 JMS アプリケーションの設定で説明するとおり、接続が開始する前からメッセージを処理するよう設定されます。メッセージは、停止している接続上に作成することはできますが、停止している接続に届けることはできません。

接続が開始されていれば、stop() メソッドを使用して接続を停止できます。このメソッドは、次の手順を実行します。

一般に、JMS プロバイダは接続を作成するときに大量のリソースを割り当てます。接続が使用されなくなったら、その接続をクローズしてリソースを解放する必要があります。接続をクローズするには、次のメソッドを使用します。

public void close(
) throws JMSException

このメソッドは、次の手順を実行して系統的にシャットダウンを行います。

接続をクローズすると、関連付けられているすべてのオブジェクトがクローズされます。受信メッセージの acknowledge() メソッドを除いて、接続で作成または受信されたメッセージ オブジェクトは引き続き使用できます。閉じた接続をクローズしても影響ははありません。

注意: クローズされた接続のセッションから受信したメッセージを確認応答しようとすると、IllegalStateException が送出されます。

 


セッションの管理

以下の節では、セッションを管理する方法について説明します。

セッション例外リスナの定義

例外リスナは、セッションに問題が発生すると、クライアントに非同期的に通知します。これは、通知されない限りセッションがメッセージの消費を待ち続ける場合に役立ちます。

注意: 例外リスナの目的は、セッションによって送出されたすべての例外をモニタすることではなく、本来なら通知されない例外を通知することです。

セッションに対する例外リスナを定義するには、次の WLSession メソッドを使用します。

public void setExceptionListener(
ExceptionListener listener
) throws JMSException

セッションに対する ExceptionListener オブジェクトを指定しなければなりません。

JMS プロバイダは、セッションの問題を発見すると、次の ExceptionListener メソッドを使用して例外リスナ(定義されている場合)に通知します。

public void onException(
JMSException exception
)

JMS プロバイダは、このメソッドを呼び出すときに、問題を説明する例外を指定します。

セッションに対する例外リスナにアクセスするには、次の WLSession メソッドを使用します。

public ExceptionListener getExceptionListener(
) throws JMSException

注意: 1 つのセッションに対して 1 つのスレッドしか存在しないので、例外リスナとメッセージ リスナ(非同期メッセージ配信用に使用される)を同時に実行することはできません。そのため、問題が発生したときにメッセージ リスナが実行されている場合、そのメッセージ リスナが実行を完了するまで例外リスナはブロックされます。メッセージ リスナの詳細については、 メッセージの非同期受信を参照してください。

セッションのクローズ

接続と同じように、JMS プロバイダはセッションを作成するときに大量のリソースを割り当てます。セッションが使用されなくなったら、そのセッションをクローズしてリソースを解放することをお勧めします。セッションをクローズするには、次の Session メソッドを使用します。

public void close(
) throws JMSException

注意: close() メソッドは、セッション スレッドとは別個のスレッドから呼び出すことができる唯一の Session メソッドです。

このメソッドは、次の手順を実行して系統的にシャットダウンを行います。

セッションをクローズすると、関連付けられているすべてのプロデューサとコンシューマもクローズされます。

注意: onMessage() メソッド呼び出し内で close() メソッドを発行する場合、システム管理者は接続ファクトリをコンフィグレーションするときに [メッセージの短縮を許可] チェック ボックスを選択しなければなりません。詳細については、Administration Console オンライン ヘルプの「JMS 接続ファクトリ」を参照してください。

 


送り先の動的作成

以下のいずれかを使用して、送り先を動的に作成できます。

送り先の動的作成に関する手順については、以降の節で説明します。

JMSHelper クラス メソッドの使い方

以下の各 JMSHelper メソッドを使用してキューまたはトピックを作成する非同期リクエストを動的に送信できます。

static public void createPermanentQueueAsync(
Context ctx,
String jmsServerName,
String queueName,
String jndiName
) throws JMSException

static public void createPermanentTopicAsync(
Context ctx,
String jmsServerName,
String topicName,
String jndiName
) throws JMSException

JNDI 初期コンテキスト、送り先に関連付けられる JMS サーバの名前、送り先(キューまたはトピック)の名前、および JNDI ネームスペース内で送り先をルックアップする場合に使用する名前を指定する必要があります。

各メソッドによって、以下のものが更新されます。

注意: いずれのメソッド呼び出しも、例外を送出せずに失敗する場合があります。また、例外が送出されても、それが必ずしもメソッド呼び出しの失敗を示しているとは限りません。

JMS サーバでの送り先の作成と JNDI ネームスペースへの情報の伝播には、時間がかかる場合があります。複数のサーバを使用している環境では、伝播の遅延が増大します。JNDI ルックアップを実行するよりも、createQueue() メソッドまたは createTopic() メソッドを使用して、それぞれキューまたはトピックの存在をテストすることをお勧めします。この方法によって、伝播固有の遅延を、ある程度回避できます。

たとえば、次に示す findQueue() メソッドは、動的に作成されたキューにアクセスしようとしますが、アクセスに失敗すると再試行まで、指定された間隔スリープします。無限ループを回避するために、再試行の最大回数が設定されています。

private static Queue findQueue (
QueueSession queueSession,
String jmsServerName,
String queueName,
int retryCount,
long retryInterval
) throws JMSException
{
String wlsQueueName = jmsServerName + "/" + queueName;
String command = "QueueSession.createQueue(" +
wlsQueueName + ")";
long startTimeMillis = System.currentTimeMillis();
for (int i=retryCount; i>=0; i--) {
try {
System.out.println("Trying " + command);
Queue queue = queueSession.createQueue(wlsQueueName);
System.out.println(command + "succeeded after " +
(retryCount - i + 1) + " tries in " +
(System.currentTimeMillis() - startTimeMillis) +
" millis.");
return queue;
} catch (JMSException je) {
if (retryCount == 0) throw je;
}
try {
System.out.println(command + “> failed, pausing “ +
retryInterval + " millis.");
Thread.sleep(retryInterval);
} catch (InterruptedException ignore) {}

}
throw new JMSException("out of retries");
}

この場合、JMSHelper クラス メソッドの後に findQueue() メソッドを呼び出すことで、動的に作成されたキューを使用可能になりしだい、取り出すことができます。次に例を示します。

JMSHelper.createPermanentQueueAsync(ctx, domain, jmsServerName,
queueName, jndiName);
Queue queue = findQueue(qsess, jmsServerName, queueName,
retry_count, retry_interval);

JMSHelper クラスの詳細については、weblogic.jms.extensions.JMSHelper Javadoc を参照してください。

一時的な送り先の使い方

一時的な送り先を使用することで、サーバ定義の送り先のコンフィグレーションと作成に伴うシステム管理のオーバーヘッドを発生させずに、必要に応じてアプリケーションで送り先を作成できます。

WebLogic JMS サーバでは、JMSReplyTo ヘッダ フィールドを使用して、アプリケーションに応答を返すことができます。アプリケーションでは、オプションとして、メッセージの JMSReplyTo ヘッダ フィールドをその一時的な送り先に設定することで、使用している一時的な送り先を別のアプリケーションに対して公開できます。

一時的な送り先は、 一時的な送り先の削除にある説明のとおりに delete() メソッドを使用して削除されない限り、現在の接続が継続している間だけ存在します。

サーバが再起動されると、メッセージは使用できなくなるので、すべての PERSISTENT メッセージは自動的に NON_PERSISTENT メッセージになります。そのため、一時的な送り先は、再起動によるデータの消失が許されないビジネス ロジックには適していません。

注意: 一時的な送り先(キューまたはトピック)を作成する前に、Administration Console を使用して、一時的な送り先を使用する JMS サーバをコンフィグレーションする必要があります。そのためには、JMS サーバの Temporary Template 属性を使用して、同じドメイン内でコンフィグレーションされる JMS テンプレートを選択します。JMS サーバのコンフィグレーションについては、Administration Console オンライン ヘルプの「JMS サーバ」を参照してください。

以降の節では、一時的なキュー(PTP)または一時的なトピック(Pub/Sub)の作成方法について説明します。

一時的なキューの作成

次の QueueSession メソッドを使用して、一時的なキューを作成できます。

public TemporaryQueue createTemporaryQueue(
) throws JMSException

たとえば、現在の接続が継続している間だけ存在する TemporaryQueue への参照を作成するには、次のメソッド呼び出しを使用します。

QueueSender = Session.createTemporaryQueue();

一時的なトピックの作成

次の TopicSession メソッドを使用して、一時的なトピックを作成できます。

public TemporaryTopic createTemporaryTopic(
) throws JMSException

たとえば、現在の接続が継続している間だけ存在する一時的なトピックへの参照を作成するには、次のメソッド呼び出しを使用します。

TopicPublisher = Session.createTemporaryTopic();

一時的な送り先の削除

一時的な送り先の使用が終了したら、次の TemporaryQueue メソッドまたは TemporaryTopic メソッドを使用して送り先を削除し、関連リソースを解放できます。

public void delete(
) throws JMSException

 


恒久サブスクリプションの設定

WebLogic JMS では、恒久サブスクリプションおよび非恒久サブスクリプションがサポートされています。

恒久サブスクリプションの場合、WebLogic JMS では、メッセージはサブスクライバに配信されるか、または期限切れになるまでファイルまたはデータベースに格納されます。この場合、メッセージの配信時にサブスクライバがアクティブな状態でなくてもかまいません。サブスクライバを表す Java オブジェクトが存在していれば、サブスクライバはアクティブであるとみなされます。恒久サブスクリプションは、Pub/Sub メッセージングのみでサポートされています。

非恒久サブスクリプションの場合、WebLogic JMS では、メッセージはアクティブ セッションを持つアプリケーションにのみ配信されます。アプリケーションがリスンしていない間にトピックへ送信されたメッセージは、二度とそのアプリケーションに配信されません。つまり、非恒久サブスクリプションは、そのサブスクライバ オブジェクトが存在している間だけ存続します。デフォルトでは、サブスクライバは非恒久です。

以降の節で説明する内容は、次のとおりです。

クライアント ID の定義

恒久サブスクリプションをサポートするには、接続に対してクライアント ID を定義する必要があります。

注意: JMS クライアント ID は、WebLogic セキュリティ レルムでのユーザ認証で使用される WebLogic Server ユーザ名とは必ずしも一致しません。JMS アプリケーションに適合していれば、JMS クライアント ID を WebLogic Server ユーザ名に設定することは当然可能です。

クライアント ID は、以下の 2 つの方法で設定できます。

注意: 恒久サブスクリプションのサポートは、Pub/Sub メッセージング モデル固有の機能なので、クライアント ID はトピック接続でしか使用できません。キュー接続にもクライアント ID がありますが、JMS では使用されません。

恒久サブスクリプションは、一時的なトピックに対しては作成しないでください。一時的なトピックは、現在の接続が継続している間だけ存在するように設計されているからです。

恒久サブスクリプション用のサブスクライバの作成

以下の TopicSession メソッドを使用して、恒久サブスクリプション用のサブスクライバを作成できます。

public TopicSubscriber createDurableSubscriber(
Topic topic,
String name
) throws JMSException

public TopicSubscriber createDurableSubscriber(
Topic topic,
String name,
String messageSelector,
boolean noLocal
) throws JMSException

サブスクライバを作成するトピックの名前と恒久サブスクリプションの名前を指定する必要があります。また、メッセージをフィルタ処理するためのメッセージ セレクタ、および noLocal フラグ(この節で後述)を指定することもできます。メッセージ セレクタの詳細については、 メッセージのフィルタ処理を参照してください。messageSelector を指定しない場合、デフォルトではすべてのメッセージが検索されます。

アプリケーションでは、JMS 接続を使用して同じトピックに対してパブリッシュとサブスクライブの両方を行うことができます。トピック メッセージはすべてのサブスクライバに配信されるので、アプリケーションは自身がパブリッシュしたメッセージを受信する可能性があります。これを防ぐために、JMS アプリケーションは noLocal フラグを true に設定できます。noLocal 値は、デフォルトでは false になっています。

恒久サブスクリプションは、クライアント ID ごとにユニークである必要があります。接続に対するクライアント ID の定義については、 クライアント ID の定義を参照してください。

特定の恒久サブスクリプション用のサブスクライバをいつでも定義できるのは、1 つのセッションだけです。複数のサブスクライバが恒久サブスクリプションにアクセスできますが、同時にはアクセスできません。恒久サブスクリプションはファイルまたはデータベースに格納されます。

恒久サブスクリプションの削除

恒久サブスクリプションを削除するには、次の TopicSession メソッドを使用します。

public void unsubscribe(
String name
) throws JMSException

削除する恒久サブスクリプションの名前を指定する必要があリます。

以下の条件のいずれかに当てはまる場合は、恒久サブスクリプションを削除できません。

注意: WebLogic Server バージョン 6.1 以降の場合は、恒久サブスクリプションの管理用に実行時 MBean が追加されています。この機能を使用すると、Administration Console で恒久サブスクリプションをモニタおよび削除できます。Administration Console による恒久サブスクリプション管理の詳細については、『管理者ガイド』の「JMS の管理」を参照してください。

恒久サブスクリプションの変更

恒久サブスクリプションを変更するには、以下の手順を実行します。

  1. 恒久サブスクリプションの削除にある説明に従って、恒久サブスクリプションを削除します。

    この手順は省略可能です。この手順が明示的に実行されない場合は、次の手順で恒久サブスクリプションが再作成されるときに暗黙的に削除が行われます。

  2. 恒久サブスクリプション用のサブスクライバの作成で説明されているメソッドを使用して、同じ名前の恒久サブスクリプションを再作成します。ただし、トピック名、メッセージ セレクタ、noLocal のいずれかには異なる値を指定します。

    新しい値に基づいて、恒久サブスクリプションが再作成されます。

注意: 恒久サブスクリプションを再作成する場合には、重複した名前を持つ恒久サブスクリプションを作成しないよう注意してください。たとえば、使用できない JMS サーバから恒久サブスクリプションを削除しようとすると、削除は失敗します。続いて、別の JMS サーバで同じ名前の恒久サブスクリプションを作成すると、最初の JMS サーバが使用可能になったときに予期しない結果が生じることがあります。元の恒久サブスクリプションが削除されていないため、最初の JMS サーバが再び使用可能になると、重複した名前の 2 つの恒久サブスクリプションが存在することになります。

 


メッセージ ヘッダ フィールドおよびメッセージ プロパティ フィールドの設定と参照

WebLogic JMS には、メッセージの識別および転送を定義できる一連の標準ヘッダ フィールドが用意されています。さらに、プロパティ フィールドを使用すると、標準セットを拡張した、アプリケーション固有のヘッダ フィールドをメッセージ内に含めることができます。メッセージ ヘッダ フィールドおよびメッセージ プロパティ フィールドを使用して、通信しているプロセス間で情報をやり取りできます。

データをメッセージ本文ではなくプロパティ フィールドに含める主要な理由は、メッセージ セレクタを使用したメッセージのフィルタ処理をサポートするためです。メッセージ セレクタからは、メッセージ本文のデータにはアクセスできません。たとえば、プロパティ フィールドを使用して、あるメッセージに高い優先度を割り当てると仮定します。その場合、このプロパティ フィールドにアクセスし、至急の優先度が指定されたメッセージだけを選択するメッセージ セレクタを含むメッセージ コンシューマを作成できます。セレクタの詳細については、 メッセージのフィルタ処理を参照してください。

メッセージ ヘッダ フィールドの設定

JMS メッセージには、常にメッセージと共に送信されるヘッダ フィールドの標準セットが含まれます。これらはメッセージを受信するメッセージ コンシューマで利用でき、また、一部のフィールドはメッセージを送信するメッセージ プロデューサで設定できます。メッセージを受信したら、ヘッダ フィールドの値は変更できます。

標準メッセージ ヘッダ フィールドの詳細については、 メッセージ ヘッダ フィールドを参照してください。

次の表に、Message クラスの set メソッドと get メソッドを、サポートされているデータ型ごとに示します。

注意: set() メソッドを使用して設定されたヘッダ フィールド値は、send() メソッドによってオーバーライドされる場合もあります(次表参照)。

表4-5 メッセージ ヘッダの set メソッドおよび get メソッド

ヘッダ フィールド

set メソッド

get メソッド

JMSCorrelationID

public void setJMSCorrelationID(
  String correlationID
) throws JMSException

public String getJMSCorrelationID(
) throws JMSException


public byte[] getJMSCorrelationIDAsBytes(
) throws JMSException

JMSDestination1

public void setJMSDestination(
  Destination destination
) throws JMSException

public Destination getJMSDestination(
) throws JMSException

JMSDeliveryMode1

public void setJMSDeliveryMode(
  int deliveryMode
) throws JMSException

public int getJMSDeliveryMode(
) throws JMSException

JMSDeliveryTime1

public void setJMSDeliveryTime(
  long deliveryTime
) throws JMSException

public long getJMSDeliveryTime(
) throws JMSException

JMSDeliveryMode1

public void setJMSDeliveryMode(
  int deliveryMode
) throws JMSException

public int getJMSDeliveryMode(
) throws JMSException

JMSMessageID1

public void setJMSMessageID(
  String id
) throws JMSException

set メソッドだけでなく、weblogic.jms.extensions.JMSHelper クラスには、WebLogic JMS 6.0 以前の JMSMessageID 形式を WebLogic JMS 6.1 の形式に(または WebLogic JMS 6.1 の形式をそれ以前の形式に)変換する、以下のメソッドも用意されている。
public void oldJMSMessageIDToNew(
  String id,
  long timeStamp
) throws JMSException

public void newJMSMessageIDToOld(
  String id,
  long timeStamp
) throws JMSException

public String getJMSMessageID(
) throws JMSException

JMSPriority1

public void setJMSPriority(
  int priority
) throws JMSException

public int getJMSPriority(
) throws JMSException

JMSRedelivered1

public void setJMSRedelivered(
  boolean redelivered
) throws JMSException

public boolean getJMSRedelivered(
) throws JMSException

JMSReplyTo

public void setJMSReplyTo(
  Destination replyTo
) throws JMSException

public Destination getJMSReplyTo(
) throws JMSException

JMSTimeStamp1

public void setJMSTimeStamp(
  long timestamp
) throws JMSException

public long getJMSTimeStamp(
) throws JMSException

JMSType

public void setJMSType(
  String type
) throws JMSException

public String getJMSType(
) throws JMSException

1send() メソッドが実行されている場合、対応する set() メソッドは、メッセージ ヘッダ フィールドに影響を与えません。ヘッダ フィールド値が設定されている場合は、send() メソッドの処理中に、このヘッダ フィールド値がオーバーライドされます。

samples\examples\jms\sender ディレクトリに収められている WebLogic Server 付属の examples.jms.sender.SenderServletサンプルでは、送信するメッセージのヘッダ フィールドを設定する方法、および送信後にメッセージのヘッダ フィールドを表示する方法を示します。

たとえば、send() メソッドの後に置く、次のコードは、WebLogic JMS によってメッセージに割り当てられたメッセージ ID を表示します。

System.out.println("Sent message " +
msg.getJMSMessageID() + " to " +
msg.getJMSDestination());

メッセージ プロパティ フィールドの設定

プロパティ フィールドを設定するには、適切な set メソッドを呼び出して、プロパティ名と値を指定します。プロパティ フィールドを参照するには、適切な get メソッドを呼び出して、プロパティ名を指定します。

送信側アプリケーションでは、メッセージにプロパティを設定できます。受信側アプリケーションではプロパティを表示できますが、次の clearProperties() メソッドを使用して消去してからでないと、プロパティを変更することはできません。

public void clearProperties(
) throws JMSException

このメソッドは、メッセージ ヘッダ フィールドおよびメッセージ本文は消去しません。

注意: JMS 用に JMSX というプロパティ名のプレフィックスが予約されています。接続メタデータには、JMSX プロパティのリストが含まれています。getJMSXPropertyNames() メソッドを使用して、列挙リストとして、このリストにアクセスできます。詳細については、 接続メタデータへのアクセスを参照してください。

プロバイダ固有のプロパティ用に JMS_ というプロパティ名のプレフィックスが予約されています。このプレフィックスは標準の JMS メッセージングでは使用できません。

プロパティ フィールドは、boolean、byte、double、float、int、long、short、string の各データ型のいずれかに設定できます。次の表に、Message クラスの set メソッドと get メソッドを、サポートされているデータ型ごとに示します。

表4-6 メッセージ プロパティのデータ型ごとの set メソッドおよび get メソッド

データ型

set メソッド

get メソッド

boolean

public void setBooleanProperty(
  String name,
  boolean value
) throws JMSException

public boolean getBooleanProperty(
  String name
) throws JMSException

byte

public void setByteProperty(
  String name,
  byte value
) throws JMSException

public byte getByteProperty(
  String name
) throws JMSException

double

public void setDoubleProperty(
  String name,
double value
) throws JMSException

public double getDoubleProperty(
  String name
) throws JMSException

float

public void setFloatProperty(
  String name,
  float value
) throws JMSException

public float getFloatProperty(
  String name
) throws JMSException

int

public void setIntProperty(
  String name,
  int value
) throws JMSException

public int getIntProperty(
  String name
) throws JMSException

long

public void setLongProperty(
  String name,
  long value) throws JMSException

public long getLongProperty(
  String name
) throws JMSException

short

public void setShortProperty(
  String name,
  short value
) throws JMSException

public short getShortProperty(
  String name
) throws JMSException

String

public void setStringProperty(
  String name,
  String value
) throws JMSException

public String getStringProperty(
  String name
) throws JMSException


 

上記の表で説明した set メソッドおよび get メソッド以外にも、setObjectProperty() メソッドおよび getObjectProperty() メソッドを使用して、プロパティのデータ型の具体的なプリミティブ値を使用できます。具体的な値が使用されている場合、プロパティのデータ型はコンパイル時ではなく、実行時に決定されます。有効なオブジェクトのデータ型は、boolean、byte、double、float、int、long、short、および string です。

次の Message メソッドを使用して、すべてのプロパティ フィールド名にアクセスできます。

public Enumeration getPropertyNames(
) throws JMSException

このメソッドは、すべてのプロパティ フィールド名を列挙して返します。その後、プロパティ フィールドのデータ型に基づいて、上記の表で説明されている適切な get メソッドにプロパティ フィールド名を渡すことで、各プロパティ フィールドの値を取り出すことができます。

次の表は、メッセージ プロパティの変換表です。この表から、読み込み可能なデータ型を、書き込まれたデータ型に基づいて識別できます。

表4-7 メッセージ プロパティの変換表

書き込まれた
プロパティの
データ型

読み込み可能なデータ型

boolean

byte

double

float

int

long

short

String

boolean

X







X

byte


X



X

X

X

X

double



X





X

float



X

X




X

int





X

X


X

long






X


X

Object

X

X

X

X

X

X

X

X

short





X

X

X

X

String

X

X

X

X

X

X

X

X


 

次の Message メソッドを使用して、プロパティの値が設定されているかどうかをテストできます。

public boolean propertyExists(
String name
) throws JMSException

プロパティ名を指定すると、メソッドはそのプロパティが存在するかどうかを示すブール値を返します。

たとえば、次のコードは、2 種類の String プロパティと 1 種類の int プロパティを設定します。

msg.setStringProperty("User", user);
msg.setStringProperty("Category", category);
msg.setIntProperty("Rating", rating);

メッセージ プロパティ フィールドの詳細については、 メッセージ プロパティ フィールドまたは javax.jms.Message Javadoc を参照してください。

メッセージ ヘッダ フィールドおよびメッセージ プロパティ フィールドの参照

注意: 参照できるのは、キューのメッセージ ヘッダ フィールドおよびメッセージ プロパティ フィールドだけです。トピックのメッセージ ヘッダ フィールドおよびメッセージ プロパティ フィールドは参照できません。

以下の QueueSession メソッドを使用して、キューにあるメッセージのヘッダ フィールドおよびプロパティ フィールドを参照できます。

public QueueBrowser createBrowser(
Queue queue
) throws JMSException

public QueueBrowser createBrowser(
Queue queue,
String messageSelector
) throws JMSException

参照するキューを指定する必要があります。また、参照するメッセージをフィルタ処理するメッセージ セレクタを指定することもできます。メッセージ セレクタの詳細については、 メッセージのフィルタ処理を参照してください。

キューを定義すると、以下の QueueBrowser メソッドを使用して、キュー ブラウザに関連付けられたキュー名およびメッセージ セレクタにアクセスできるようになります。

public Queue getQueue(
) throws JMSException

public String getMessageSelector(
) throws JMSException

さらに、次の QueueBrowser メソッドを使用して、メッセージを参照するための列挙値にアクセスできます。

public Enumeration getEnumeration(
) throws JMSException

samples\examples\jms\queue ディレクトリに収められている WebLogic Server 付属の examples.jms.queue.QueueBrowser サンプルでは、受信メッセージのヘッダ フィールドにアクセスする方法を示します。

たとえば、次の QueueBrowser サンプルからの引用コードでは、QueueBrowser オブジェクトを作成します。

qbrowser = qsession.createBrowser(queue);

次のコードは、QueueBrowser サンプルで定義されている displayQueue() メソッドからの引用です。この例では、QueueBrowser オブジェクトを使用して、キューのメッセージをスキャンする場合に使用される列挙値を取得します。

public void displayQueue(
) throws JMSException
{
Enumeration e = qbrowser.getEnumeration();
Message m = null;

if (! e.hasMoreElements()) {
System.out.println("There are no messages on this queue.");
} else {

System.out.println("Queued JMS Messages: ");
while (e.hasMoreElements()) {
m = (Message) e.nextElement();
System.out.println("Message ID " + m.getJMSMessageID() +
" delivered " + new Date(m.getJMSTimestamp())
" to " + m.getJMSDestination());
}
}

キュー ブラウザが使用されていない場合は、キュー ブラウザを閉じてリソースを解放する必要があります。詳細については、 オブジェクト リソースの解放を参照してください。

QueueBrowser クラスの詳細については、javax.jms.QueueBrowser Javadoc を参照してください。

 


メッセージのフィルタ処理

多くの場合、アプリケーションでは、配信されるすべてのメッセージが通知される必要はありません。メッセージ セレクタを使用すると、不要なメッセージをフィルタ処理できるので、ネットワーク トラフィックへの影響が最小限になり、パフォーマンスが向上します。

メッセージ セレクタは、以下のように動作します。

メッセージ セレクタはメッセージの内容(本文)を参照することができないため、情報の一部をメッセージ プロパティ フィールドに複製することもできます(XML メッセージの場合を除く)。

キュー レシーバまたはトピック サブスクライバの作成時に、それぞれ QueueSession.createReceiver() メソッドまたは TopicSession.createSubscriber() メソッドの引数としてセレクタを指定します。キュー レシーバまたはトピック サブスクライバの作成の詳細については、 手順 5 : セッションと送り先を使用してメッセージ プロデューサとメッセージ コンシューマを作成するを参照してください。

以降の節では、SQL 文と XML セレクタ メソッドを使用してメッセージ セレクタを定義する方法、およびメッセージ セレクタを更新する方法について説明します。ヘッダ フィールドおよびプロパティ フィールドの設定の詳細については、それぞれ メッセージ ヘッダ フィールドおよびメッセージ プロパティ フィールドの設定と参照または メッセージ プロパティ フィールドの設定を参照してください。

SQL 文を使用したメッセージ セレクタの定義

メッセージ セレクタはブール式であり、SQLselect 文の where 句と似た構文を持つ文字列です。

次の引用は、セレクタ式の例を示します。

salary > 64000 and dept in ('eng','qa')

(product like 'WebLogic%' or product like '%T3')
and version > 3.0

hireyear between 1990 and 1992
or fireyear is not null

fireyear - hireyear > 4

次の例では、キュー レシーバの作成時に、優先度が 6 未満のメッセージをフィルタで除外するセレクタを設定する方法を示します。

String selector = "JMSPriority >= 6";
qsession.createReceiver(queue, selector);

次の例では、トピック サブスクライバの作成時に、同様のセレクタを設定する方法を示します。

String selector = "JMSPriority >= 6";
qsession.createSubscriber(topic, selector);

メッセージ セレクタの構文の詳細については、javax.jms.Message Javadoc を参照してください。

XML セレクタ メソッドを使用した XML メッセージ セレクタの定義

XML メッセージ タイプの場合、メッセージ セレクタの定義には、前節で説明した SQL セレクタ式だけでなく、次のメソッドを使用することもできます。

String JMS_BEA_SELECT(String type, String expression)

JMS_BEA_SELECT は、WebLogic JMS SQL 構文の組み込み関数です。構文タイプと XPath 式を指定します。このリリースの構文タイプは、xpath(XML Path Language)に設定する必要があります。XML Path Language は、XML Path Language(XPath)のドキュメントで定義されており、XML Path Language の Web サイト http://www.w3.org/TR/xpath で入手できます。

注意: XML メッセージが壊れていると (終了タグがないなど) どの XML セレクタとも一致しないので、XML メッセージの構文には十分注意してください。

以下の環境では、メソッドは NULL 値を返します。

たとえば、次のような XML の引用があります。

<order>
<item>
<id>007</id>
<name>Hand-held Power Drill</name>
<description>Compact, assorted colors.</description>
<price>$34.99</price>
</item>
<item>
<id>123</id>
<name>Mitre Saw</name>
<description>Three blades sizes.</description>
<price>$69.99</price>
</item>
<item>
<id>66</id>
<name>Socket Wrench Set</name>
<description>Set of 10.</description>
<price>$19.99</price>
</item>
</order>

次の例は、上記のサンプルにおける 2 番目の項目の名前を取り出す方法を示したものです。このメソッド呼び出しからは、「Mitre Saw」という文字列が返ります。

String sel = "JMS_BEA_SELECT(`xpath', `/order/item[2]/name/text()') = `Mitre Saw'";

二重引用符と一重引用符およびスペースの使い方に注意する必要があります。xpath、XML タブ、および文字列値を囲む一重引用符の使い方に注意してください。

次の例は、上記のサンプルにおける 3 番目の項目の ID を取り出す方法を示したものです。このメソッド呼び出しからは、「66」という文字列が返ります。

String sel = "JMS_BEA_SELECT(`xpath', `/order/item[3]/id/text()') = `66'";

メッセージ セレクタの表示

次の MessageConsumer メソッドを使用して、メッセージ セレクタを表示できます。

public String getMessageSelector(
) throws JMSException

このメソッドは、現在定義されているメッセージ セレクタ、またはメッセージ セレクタが定義されていない場合は NULL のいずれかを返します。

トピック サブスクライバ メッセージ セレクタのインデックス付けによるパフォーマンスの最適化

WebLogic JMS では、アプリケーションがある特定の特長を備えている場合、トピック サブスクライバ メッセージ セレクタにインデックスを付けることで、メッセージ セレクタを大幅に最適化できます。対象となるのは、通常、サブスクライバの数が多く、各サブスクライバが固有の識別子 (ユーザ名など) を持ち、単一のサブスクライバまたはサブスクライバのリストに迅速にメッセージを送信する必要があるアプリケーションです。典型的な例は、各サブスクライバが異なるユーザに対応し、各メッセージに 1 つ以上の対象ユーザのリストが含まれるようなインスタント メッセージング アプリケーションです。

最適化されたサブスクライバ メッセージ セレクタをアクティブにするには、サブスクライバはセレクタに対して次の構文を使用する必要があります。

"identifier IS NOT NULL"

identifier は、定義済みの JMS メッセージ プロパティではない (たとえば、JMSCorrelationIDJMSType 以外の) 任意の文字列です。複数のサブスクライバが同じ識別子を共有できます。

WebLogic JMS は、この構文どおりに記述されたメッセージ セレクタをヒントにして、内部的なサブスクライバ インデックスを作成します。この構文に従わないメッセージ セレクタ、または余分な OR 句や AND 句を含むメッセージ セレクタも受け付けられますが、最適化は有効になりません。

サブスクライバがこのメッセージ セレクタ構文を使って登録してあると、メッセージのユーザ プロパティに 1 つ以上の識別子を含めることで、特定のサブスクライバを対象にしたメッセージをトピックにパブリッシュすることができます。次に例を示します。

// 名前付きのサブスクライバを設定する。"Wilma" はサブスクライバの名前で
// subscriberSession は JMS TopicSession である。
// 使われているセレクタ構文によって最適化が有効になる。

TopicSubscriber topicSubscriber =
subscriberSession.createSubscriber(
(Topic)context.lookup("IMTopic"),
"Wilma IS NOT NULL",
/* noLocal= */ true);

// サブスクライバ "Fred" と "Wilma" にメッセージを送信する。
// publisherSession は JMS TopicSession である。
// メッセージ セレクタ式 "Wilma IS NOT NULL" または "Fred IS NOT NULL"
// を指定しているサブスクライバは、このメッセージを受け取る。

TopicPublisher topicPublisher =
publisherSession.createPublisher(
(Topic)context.lookup("IMTopic");

TextMessage msg =
publisherSession.createTextMessage("Hi there!");
msg.setBooleanProperty("Fred", true);
msg.setBooleanProperty("Wilma", true);

topicPublisher.publish(msg);

注意: 最適化されたメッセージ セレクタとメッセージの構文は、標準の JMS API に基づいています。したがって、この構文を使用するアプリケーションは、メッセージ セレクタを最適化していない WebLogic JMS のバージョンだけでなく、WebLogic JMS 以外の製品でも動作します。ただし、これらのバージョンでは、最適化拡張機能を有効にしたバージョンよりパフォーマンスが劣ります。

メッセージ セレクタの最適化は、MULTICAST_NO_ACKNOWLEDGE 確認応答モードを使用するアプリケーションに対しては影響がありません。このようなアプリケーションでは、メッセージ選択はサーバサイドではなくクライアントサイドで行われるので、そもそもこの拡張機能を使う必要がありません。

 


サーバ セッション プールの定義

WebLogic JMS には、サーバ セッションのサーバ管理プールを定義するためのオプションの JMS 機能が実装されています。この機能を使用すると、アプリケーションで複数のメッセージを並行して処理できます。

サーバ セッション プールの機能は次のとおりです。

次の図に、サーバ セッション プール機能、およびアプリケーションとアプリケーション サーバのコンポーネントの関係を示します。

図4-3 サーバ セッション プール機能


 

図に示されているように、アプリケーションにはシングル スレッドのメッセージ リスナが用意されています。JMS によって実装された、アプリケーション サーバ上の接続コンシューマによって、以下のタスクが実行され、1 つまたは複数のメッセージが処理されます。

  1. サーバ セッション プールからサーバ セッションを取得する

  2. サーバ セッションのセッションを取得する

  3. セッションに 1 つまたは複数のメッセージをロードする

  4. サーバ セッションを開始して、メッセージを受信する

  5. メッセージの処理が終了したら、サーバ セッションを解放してプールに戻す

次の図に、メッセージの並行処理を行うための準備に必要な手順を示します。

図4-4 メッセージの並行処理を行うための準備


 
 

注意: サーバ セッション プールを作成する場合(手順 2)、WebLogic Server ではまず、weblogic.allow.create.jms.ServerSessionPool ACL がテストされ、ユーザに create パーミッションが付与されていることが確認されます。このパーミッションは、デフォルトでは everyone に付与されています。このプロパティを更新して、パーミッションを特定のユーザやグループに制限したり、このプロパティを削除して、サーバ セッション プール機能を無効にしたりできます。ACL のコンフィグレーションの詳細については、『 管理者ガイド』の「セキュリティの管理」を参照してください。

この手順では、アプリケーションで、他のアプリケーション サーバ プロバイダのセッション プール実装を使用できます。サーバ セッション プールはメッセージ駆動型 Bean を使用して実装することもできます。メッセージ駆動型 Bean によるサーバ セッション プールの実装については、『 WebLogic エンタープライズ JavaBeans プログラマーズ ガイド』を参照してください。

コンフィグレーション時にセッション プールと接続コンシューマが定義された場合は、この手順を省略することができます。サーバ セッション プールと接続コンシューマのコンフィグレーションの詳細については、『管理者ガイド』の「JMS の管理」を参照してください。

WebLogic JMS は現在、オプションの TopicConnection.createDurableConnectionConsumer() 操作をサポートしていません。この高機能 JMS の操作の詳細については、Sun Microsystems JMS 仕様 を参照してください。

手順 1 : JNDI でサーバ セッション プール ファクトリをルックアップする

サーバ セッション プール ファクトリを使用して、サーバ セッション プールを作成します。

WebLogic JMS では、デフォルトで次のような ServerSessionPoolFactory オブジェクトが定義されています。weblogic.jms.ServerSessionPoolFactory:<name>。ここで <name> には、セッション プールの作成先になる JMS サーバの名前を指定します。

コンフィグレーションが終了したら、サーバ セッション プール ファクトリをルックアップするために、まず NamingManager.InitialContext() メソッドを使用して JNDI コンテキスト(context)を定義します。サーブレット アプリケーション以外のアプリケーションの場合は、初期コンテキストの作成に使用する環境を渡す必要があります。詳細については、NamingManager.InitialContext() Javadoc を参照してください。

コンテキストが定義されたら、次のコードを使用して、JNDI でサーバ セッション プール ファクトリをルックアップします。

factory = (ServerSessionPoolFactory) context.lookup(<ssp_name>);

<ssp_name> には、サーバ セッション プール ファクトリの修飾名または非修飾名を指定します。

サーバ セッション プール ファクトリの詳細については、 ServerSessionPoolFactoryまたは weblogic.jms.ServerSessionPoolFactory Javadoc を参照してください。

手順 2 : サーバ セッション プール ファクトリを使用してサーバ セッション プールを作成する

以降の節で説明する ServerSessionPoolFactory メソッドを使用して、キュー(PTP)またはトピック(Pub/Sub)の接続コンシューマで使用するサーバ セッション プールを作成できます。

サーバ セッション プールの詳細については、 ServerSessionPoolまたは javax.jms.ServerSessionPool Javadoc を参照してください。

キュー接続コンシューマで使用するサーバ セッション プールを作成する

ServerSessionPoolFactory には、キュー接続コンシューマ用のサーバ セッション プールを作成する、次のメソッドが用意されています。

public ServerSessionPool getServerSessionPool(
QueueConnection connection,
int maxSessions,
boolean transacted,
int ackMode,
String listenerClassName
) throws JMSException

サーバ セッション プールに関連付けられるキュー接続、接続コンシューマ(手順 3 で作成予定)で取得できる並行セッションの最大数、セッションをトランザクション処理するかどうか、確認応答モード(トランザクション処理されないセッションの場合にのみ適用可能)、およびインスタンス化され、メッセージの受信および並行処理に使用されるメッセージ リスナ クラスを指定する必要があります。

ServerSessionPoolFactory クラス メソッドの詳細については、weblogic.jms.ServerSessionPoolFactoryJavadoc を参照してください。ConnectionConsumer クラスの詳細については、javax.jms.ConnectionConsumer Javadoc を参照してください。

トピック接続コンシューマで使用するサーバ セッション プールを作成する

ServerSessionPoolFactory には、トピック接続コンシューマ用のサーバ セッション プールを作成する、次のメソッドが用意されています。

public ServerSessionPool getServerSessionPool(
TopicConnection connection,
int maxSessions,
boolean transacted,
int ackMode,
String listenerClassName
) throws JMSException

サーバ セッション プールに関連付けられるトピック接続、接続コンシューマ(手順 3 で作成予定)で取得できる並行セッションの最大数、セッションをトランザクション処理するかどうか、確認応答モード(トランザクション処理されないセッションの場合にのみ適用可能)、およびインスタンス化され、メッセージの受信および並行処理に使用されるメッセージ リスナ クラスを指定する必要があります。

ServerSessionPoolFactory クラス メソッドの詳細については、weblogic.jms.ServerSessionPoolFactoryJavadoc を参照してください。ConnectionConsumer クラスの詳細については、javax.jms.ConnectionConsumer Javadoc を参照してください。

手順 3 : 接続コンシューマを作成する

以下の方法のいずれかを使用して、サーバ セッションを取得し、メッセージを並行処理するための接続コンシューマを作成できます。

ConnectionConsumer クラスの詳細については、 ConnectionConsumerまたは javax.jms.ConnectionConsumer Javadoc を参照してください。

キュー用の接続コンシューマを作成する

QueueConnection には、キュー用の接続コンシューマを作成する、次のメソッドが用意されています。

public ConnectionConsumer createConnectionConsumer(
Queue queue,
String messageSelector,
ServerSessionPool sessionPool,
int maxMessages
) throws JMSException

関連付けられるキューの名前、メッセージをフィルタ処理するためのメッセージ セレクタ、サーバ セッションにアクセスするためのサーバ セッション プール、およびサーバ セッションに同時に割り当てることができるメッセージの最大数を指定する必要があります。メッセージ セレクタの詳細については、 メッセージのフィルタ処理を参照してください。

QueueConnection クラス メソッドの詳細については、javax.jms.QueueConnection Javadoc を参照してください。ConnectionConsumer クラスの詳細については、javax.jms.ConnectionConsumer Javadoc を参照してください。

トピック用の接続コンシューマを作成する

TopicConnection には、トピック用のConnectionConsumers を作成する、以下の 2 種類のメソッドが用意されています。

public ConnectionConsumer createConnectionConsumer(
Topic topic,
String messageSelector,
ServerSessionPool sessionPool,
int maxMessages
) throws JMSException

public ConnectionConsumer createDurableConnectionConsumer(
Topic topic,
String messageSelector,
ServerSessionPool sessionPool,
int maxMessages
) throws JMSException

各メソッドには、関連付けられるトピックの名前、メッセージをフィルタ処理するためのメッセージ セレクタ、サーバ セッションにアクセスするためのサーバ セッション プール、およびサーバ セッションに同時に割り当てることができるメッセージの最大数を指定する必要があります。メッセージ セレクタの詳細については、 メッセージのフィルタ処理を参照してください。

いずれのメソッドも接続コンシューマを作成しますが、後者のメソッドは、恒久サブスクライバで使用する恒久接続コンシューマも作成します。恒久サブスクライバの詳細については、 恒久サブスクリプションの設定を参照してください。

TopicConnection クラス メソッドの詳細については、javax.jms.TopicConnection Javadoc を参照してください。ConnectionConsumer クラスの詳細については、javax.jms.ConnectionConsumer Javadoc を参照してください。

例 : PTP クライアントのサーバ セッション プールの設定

次の例では、JMS クライアント用のサーバ セッション プールを設定する方法を示します。startup() メソッドは、 例 : PTP アプリケーションの設定で説明されている examples.jms.queue.QueueSend サンプルの init() メソッドとほぼ同じです。このメソッドでもサーバ セッション プールを設定できます。

次の例に startup() メソッドを示し、合わせて各設定手順も述べます。

サーバ セッション プール アプリケーションを実装するには、次のパッケージをインポート リストに追加します。

import weblogic.jms.ServerSessionPoolFactory

セッション プールの作成に必要なセッション プール ファクトリの静的変数を定義します。

private final static String SESSION_POOL_FACTORY=
"weblogic.jms.ServerSessionPoolFactory:examplesJMSServer";

private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private ServerSessionPoolFactory sessionPoolFactory;
private ServerSessionPool sessionPool;
private ConnectionConsumer consumer;

必要な JMS オブジェクトを作成します。

public String startup(
String name,
Hashtable args
) throws Exception

{
String connectionFactory = (String)args.get("connectionFactory");
String queueName = (String)args.get("queue");
if (connectionFactory == null || queueName == null) {
throw new IllegalArgumentException("connectionFactory="+connectionFactory+
", queueName="+queueName);
}
Context ctx = new InitialContext();
qconFactory = (QueueConnectionFactory)
ctx.lookup(connectionFactory);
qcon =qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qcon.start();

手順 1

JNDI でサーバ セッション プール ファクトリをルックアップします。

sessionPoolFactory = (ServerSessionPoolFactory)
ctx.lookup(SESSION_POOL_FACTORY);

手順 2

次のように、サーバ セッション プール ファクトリを使用してサーバ セッション プールを作成します。

sessionPool = sessionPoolFactory.getServerSessionPool(qcon, 5,
false, Session.AUTO_ACKNOWLEDGE,
examples.jms.startup.MsgListener);

このコードでは、以下のように定義されています。

手順 3

次のように、接続コンシューマを作成します。

consumer = qcon.createConnectionConsumer(queue, "TRUE",
sessionPool, 10);

このコードでは、以下のように定義されています。

この例で使用した JMS クラスの詳細については、 WebLogic JMS のクラスまたは javax.jms Javadoc を参照してください。

例 : Pub/Sub クライアントのサーバ セッション プールの設定

次の例では、JMS クライアント用のサーバ セッション プールを設定する方法を示します。startup() メソッドは、 例 : Pub/Sub アプリケーションの設定で説明されている examples.jms.topic.TopicSend サンプルの init() メソッドとほぼ同じです。このメソッドでもサーバ セッション プールを設定できます。

次の例に startup() メソッドを示し、合わせて各設定手順も述べます。

サーバ セッション プール アプリケーションを実装するには、次のパッケージをインポート リストに追加します。

import weblogic.jms.ServerSessionPoolFactory

セッション プールの作成に必要なセッション プール ファクトリの静的変数を定義します。

private final static String SESSION_POOL_FACTORY=
"weblogic.jms.ServerSessionPoolFactory:examplesJMSServer";

private TopicConnectionFactory tconFactory;
private TopicConnection tcon;
private TopicSession tsession;
private TopicSender tsender;
private Topic topic;
private ServerSessionPoolFactory sessionPoolFactory;
private ServerSessionPool sessionPool;
private ConnectionConsumer consumer;

必要な JMS オブジェクトを作成します。

public String startup(
String name,
Hashtable args
) throws Exception

{
String connectionFactory = (String)args.get("connectionFactory");
String topicName = (String)args.get("topic");
if (connectionFactory == null || topicName == null) {
throw new IllegalArgumentException("connectionFactory="+connectionFactory+
", topicName="+topicName);
}
Context ctx = new InitialContext();
tconFactory = (TopicConnectionFactory)
ctx.lookup(connectionFactory);
tcon = tconFactory.createTopicConnection();
tsession = tcon.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = (Topic) ctx.lookup(topicName);
tcon.start();

手順 1

JNDI でサーバ セッション プール ファクトリをルックアップします。

sessionPoolFactory = (ServerSessionPoolFactory)
ctx.lookup(SESSION_POOL_FACTORY);

手順 2

次のように、サーバ セッション プール ファクトリを使用してサーバ セッション プールを作成します。

sessionPool = sessionPoolFactory.getServerSessionPool(tcon, 5,
false, Session.AUTO_ACKNOWLEDGE,
examples.jms.startup.MsgListener);

このコードでは、以下のように定義されています。

手順 3

次のように、接続コンシューマを作成します。

consumer = tcon.createConnectionConsumer(topic, "TRUE",
sessionPool, 10);

このコードでは、以下のように定義されています。

この例で使用した JMS クラスの詳細については、 WebLogic JMS のクラスまたは javax.jms Javadoc を参照してください。

 


マルチキャストの使い方

マルチキャストを使用することによって、後でメッセージをサブスクライバに転送する、指定したホストのグループにメッセージを配信できます。

マルチキャストには、次のような利点があります。

マルチキャストには、次のような制約があります。

マルチキャストを使用すると便利な例としては、株価表示があります。最新の株価を入手する場合に重要になるのは、信頼性よりもタイムリーな配信です。全部または一部の内容が配信されなくても、リアルタイムの株価情報にアクセスするときに、クライアントは簡単に情報の再送信を要求できます。クライアントでは情報の回復は必要とされません。回復された情報が再配信される頃には、その情報は古くて価値のないものになっています。

次の図に、マルチキャストの設定に必要な手順を示します。

図4-5 マルチキャストの設定


 
 
 

注意: マルチキャストは、Pub/Sub メッセージング モデル、および非恒久サブスクライバのみでサポートされています。

マルチキャスト セッションおよびマルチキャスト コンシューマに関するモニタ統計は提供されません。

マルチキャストを設定する前に、マルチキャストをサポートするよう、次のように接続ファクトリおよび送り先をコンフィグレーションする必要があります。

注意: マルチキャスト IP アドレス、ポート、存続時間の各属性をコンフィグレーションする場合は、ネットワーク管理者に相談してから、適切な値を設定することをお勧めします。

マルチキャストのコンフィグレーション属性の詳細については、Administration Console オンライン ヘルプを参照してください。マルチキャストのコンフィグレーション属性は、 コンフィグレーション チェックリストでも簡単に説明されています。

手順 1 :JMS アプリケーションを設定し、マルチキャスト セッションとトピック サブスクライバを作成する

JMS アプリケーションの設定にある説明に従って JMS アプリケーションを設定します。ただし、セッションを作成するときは( 手順 3 : 接続を使用してセッションを作成する参照)、acknowledgeMode 値を MULTICAST_NO_ACKNOWLEDGE に設定して、そのセッションでマルチキャスト メッセージを受信するように指定します。

注意: マルチキャストは、非恒久サブスクライバに対する Pub/Sub メッセージング モデルでのみサポートされています。マルチキャスト セッションで恒久サブスクライバを作成しようとすると、JMSException が送出されます。

たとえば、次のメソッドは、Pub/Sub メッセージング モデル用のマルチキャスト セッションの作成方法を示します。

tsession = tcon.createTopicSession(
false,
WLSession.MULTICAST_NO_ACKNOWLEDGE
);

注意: クライアント サイドでは、ソケットからメッセージを取り出すには、マルチキャストを行うセッションごとに専用のスレッドが 1 つ必要です。したがって、JMS クライアント サイドのスレッド プール サイズを増やして調節する必要があります。スレッド プール サイズを調節する方法の詳細については、http://dev2dev.bea.com/resourcelibrary/whitepapers.jsp?highlight=whitepapers にある『WebLogic JMS Performance Guide』ホワイト ペーパーの「Tuning Thread Pools and EJB Pools」の節を参照してください。この節では、JMS クライアント サイドのスレッド プールのチューニングについて解説されています。

さらに、 TopicPublisher と TopicSubscriber の作成にある説明に従って、トピック サブスクライバを作成します。

たとえば、次のコードは、トピック サブスクライバの作成方法を示します。

tsubscriber = tsession.createSubscriber(myTopic);

注意: 指定した送り先がマルチキャストをサポートするようコンフィグレーションされていない場合、createSubscriber() メソッドは失敗します。

手順 2 :メッセージ リスナを設定する

マルチキャストのトピック サブスクライバでは、メッセージを非同期に受信することしかできません。マルチキャスト セッションで同期メッセージを受信しようとすると、JMSException が送出されます。

メッセージの非同期受信にある説明に従って、トピック サブスクライバに対してメッセージ リスナを設定します。

たとえば、次のコードは、メッセージ リスナの設定方法を示します。

tsubscriber.setMessageListener(this);

メッセージを受信すると、WebLogic JMS では、送り先から送信されたメッセージのシーケンスがトラッキングされます。マルチキャスト サブスクライバのメッセージ リスナがシーケンスが異なるメッセージを受信すると、その結果、1 つまたは複数のメッセージがスキップされ、そのセッションの ExceptionListenerSequenceGapException が送出されます。スキップされたメッセージは、その後配信されても破棄されます。たとえば、次の図では、サブスクライバは 2 つの送り先から同時にメッセージを受信しています。

図4-6 マルチキャストにおけるシーケンスのずれ


 

送り先 1 からメッセージ「4」を受信すると、SequenceGapException が送出され、シーケンスが異なるメッセージが受信されたことがアプリケーションに通知されます。その後、メッセージ「3」が配信されても、それは破棄されます。

注意: やり取りされるメッセージ数が多くなるほど、SequenceGapException が発生する危険性も大きくなります。

マルチキャストのコンフィグレーション属性の動的コンフィグレーション

システム管理者は、コンフィグレーション時に、マルチキャストをサポートするよう、各接続ファクトリに対して以下の情報をコンフィグレーションします。

メッセージが最大数に達すると、DataOverrunException が送出され、メッセージは超過時のポリシーに基づいて自動的に破棄されます。

また、Session クラスの set メソッドを使用して、最大メッセージと超過時のポリシーを設定する方法もあります。

次の表に、Session クラスの set メソッドと get メソッドを、動的コンフィグレーションが可能な属性ごとに示します。

表4-8 メッセージ プロデューサの set メソッドおよび get メソッド

属性

set メソッド

get メソッド

最大メッセージ

public void setMessagesMaximum(
  int messagesMaximum
) throws JMSException

public int getMessagesMaximum(
) throws JMSException

超過時のポリシー

public void setOverrunPolicy (
  int overrunPolicy
) throws JMSException

public int getOverrunPolicy(
) throws JMSException

注意: set メソッドを使用して設定された値は、コンフィグレーションされた値よりも優先されます。

Session クラス メソッドの詳細については、weblogic.jms.extensions.WLSession Javadoc を参照してください。マルチキャストのコンフィグレーション属性の詳細については、Administration Console オンライン ヘルプの「JMS の送り先」を参照してください。

例 : マルチキャスト TTL(存続時間)

注意: 次の図は、マルチキャスト TTL(存続時間)送り先コンフィグレーション属性が、ルータを経由したメッセージの配信に影響する様子を説明するための単純な例です。マルチキャスト TTL 属性をコンフィグレーションする場合は、ネットワーク管理者に相談してから、適切な値を設定することをお勧めします。

マルチキャスト TTL は、メッセージの存続時間に依存しません。

次の例では、マルチキャスト TTL 送り先コンフィグレーション属性が、ルータを経由したメッセージの配信に影響する様子を示します。マルチキャストのコンフィグレーション属性の詳細については、Administration Console オンライン ヘルプの「JMS の送り先」を参照してください。

次のようなネットワーク図があります。

図4-7 マルチキャスト TTL の例


 

この図では、ネットワークは 3 つのサブネットで構成されています。サブネット A にはマルチキャスト パブリッシャがあり、サブネット B および C にはそれぞれ 1 台ずつマルチキャスト サブスクライバがあります。

マルチキャスト TTL 属性が 0 に設定されている(メッセージはルータを経由できず、現在のサブネットにしか配信されないことを示す)場合は、サブネット A にあるマルチキャスト パブリッシャでメッセージがパブリッシュされても、メッセージはどのマルチキャスト サブスクライバにも配信されません。

マルチキャスト TTL 属性が 1 に設定されている(メッセージは 1 台のルータを経由できることを示す)場合、サブネット A にあるマルチキャスト パブリッシャでメッセージがパブリッシュされると、サブネット B にあるマルチキャスト サブスクライバでメッセージが受信されます。

同様に、マルチキャスト TTL 属性が 2 に設定されている(メッセージは 2 台のルータを経由できることを示す)場合、サブネット A にあるマルチキャスト パブリッシャでメッセージがパブリッシュされると、サブネット B および C にあるマルチキャスト サブスクライバでメッセージが受信されます。

 

back to top previous page next page