5 基本的なJMSアプリケーションの開発
必要なパッケージのインポート
WebLogicアプリケーションのメッセージの作成、送信、受信および読取りのために必要なすべてのクラスとインタフェースを定義する、Javaパッケージをインポートします。
表5-1に、WebLogic JMSアプリケーションで一般に使用されるパッケージを示します。
表5-1 WebLogic JMSパッケージ
パッケージ名 | 説明 |
---|---|
|
JMS API。このパッケージは常にWebLogic JMSアプリケーションで使用されます。 |
|
サーバーおよび宛先ルックアップに必要なJNDIパッケージ。 |
|
JTAユーザー・トランザクション・サポートに必要なJTA API。 |
追加のクラスとメソッドを提供するWebLogic固有のJMSパブリックAPI (「JMSパブリックAPIの付加価値拡張機能」を参照)。 |
JMSアプリケーションの設定
メッセージを送受信するには、あらかじめJMSアプリケーションを設定しておく必要があります。
次の各項で、基本的なWebLogic JMSアプリケーションを設定する手順を説明します。
WebLogic Serverの構成を担当するシステム管理者が必要なJMSリソース(接続ファクトリ、JMSサーバー、宛先など)を構成したことを確認してください。
-
JMSリソースの定義については、Oracle WebLogic Server JMSリソースの管理の基本JMSシステム・リソースの構成に関する項を参照してください。
-
他のJMSリソースの構成の詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのメッセージングの構成に関する項を参照してください。
-
これらの項に記述されているJMSクラスとメソッドの詳細は、「JMS APIの理解」または
javax.jms
(https://javaee.github.io/javaee-spec/javadocs/javax/jms/package-summary.html
)、またはOracle WebLogic Server Java APIリファレンスにあるweblogic.jms.extensionsのJavadocを参照してください。 -
トランザクション・アプリケーションおよびJTAユーザー・トランザクションの設定については、「WebLogic JMSによるトランザクションの使い方」を参照してください。
簡略化APIを使用したJMSアプリケーションの設定
Oracle WebLogic Server 12.2.1は、メッセージの送受信で、JMS 2.0簡略化APIをサポートします。簡略化APIの詳細は「簡略化APIプログラミング・モデルの理解」を参照してください。
図5-1は、JMS 2.0簡略化APIを使用してJMSアプリケーションを設定するのに必要なステップを示しています。
JNDIでの接続ファクトリのルックアップ
接続ファクトリをルックアップするには、あらかじめ接続ファクトリを構成情報の一部として定義しておく必要があります。
管理者は構成時に新しい接続ファクトリを構成できますが、これらのファクトリには一意の名前を付ける必要があります。そうしないとサーバーが起動しません。Java EE仕様およびWebLogic Serverによって定義されたデフォルト接続ファクトリも使用できます。詳細は、Oracle WebLogic Server JMSリソースの管理の接続ファクトリ構成に関する項を参照してください。
接続ファクトリの定義後にそれをルックアップするには、InitialContext()
コンストラクタ(https://docs.oracle.com/javase/8/docs/api/javax/naming/InitialContext.html()
)を使用してJNDIコンテキスト(namingContext
)を確立します。サーブレット・アプリケーション以外のあらゆるアプリケーションでは、InitialContext
コンストラクタをコールするときに、環境を定義するHashtable
を提供する必要があります。
JNDIコンテキストが定義された場合、JNDIで接続ファクトリをルックアップするには、次のコマンドを実行します。
ConnectionFactory connectionFactory = (ConnectionFactory) namingContext.lookup(CF_name);
CF_name
引数には、構成時に定義した接続ファクトリ名を指定します。
ConnectionFactory
クラスの詳細は、「ConnectionFactory」またはjavax.jms.ConnectionFactory
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/ConnectionFactory.html)を参照してください。
キューまたはトピックのルックアップ
キューまたはトピックをルックアップするには、それがWebLogic JMSシステム管理者によって事前に構成されている必要があります(Oracle WebLogic Server管理コンソール・オンライン・ヘルプのトピックの構成に関する項およびキューの構成に関する項を参照)。詳細は、「宛先」またはJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/Queue.html
および https://javaee.github.io/javaee-spec/javadocs/javax/jms/Topic.html
)を参照してください。
宛先の構成後に、次のいずれかの手順を実行してキューまたはトピックの宛先をルックアップできます。
JNDIコンテキスト(namingContext
)を確立し(「JNDIで接続ファクトリをルックアップする」で実行済)、次のコマンド(ポイント・ツー・ポイントまたはパブリッシュ/サブスクライブ・メッセージング用)のいずれかを実行することによって、キューまたはトピック宛先をルックアップできます。
Queue queue = (Queue) namingContext.lookup(Queue_name); Topic topic = (Topic) namingContext.lookup(Topic_name);
Queue_name
およびTopic_name
引数は、構成時に定義されたキューおよびトピック宛先のJNDI名を指定します。
JMSContextオブジェクトの作成
JMSContext
オブジェクトは、クラシックAPIのConnection
およびSession
オブジェクトを置き換えます。詳細は、「簡略化JMS APIの新しいインタフェース」を参照してください。
JMSContextオブジェクトは、ConnectionFactory
オブジェクト上で、いくつかのcreateContext
メソッドのいずれかをコールすることによって作成できます。たとえば:
JMSContext context = connectionFactory.createContext(sessionMode);
この場合、新しいJMSContext
オブジェクトcontext
が使用するために、指定されたモードでの接続およびセッションが作成されます。詳細は、connectionFactory
インタフェースの定義をhttps://javaee.github.io/javaee-spec/javadocs/javax/jms/ConnectionFactory.html
で参照してください。
別の方法として、「@Injectアノテーションを使用したJMSContextオブジェクトの宣言」で説明している@Inject
アノテーションを使用して、Java EEのWebおよびEJBコンテナにJMSContext
をインジェクトできます。これは、Java EEアプリケーションでJMSContext
を作成する場合の推奨される方法です。たとえば:
@Inject @JMSConnectionFactory("myJMSCF") JMSContext context;
JMSContext
インタフェースの使用方法の詳細は、https://javaee.github.io/javaee-spec/javadocs/javax/jms/JMSContext.htmlを参照してください。
JMSProducerおよびJMSConsumerオブジェクトの作成
メッセージを送信または受信するには、それぞれJMSProducerおよびJMSConsumerオブジェクトを使用します。
次のようにJMSContext
オブジェクト上でcreateProducer
メソッドをコールすることによって、JMSProducer
オブジェクトを作成できます。
JMSProducer producer = context.createProducer();
ノート:
JMSProducer
オブジェクトを変数に保存する必要はありません。そのかわり、次のように、send
メソッドのコール時にオブジェクトを作成します。
context.createProducer().send(queue, message);
詳細は、https://javaee.github.io/javaee-spec/javadocs/javax/jms/JMSProducer.html
を参照してください。
次のようにして、JMSContext
オブジェクト上でcreateConsumer
メソッドの1つにQueueまたはTopicオブジェクトを渡すことによって、JMSConsumer
オブジェクトを作成できます。
JMSContext context = connectionFactory.createContext(); JMSConsumer consumer = context.createConsumer(queue);
詳細は、https://javaee.github.io/javaee-spec/javadocs/javax/jms/JMSConsumer.html
を参照してください。
クラシックAPIを使用したJMSアプリケーションの設定
次の図は、JMS 1.1クラシックAPIを使用してJMSアプリケーションを設定するのに必要なステップを示しています。
ノート:
Oracle WebLogic Server 12.2.1は、メッセージの送受信で、JMS 2.0簡略化APIをサポートします。「簡略化APIプログラミング・モデルの理解」を参照してください。
ステップ1: JNDIで接続ファクトリをルックアップする
接続ファクトリをルックアップするには、あらかじめ接続ファクトリを構成情報の一部として定義しておく必要があります。
管理者は構成時に新しい接続ファクトリを構成できますが、これらのファクトリには一意の名前を付ける必要があります。そうしないとサーバーが起動しません。Java EE仕様およびWebLogic Serverによって定義されたデフォルト接続ファクトリも使用できます。詳細は、『Oracle WebLogic Server JMSリソースの管理』の接続ファクトリ構成に関する項を参照してください。
接続ファクトリの定義後に、その接続ファクトリをルックアップするには、InitialContext()
メソッド(http://docs.oracle.com/javase/8/docs/api/javax/naming/InitialContext.html#InitialContext()
)を使用してJNDIコンテキスト(context
)を確立します。サーブレット・アプリケーション以外のアプリケーションの場合は、初期コンテキストの作成に使用する環境を渡す必要があります。
コンテキストの定義後に、JNDIで接続ファクトリをルックアップするには、PTPまたはパブリッシュ/サブスクライブ・メッセージングにそれぞれ次のコマンドのいずれかを実行します。
QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory) context.lookup(CF_name); TopicConnectionFactory topicConnectionFactory = (TopicConnectionFactory) context.lookup(CF_name);
CF_name
引数には、構成時に定義した接続ファクトリ名を指定します。
ConnectionFactory
クラスの詳細は、「ConnectionFactory」またはjavax.jms.ConnectionFactory
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/ConnectionFactory.html
)を参照してください。
ステップ2: 接続ファクトリを使用して接続を作成する
メッセージング・システムにアクセスするための接続を作成するには、次節で説明するConnectionFactory
メソッドを使用します。
Connection
クラスの詳細は、「Connection」またはjavax.jms.Connection
のJavadoc (http://docs.oracle.com/javaee/7/api/javax/jms/Connection.html
)を参照してください。
キュー接続の作成
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 (https://javaee.github.io/javaee-spec/javadocs/javax/jms/ConnectionFactory.html
)を参照してください。QueueConnection
クラスの詳細は、javax.jms.QueueConnection
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/QueueConnection.html
)を参照してください。
トピック接続の作成
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 (https://javaee.github.io/javaee-spec/javadocs/javax/jms/TopicConnectionFactory.html
)を参照してください。TopicConnection
クラスの詳細は、javax.jms.TopicConnection
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/TopicConnection.html
)を参照してください。
ステップ3: 接続を使用してセッションを作成する
キューまたはトピックにアクセスするために1つまたは複数のセッションを作成するには、以降の節で説明するConnection
メソッドを使用します。
ノート:
セッションおよびそのメッセージのプロデューサとコンシューマには、一度に1つのスレッドしかアクセスできません。それらに複数のスレッドが同時にアクセスした場合、それらの動作は不明確になります。
WebLogic JMSでは、単一のセッションでQueueConsumer型とTopicSubscriber型のMessageConsumerを一緒に使用することはできません。ただし、単一のセッションでQueueSender型とTopicSubscriber型(またはQueueConsumer型とTopicPublisher型)を1つずつ使用することは可能です。また、MessageProducerは型に関係なく複数使用できます。
Session
クラスの詳細は、「Session」またはjavax.jms.Session
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/Session.html
)を参照してください。
createSessionメソッドを使用したセッションの作成
javax.jms.Connection
で、createSession
メソッドを使用して、セッションを作成します。このメソッドは、次のように、単一のパラメータsessionMode
を受け入れるか、パラメータを使用しません。
Session createSession(int sessionMode) throws JMSException or Session createSession() throws JMSException
キュー・セッションの作成
QueueConnection
クラスは、キュー・セッション作成用のメソッドを次のとおり定義します。
public QueueSession createQueueSession( boolean transacted, int acknowledgeMode ) throws JMSException
このメソッドでは、セッションをトランザクション処理するか(true
)、またはトランザクション処理しないか(false
)を示すブール引数と、非トランザクション・セッションの確認応答モードを示す整数値を指定する必要があります。トランザクション・セッションの場合、acknowledgeMode
属性は無視されます。この場合、メッセージはcommit()
メソッドでトランザクションがコミットされたときに確認応答されます。
QueueConnection
クラスのメソッドの詳細は、javax.jms.QueueConnection
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/QueueConnection.html
)を参照してください。QueueSession
クラスの詳細は、javax.jms.QueueSession
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/QueueSession.html
)を参照してください。
トピック・セッションの作成
TopicConnection
クラスは、トピック・セッション作成用のメソッドを次のとおり定義します。
public TopicSession createTopicSession( boolean transacted, int acknowledgeMode ) throws JMSException
このメソッドでは、セッションをトランザクション処理するか(true
)、またはトランザクション処理しないか(false
)を示すブール引数と、非トランザクション・セッションの確認応答モードを示す整数値を指定する必要があります。トランザクション・セッションの場合、acknowledgeMode
属性は無視されます。この場合、メッセージはcommit()
メソッドでトランザクションがコミットされたときに確認応答されます。
TopicConnection
クラスのメソッドの詳細は、javax.jms.TopicConnection
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/TopicConnection.html
)を参照してください。TopicSession
クラスの詳細は、javax.jms.TopicSession
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/TopicSession.html
)を参照してください。
ステップ4: 宛先(キューまたはトピック)をルックアップする
宛先をルックアップするには、宛先がWebLogic JMSシステム管理者によって事前に構成されている必要があります(Oracle WebLogic Server管理コンソール・オンライン・ヘルプのトピックの構成に関する項およびキューの構成に関する項を参照)。Destination
クラスの詳細は、「宛先」またはjavax.jms.Destination
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/Destination.html
)を参照してください。
宛先の構成後に、JNDI名または参照を使用して宛先をルックアップできます。
JNDI名の使用
JNDIコンテキスト(context
)を確立し(「JNDIで接続ファクトリをルックアップする」で実行済)、次のコマンド(PTPまたはパブリッシュ/サブスクライブ・メッセージング用)のいずれかを実行することによって、宛先をルックアップできます。
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
JNDI名の構文、createQueue()、およびcreateTopic()については、「宛先のルックアップ方法」を参照してください
ステップ5: メッセージ・プロデューサとメッセージ・コンシューマを作成する
メッセージ・プロデューサとメッセージ・コンシューマを作成するには、次節で説明するSession
メソッドに宛先の参照を渡します。
ノート:
各コンシューマはメッセージの独自のローカル・コピーを受信します。メッセージの受信後、ヘッダー・フィールド値を変更することはできますが、メッセージ・プロパティとメッセージ本文は読取り専用です。(この時点でメッセージ・プロパティまたは本文を変更しようとすると、MessageNotWriteableException
が発生します。)メッセージ本文を変更するには、対応するメッセージ・タイプのclearbody()
メソッドを実行して、既存の内容を消去し、書込み権限を有効にします。
MessageProducer
クラスとMessageConsumer
クラスの詳細は、「MessageProducerとMessageConsumer」またはjavax.jms.MessageProducer
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/MessageProducer.html
)およびjavax.jms.MessageConsumer
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/MessageConsumer.html
)を参照してください。
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 (https://javaee.github.io/javaee-spec/javadocs/javax/jms/QueueSession.html
)を参照してください。QueueSender
クラスとQueueReceiver
クラスの詳細は、javax.jms.QueueSender
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/QueueSender.html
)およびjavax.jms.QueueReceiver
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/QueueReceiver.html
)を参照してください。
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
メソッドまたはTopicSubscriber
メソッドを使用して、そのトピック・パブリッシャまたはサブスクライバに関連付けられているトピック名にアクセスできます。
Topic getTopic( ) throws JMSException
また、次のTopicSubscriber
メソッドを使用すると、トピック・サブスクライバに関連付けられるnoLocal
変数の設定値にアクセスできます。
boolean getNoLocal( ) throws JMSException
TopicSession
クラスのメソッドの詳細は、javax.jms.TopicSession
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/TopicSession.html
)を参照してください。TopicPublisher
クラスとTopicSubscriber
クラスの詳細は、javax.jms.TopicPublisher
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/TopicPublisher.html
)およびjavax.jms.TopicSubscriber
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/TopicSubscriber.html
)を参照してください。
ステップ6a: メッセージ・オブジェクトを作成する(メッセージ・プロデューサ)
ノート:
このステップは、メッセージ・プロデューサだけに適用されます。
メッセージ・オブジェクトを作成するには、以下の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
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/Session.html
)およびweblogic.jms.extensions.WLSession
のJavadocを参照してください。Message
クラスとそのメソッドの詳細は、「Message」またはjavax.jms.Message
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/Message.html
)を参照してください。
ステップ6b: 非同期メッセージ・リスナーを登録する(オプション)
ノート:
このステップは、メッセージ・コンシューマだけに適用されます。
メッセージを非同期的に受信するには、次のステップで非同期メッセージ・リスナーを登録する必要があります。
メッセージ・リスナーの設定を解除するには、null値を指定してMessageListener()
メソッドを呼び出します。
メッセージ・リスナーを定義したら、次のMessageConsumer
メソッドを呼び出してそのリスナーにアクセスできます。
public MessageListener getMessageListener( ) throws JMSException
ノート:
WebLogic JMSは、同じセッションの複数のonMessage()
呼出しが同時に実行されないことを保証します。
メッセージ・コンシューマが管理者またはサーバー障害によってクローズされた場合、ConsumerClosedException
がセッション例外リスナーに送信されます(定義済の場合)。このように、必要な場合は新しいメッセージ・コンシューマを作成できます。セッション例外リスナーの定義については、「セッション例外リスナーの定義」を参照してください
MessageConsumer
クラスのメソッドは、QueueReceiver
およびTopicSubscriber
クラスによって継承されます。MessageConsumer
クラスのメソッドの詳細は、「MessageProducerとMessageConsumer」またはjavax.jms.MessageConsumer
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/MessageConsumer.html
)を参照してください。
ステップ7: 接続を開始する
接続を開始するには、Connection
クラスのstart()
メソッドを使用します。
接続の開始、停止およびクローズの詳細は、「接続の開始、停止、クローズ」またはjavax.jms.Connection
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/Connection.html
)を参照してください。
例: クラシックAPIを使用したポイント・ツー・ポイントJMSアプリケーションの設定
次の例は、EXAMPLES_HOME
\wlserver\samples\server\examples\src\examples\jms\classicapi\queue
ディレクトリにあるWebLogic Server付属のexamples.jms.queue.QueueSend
例からの抜粋です。EXAMPLES_HOME
は、WebLogic Serverのサンプル・コードが構成されるディレクトリを表します。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); }
ノート:
EJBまたはサーブレットの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 { // If it is not a TextMessage... msgText = msg.toString(); } System.out.println("Message Received: "+ msgText ); if (msgText.equalsIgnoreCase("quit")) { synchronized(this) { quit = true; this.notifyAll(); // Notify main thread to quit } } } catch (JMSException jmse) { jmse.printStackTrace(); } }
onMessage()
メソッドは、キュー・レシーバを通して受信したメッセージを処理します。このメソッドは、メッセージがTextMessage
であるかどうかを検証し、そうである場合は、そのメッセージのテキストを印刷します。onMessage()
メソッドが別のタイプのメッセージを受信した場合、そのメッセージのtoString()
メソッドを使用してメッセージの内容を表示します。
ノート:
受信したメッセージのタイプが、メッセージ・ハンドラ・メソッドが予期したタイプであるかどうかを検証するようにしてください。
この例で使用されているJMSクラスの詳細は、「JMS APIの理解」またはjavax.jms
のJavadoc (http://www.oracle.com/technetwork/java/jms/index.html)を参照してください。
例: クラシックAPIを使用したパブリッシュ/サブスクライブJMSアプリケーションの設定
次の例は、EXAMPLES_HOME
\wlserver\samples\server\examples\src\examples\jms\classicapi\topic
ディレクトリにあるWebLogic Server付属のexamples.jms.topic.TopicSend
例からの抜粋です。EXAMPLES_HOME
は、WebLogic Serverのサンプル・コードが構成されるディレクトリを表します。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()
メソッドに渡されます。TopicReceive
の例のonMessage()
インタフェースは、QueueReceive
onMessage()
インタフェース(「例: クラシックAPIを使用したポイント・ツー・ポイントJMSアプリケーションの設定」を参照)と同じです。
この例で使用されているJMSクラスの詳細は、「JMS APIの理解」またはjavax.jms
のJavadoc (http://www.oracle.com/technetwork/java/jms/index.html
)を参照してください。
メッセージの送信
メッセージを送信するには、簡略化APIまたはクラシックAPIのいずれかを使用します。
「JMSアプリケーションの設定」での説明に従ってJMSアプリケーションを設定した後、メッセージの送信を開始できます。
簡略化JMS APIを使用したメッセージの送信
簡略化APIでは、メッセージは、JMSContext
の代役となるJMSProducer
オブジェクトを作成することによって送信されます。詳細は、「JMSProducerおよびJMSConsumerオブジェクトの作成」を参照してください。
指定された宛先にメッセージを送信するには、クラシックAPIにおけるMessageProducer
のsend
メソッドに対比できる、次のJMSProducer
メソッドを使用できます。
JMSProducer send(Destination destination, Message message)
たとえば、
context.createProducer().send(destination,"Hello");
このコードは、TextMessage
オブジェクトを作成し、その本文を「Hello」と設定し、続いてそれを、指定されたdestination
に送信します。
次のJMSProducer
メソッドも使用できます。これは適切なメッセージ・タイプのメッセージを自動的に作成し、ペイロードを、指定されたパラメータに設定します。
JMSProducer send(Destination destination,byte[] body) JMSProducer send(Destination destination, Map<String,Object> body) JMSProducer send(Destination destination, Serializable body) JMSProducer send(Destination destination, String body)
JMSProducer
インタフェースおよびsend
メソッドの詳細は、次の場所にあるJavadocを参照してください。
https://javaee.github.io/javaee-spec/javadocs/javax/jms/JMSProducer.html
WebLogic JMSには、メッセージ送信時に使用できる独自の属性があります。weblogic.jms.extensions.WLJMSProducer
にJMSProducer
インスタンスをキャストすることによって、配信モード(DeliveryMode.PERSISTENT
またはDeliveryMode.NON_PERSISTENT
)、優先度(0-9
)、配信遅延および存続時間(ミリ秒単位)を指定することもできます。Oracle WebLogic Server Java APIリファレンスにあるWLSJMSProducer
のJavadocを参照してください。
たとえば、
context.createProducer().setDeliveryMode(DeliveryMode.NON_PERSISTENT).send(destination,message);
指定しない場合、配信モード、優先度、および存続時間の各属性は以下のいずれかに設定されます。
-
プロデューサに対して定義された接続ファクトリまたは宛先オーバーライド構成属性(Oracle WebLogic Server管理コンソール・オンライン・ヘルプのデフォルトの配信パラメータの構成に関する項を参照)。
-
JMSProducerオブジェクトのsetメソッドを使用して指定された値(「JMSProducerおよびMessageProducer属性の設定」を参照)。
クラシックJMS APIを使用したメッセージの送信
「クラシックAPIを使用したJMSアプリケーションの設定」の説明に従ってJMSアプリケーションを設定すると、メッセージを送信できるようになります。メッセージを送信するには、以下の節で説明するステップを順番どおりに実行する必要があります。
メッセージの送信に使用するJMSクラスとメッセージ・タイプの詳細は、javax.jms.Message
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/Message.html
)を参照してください。メッセージの受信については、「メッセージの受信」を参照してください
メッセージ・オブジェクトを作成する
この手順は、「ステップ6a: メッセージ・オブジェクトを作成する(メッセージ・プロデューサ)」で説明したように、クライアント設定手順の一部としてすでに完了しています。
メッセージを定義する
このステップは、「ステップ6a: メッセージ・オブジェクトを作成する(メッセージ・プロデューサ)」で説明したように、アプリケーションの設定時に完了している場合もあります。このステップが完了しているかどうかは、メッセージ・オブジェクトを作成するために呼び出されたメソッドによって決まります。たとえば、TextMessageタイプとObjectMessageタイプの場合は、メッセージ・オブジェクトを作成するときにオプションでメッセージを定義することができます。
すでに値が指定されており、それを変更しない場合は、そのままステップ3に進みます。
値が指定されている場合、または既存の値を変更する場合は、適切なset
メソッドを使用して値を定義できます。たとえば、TextMessage
のテキストを定義するメソッドは次のとおりです。
public void setText( String string ) throws JMSException
ノート:
メッセージはnullとして定義することができます。
それ以後は、次のメソッドを使用してメッセージをクリアできます。
public void clearBody( ) throws JMSException
メッセージの定義に使用するメソッドの詳細は、javax.jms.Session
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/Session.html
)を参照してください。
MessageProducerを使用してメッセージを宛先に送信する
Destination
オブジェクトとMessageProducer
オブジェクトは、「クラシックAPIを使用したJMSアプリケーションの設定」で説明したとおり、アプリケーションの設定時に作成されています
ノート:
複数のトピック・サブスクライバが同じトピックに対して定義されている場合、各サブスクライバはメッセージの独自のローカル・コピーを受信します。メッセージの受信後、ヘッダー・フィールド値を変更することはできますが、メッセージ・プロパティとメッセージ本文は読取り専用です。メッセージ本文を変更するには、対応するメッセージ・タイプのclearbody()
メソッドを実行して、既存の内容を消去し、書込み権限を有効にします。
MessageProducer
クラスの詳細は、「MessageProducerとMessageConsumer」またはjavax.jms.MessageProducer
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/MessageProducer.html
)を参照してください。
メッセージを指定する必要があります。また、キュー名(匿名メッセージ・プロデューサ用)、配信モード(DeliveryMode.PERSISTENT
またはDeliveryMode.NON_PERSISTENT
)、優先度(0-9
)、配信遅延および存続時間(ミリ秒単位)も指定できます。指定しない場合、配信モード、優先度、および存続時間の各属性は以下のいずれかに設定されます。
-
プロデューサに対して定義された接続ファクトリまたは宛先オーバーライド構成属性(Oracle WebLogic Server管理コンソール・オンライン・ヘルプのデフォルトの配信パラメータの構成に関する項を参照)。
-
メッセージ・プロデューサのsetメソッドを使用して指定された値(「JMSProducerおよびMessageProducer属性の設定」を参照)。
配信モードをPERSISTENT
として定義した場合、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの永続ストアの構成に関する項で説明しているように、宛先のバッキング・ストアを構成する必要があります。
ノート:
バッキング・ストアが構成されていない場合、配信モードはNON_PERSISTENT
に変更され、メッセージは永続ストアに書き込まれません。
QueueSender
およびTopicPublisher
メソッドを使用したメッセージ送信の詳細は、次のWebLogic Serverドキュメントを参照してください。
https://docs.oracle.com/middleware/1213/wls/JMSPG/implement.htm#JMSPG228
QueueSender
クラスのメソッドの詳細は、javax.jms.QueueSender
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/QueueSender.html
)を参照してください。
TopicPublisher
クラスのメソッドの詳細は、javax.jms.TopicPublisher
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/TopicPublisher.html
)を参照してください。
メッセージの非同期送信
非同期モードでは、JMSクライアントは、メッセージを送信したら、JMSサーバーからの確認応答を待機せずに、アプリケーションに制御を戻します。
メッセージを非同期送信するには、アプリケーションでCompletionListener
オブジェクトを定義する必要があります。メッセージを受信したことを示す確認応答をJMSサーバーから受信すると、JMSプロバイダは、アプリケーションで定義されたCompletionListener
オブジェクト上のコールバック・メソッドonCompletion
を呼び出して、アプリケーションに通知します。CompletionListener
インタフェースの詳細は、https://javaee.github.io/javaee-spec/javadocs/javax/jms/CompletionListener.html
を参照してください。
javax.jms.CompletionListener
オブジェクトを定義したら、次のようにして、JMSProducer
またはMessageProducer
オブジェクトを使用してメッセージを非同期送信します。
-
JMSProducer
オブジェクトを使用してメッセージを送信する場合、JMSProducer
オブジェクト上で、NULLでないCompletionListener
を指定してメソッドsetAsync(CompletionListener listener)
をコールしてから、send
メソッドをコールします(次の例を参照)。// send a message asynchronously try (JMSContext context = connectionFactory.createContext()) { MyCompletionListener myCompletionListener = new MyCompletionListener(); //call normal send method context.createProducer().setAsync(myCompletionListener).send(queue, "Hello world"); ... }
詳細は、「簡略化JMS APIを使用したメッセージ送信」を参照してください。
-
MessageProducer
を使用してメッセージを送信する場合は、次のメソッドを使用してメッセージを非同期送信します。messageProducer.send(message,completionListener);
詳細は、「クラシックJMS APIを使用したメッセージ送信」を参照してください。
JMSProducerおよびMessageProducer属性の設定
前項で説明したように、メッセージを送信するときには、配信モード、優先度、配信遅延および存続時間をオプションで指定できます。指定しない場合、これらの属性には接続ファクトリの構成属性の値が設定されます。詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリの構成に関する項を参照してください。
かわりに、メッセージ・プロデューサのsetメソッドを使用して、配信モード、優先度、配信時間、存続時間、再配信遅延(タイムアウト)、および再配信制限の各属性値を動的に設定できます。表5-2に、メッセージ・プロデューサのsetメソッドとgetメソッドを、動的構成可能な属性ごとに示します。
ノート:
配信モード、優先度、存続時間、配信時間、再配信遅延(タイムアウト)、および再配信制限の各属性値は、「配信モードのオーバーライド」、「優先度のオーバーライド」、「存続時間のオーバーライド」、「配信時間のオーバーライド」、「再配信遅延のオーバーライド」、および「再配信の制限」の各構成属性を使用して宛先によってオーバーライドできます。詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのメッセージ配信のオーバーライドの構成に関する項およびトピック・メッセージ配信のオーバーライドの構成に関する項を参照してください。
表5-2 メッセージ・プロデューサのsetメソッドおよびgetメソッド
属性 | setメソッド | getメソッド |
---|---|---|
配信モード |
|
|
優先度 |
|
|
存続時間 |
|
|
再配信制限 |
|
|
送信タイムアウト |
|
|
ノート:
JMSでは、メッセージIDとタイムスタンプ情報を無効にするためのMessageProducer
メソッドを定義することもできます。ただし、これらのメソッドはWebLogic JMSでは無視されます。
MessageProducer
クラスのメソッドの詳細は、javax.jms.MessageProducer
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/MessageProducer.html
)またはweblogic.jms.extensions.WLMessageProducer
のJavadocを参照してください。
例: ポイント・ツー・ポイント・アプリケーション内でのメッセージの送信
次の例は、EXAMPLES_HOME
\wl_server\examples\src\examples\jms\queue
ディレクトリにあるWebLogic Server付属のexamples.jms.queue.QueueSend
例からの抜粋です。EXAMPLES_HOME
は、WebLogic Serverのサンプル・コードが構成されるディレクトリを表します。この例では、TextMessage
を作成し、メッセージのテキストを設定してキューに送信するために必要なコードを示してあります。
msg = qsession.createTextMessage(); . . . public void send( String message ) throws JMSException { msg.setText(message); qsender.send(msg); }
QueueSender
クラスとメソッドの詳細は、javax.jms.QueueSender
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/QueueSender.html
)を参照してください。
例: パブリッシュ/サブスクライブ・アプリケーション内でのメッセージの送信
次の例は、EXAMPLES_HOME
\wl_server\examples\src\examples\jms\topic
ディレクトリにあるWebLogic Server付属のexamples.jms.topic.TopicSend
例からの抜粋です。EXAMPLES_HOME
は、WebLogic Serverのサンプル・コードが構成されるディレクトリを表します。この例では、TextMessage
を作成し、メッセージのテキストを設定してトピックに送信するために必要なコードを示してあります。
msg = tsession.createTextMessage(); . . . public void send( String message ) throws JMSException { msg.setText(message); tpublisher.publish(msg); }
TopicPublisher
クラスとメソッドの詳細は、javax.jms.TopicPublisher
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/TopicPublisher.html
)を参照してください。
メッセージの受信
JMSConsumer
およびMessageConsumer
メソッドを使用してメッセージを受信する方法を学習します。
「JMSアプリケーションの設定」の説明に従ってJMSアプリケーションを設定すると、メッセージを受信できるようになります。
メッセージを受信するには、レシーバ・オブジェクトを作成し、メッセージを同期受信するか非同期受信するかを指定する必要があります。
メッセージを受信する順序は、以下の要素によって設定できます。
-
構成時または
send()
メソッドの一部として定義するメッセージ配信属性(配信モードとソート条件)。詳細については、「メッセージの送信」を参照してください -
宛先キーを使用して設定される宛先ソート順序。詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの宛先キーの構成に関する項を参照してください。
メッセージの受信後、ヘッダー・フィールド値を変更することはできますが、メッセージ・プロパティとメッセージ本文は読取り専用です。メッセージ本文を変更するには、対応するメッセージ・タイプのclearbody()
メソッドを実行して、既存の内容を消去し、書込み権限を有効にします。
メッセージの受信に使用するJMSクラスとメッセージ・タイプの詳細は、javax.jms.Message
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/Message.html
)を参照してください。メッセージの送信については、「メッセージの送信」を参照してください
簡略化APIを使用したメッセージの非同期受信
てメッセージを受信するには、まず、JMSContext
オブジェクト上で、いくつかのcreateConsumer
またはcreateDurableConsumer
メソッドの1つを使用してJMSConsumer
オブジェクトを作成する必要があります。
JMSConsumer
オブジェクトを作成し、メソッドsetMessageListener
を使用して、MessageListener
インタフェースを実装するオブジェクトを指定します。メッセージ配信が自動的に開始されます。
JMSConsumer consumer = context.createConsumer(queue); consumer.setMessageListener(messageListener);
クラシックAPIを使用したメッセージの非同期受信
クラシックAPIを使用したメッセージの非同期受信は、アプリケーションの設定コンテキスト内に記載されています。詳細は、「ステップ6b: 非同期メッセージ・リスナーを登録する(オプション)」を参照してください
ノート:
接続ファクトリの構成時に「セッションあたりの最大メッセージ数」属性を設定すると、非同期コンシューマに存在し、メッセージ・リスナーにまだ渡されていないメッセージの最大数を指定できます。
非同期メッセージ・パイプライン
メッセージの生成速度が非同期メッセージ・リスナー(コンシューマ)によるそれらの消費速度を上回る場合、JMSサーバーは複数の未消費メッセージをまとめ、別の使用可能な非同期メッセージ・リスナーのセッションに送ります。こうした処理中のメッセージはメッセージ・パイプラインと呼ばれ、JMSベンダーによってはメッセージ・バックログとも呼ばれます。パイプラインまたはバックログのサイズは、非同期コンシューマで蓄積され、メッセージ・リスナーに渡されていないメッセージの数です。
メッセージ・パイプラインの構成
クライアントの最大パイプライン・サイズを設定するには、クライアントの接続ファクトリのセッションあたりの最大メッセージ数属性を構成します。この属性は、非同期コンシューマに存在し、メッセージ・リスナーにまだ渡されていないメッセージの最大数です。デフォルト値は10です。JMS接続ファクトリの構成の詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリの構成に関する項を参照してください。
パイプライン・メッセージの動作
構成されたメッセージ・パイプラインは、次のように動作します。
-
統計 — JMSモニター統計では、メッセージ・パイプラインのバックログ・メッセージは、コミットまたは確認応答されるまで保留中(キューおよび恒久サブスクライバに対して)として報告されます。
-
パフォーマンス — 「セッションあたりの最大メッセージ数」パイプライン・サイズを増やすと、高スループット・アプリケーションのパフォーマンスが向上する場合があります。パイプライン・サイズを増やすと、クライアントのメモリー使用率が高くなります。これは、非同期コンシューマのリスナーが呼び出されるまで保留中のパイプライン・メッセージがクライアントJVMに蓄積されるからです。
-
ソート — 非同期コンシューマのパイプライン内のメッセージは、コンシューマ宛先の構成済みソート順序に従ってソートされず、JMSサーバーから送信された順序を保持します。たとえば、宛先のソート順序が優先度である場合でも、優先度が最も高いメッセージが、非同期コンシューマのパイプラインにすでに送信されている優先度の低いメッセージの前に来ることはありません。
ノート:
接続ファクトリの「セッションあたりの最大メッセージ数」パイプライン・サイズは、JMSサーバーおよび宛先の最大メッセージ割当ての設定とは関係ありません。
パイプライン内のメッセージは、ネットワーク・トランスポートで単一のメッセージに集約される場合があります。パイプライン・メッセージのサイズが大きい場合、書き込まれるデータの集約サイズが最大トランスポート値を超え、望ましくない動作が発生する場合があります。たとえば、
t3
プロトコルでは、デフォルトの最大メッセージ・サイズは10,000,000バイトに設定されており、サーバーのMaxT3MessageSize
属性で構成できます。このため、10通の2MBメッセージがパイプライン内にある場合、t3
の制限を上回る場合があります。
簡略化APIを使用したメッセージの同期受信
JMSConsumer
オブジェクト上のreceive
メソッドは、メッセージの同期配信のために使用されます。
public String receiveMessage( ConnectionFactory connectionFactory,Queue queue){ String body=null; try (JMSContext context = connectionFactory.createContext();){ JMSConsumer consumer = session.createConsumer(queue); body = consumer.receiveBody(String.class); } catch (JMSRuntimeException ex) { // handle exception } return body; }
JMSConsumer
クラスのメソッドの詳細は、javax.jms.JMSConsumer
のJavadoc (https://javaee.github.io/javaee-spec/javadocs/javax/jms/JMSConsumer.html
)を参照してください。
クラシックAPIを使用したメッセージの同期受信
メッセージを同期的に受信するには、以下の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 (https://javaee.github.io/javaee-spec/javadocs/javax/jms/MessageConsumer.html
)を参照してください。
例: PTPアプリケーション内でのメッセージの同期受信
次の例は、EXAMPLES_HOME
\wl_server\examples\src\examples\jms\queue
ディレクトリにあるWebLogic Server付属のexamples.jms.queue.QueueReceive
例からの抜粋です。EXAMPLES_HOME
は、WebLogic Serverのサンプル・コードが構成されるディレクトリを表します。メッセージ・リスナーを設定するのではなく、各メッセージに対してqreceiver.receive()
を呼び出します。たとえば:
qreceiver = qsession.createReceiver(queue); qreceiver.receive();
最初の行では、キューに対するキュー・レシーバが作成されます。2番目の行では、receive()
メソッドが実行されます。receive()
メソッドは、ブロックしてメッセージを待ちます。
例: Pub/Subアプリケーション内でのメッセージの同期受信
次の例は、EXAMPLES_HOME
\wl_server\examples\src\examples\jms\topic
ディレクトリにあるWebLogic Server付属のexamples.jms.topic.TopicReceive
例からの抜粋です。EXAMPLES_HOME
は、WebLogic Serverのサンプル・コードが構成されるディレクトリを表します。メッセージ・リスナーを設定するのではなく、各メッセージに対してtsubscriber.receive()
を呼び出します。
たとえば:
tsubscriber = tsession.createSubscriber(topic); Message msg = tsubscriber.receive(); msg.acknowledge();
最初の行では、トピックに対するトピック・サブスクライバが作成されます。2番目の行では、receive()
メソッドが実行されます。receive()
メソッドは、ブロックしてメッセージを待ちます。
プリフェッチ・モードを使用した同期メッセージ・パイプラインの作成
WebLogic Server 9.1より前のバージョンでは、同期コンシューマで各メッセージに対し双方向のネットワーク呼出しが必要でした。この方法は同期コンシューマで複数のメッセージを受け取れないので非効率的であり、また同期コンシューマで利用可能なメッセージ用にサーバーのポーリングが続けられるのでネットワーク・トラフィック・リソースが増加するおそれがありました。WebLogic 9.1以降では、WebLogic Server管理コンソールまたはJMSClientParamsBean
MBeanを介してJMS接続ファクトリの「同期コンシューマのプリフェッチ・モード」オプションを有効にすることにより、同期コンシューマでも非同期コンシューマと同じ効率的な動作を利用できるようになります。
JMSクライアントの接続ファクトリでプリフェッチ・モードが有効な場合、非同期メッセージのパイプラインのように、その接続ファクトリにターゲット指定されたJMSサーバーが未消費のメッセージのバッチを積極的に同期メッセージ・コンシューマに送信します。この際、バッチごとにプリフェッチされるメッセージの最大数を定義するために、その接続ファクトリの「セッションあたりの最大メッセージ数」パラメータが使用されます。これにより、同期コンシューマでさらにメッセージを処理する準備ができたときに、そのコンシューマに対してメッセージが用意され待機している状態になるため、パフォーマンスが向上する場合があります。さらに、コンシューマでメッセージのポーリングが続けられることがなく、コンシューマからの同期呼出し数が減るので、ネットワーク・トラフィックが減少することもあります。
同期メッセージ・プリフェッチは、同期メッセージ受信に対するユーザー(XA)トランザクションも、(キューであるかトピックであるかに関係なく)セッションごとの複数の同期コンシューマもサポートしていません。上記に該当するほとんどの場合、WebLogic JMSでは何の通知もなく「同期コンシューマのプリフェッチ・モード」フラグは無視されます。ただし、無視されない場合、アプリケーションの同期受信呼出しは失敗します。
パイプライン・メッセージの動作の詳細は、「非同期メッセージ・パイプライン」を参照してくださいJMS接続ファクトリの構成の詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリの構成に関する項を参照してください。
受信メッセージの回復
ノート:
この節の説明は、確認応答モードがCLIENT_ACKNOWLEDGE
に設定されている非トランザクション・セッションだけに適用されます。同期受信されるAUTO_ACKNOWLEDGE
メッセージは確認応答済みのため、回復されないことがあります。
アプリケーションは、次のメソッドを使用して、JMSにメッセージの再配信(未確認)をリクエストできます。
public void recover( ) throws JMSException
recover()
メソッドは、次のステップを実行します。
-
セッションのメッセージ配信を停止します。
-
確認応答されていない(ただし配信されている可能性のある)すべてのメッセージに再配信のタグを付けます。
-
そのセッションの確認応答されていない最初のメッセージからメッセージの送信を再開します。
ノート:
キュー内のメッセージは、必ずしも元の配信順序と同じ順序で、または同じキュー・コンシューマに再配信されるとは限りません。再配信メッセージの正しい配信順序の保証の詳細は、「メッセージの再配信の順序付け」を参照してください。
受信メッセージの確認応答
受信したメッセージの確認応答を行うには、acknowledge()
メソッドを使用します。このメソッドは、接続ファクトリの「確認応答ポリシー」属性の構成によって異なります。
ノート:
この節の説明は、確認応答モードがCLIENT_ACKNOWLEDGE
に設定されている非トランザクション・セッションだけに適用されます。
受信したメッセージの確認応答を行うには、次のMessage
メソッドを使用します。
public void acknowledge( ) throws JMSException
acknowledge()
メソッドは、接続ファクトリの「確認応答ポリシー」属性の構成によって次のように異なります。
-
デフォルト・ポリシーの「All」の場合、あるメッセージの確認応答が呼び出されると、セッションで受信したすべての未確認応答メッセージに対して確認応答が行われます。
-
「Previous」ポリシーの場合、あるメッセージの確認応答が呼び出されると、そのメッセージ以前の未確認応答メッセージだけに対して確認応答が行われます。確認応答が行われないメッセージは、クライアントに再配信できます。
このメソッドは、確認応答モードがCLIENT_ACKNOWLEDGE
に設定されている非トランザクション・セッションに対してだけ有効です。それ以外の場合、このメソッドは無視されます。
オブジェクト・リソースの解放
JMSアプリケーションにかわって作成した接続、セッション、メッセージ・プロデューサ/コンシューマ、接続コンシューマ、またはキュー・ブラウザを使い終えたら、それらを明示的にクローズしてリソースを解放する必要があります。
JMSオブジェクトをクローズするには、close()
メソッドを次のとおり入力します。
public void close( ) throws JMSException
オブジェクトをクローズするときには、以下の処理が行われます。
-
メソッド呼出しが完了して未処理の非同期レシーバの
onMessage()
メソッド呼出しが完了するまで、その呼出しがブロックされます。 -
関連付けられているすべてのサブ・オブジェクトもクローズされます。たとえば、セッションをクローズすると、関連付けられているすべてのメッセージ・プロデューサおよびコンシューマもクローズされます。接続をクローズすると、関連付けられているすべてのセッションもクローズされます。
各オブジェクトについてのclose()
メソッドの影響については、該当するjavax.jms
のJavadoc (http://www.oracle.com/technetwork/java/jms/index.html
)を参照してください。また、接続またはセッションのclose()
メソッドの詳細は、それぞれ「接続の開始、停止、クローズ」、「セッションのクローズ」を参照してください。
次の例は、EXAMPLES_HOME
\wl_server\examples\src\examples\jms\queue
ディレクトリにあるWebLogic Server付属のexamples.jms.queue.QueueSend
例からの抜粋です。EXAMPLES_HOME
は、WebLogic Serverのサンプル・コードが構成されているディレクトリを表します。この例では、メッセージ・コンシューマ、セッション、および接続オブジェクトをクローズするのに必要なコードを示してあります。
public void close( ) throws JMSException { qreceiver.close(); qsession.close(); qcon.close(); }
このQueueSend
の例では、main()
の最後にclose()
メソッドが呼び出され、オブジェクトのクローズとリソースの解放が行われます。