6 アプリケーションの管理
WebLogic JMSの付加価値機能を使用してJMSアプリケーションをプログラム的に管理する方法を学習します。
ロールバック/リカバリ/再配信された、または期限切れになったメッセージの管理
ロールバックまたは回復されたメッセージの管理方法を学習します。
メッセージの再配信遅延の設定
一時的または外部的な要因でアプリケーションがメッセージを正しく処理できない場合に、メッセージの再配信を遅延させることができます。これにより、アプリケーションが現在処理できない有害なメッセージの受信を一時的に抑制できます。メッセージがロールバックまたはリカバリされる場合、再配信遅延は、メッセージが止められてから再配信が試行されるまでの間隔です。
JMSでメッセージをすぐに再配信すると、エラーの原因が解決されず、アプリケーションはメッセージを処理できないままの場合があります。ただし、アプリケーションが再配信遅延用に構成されている場合、メッセージがロールバックまたはリカバリされると、メッセージは再配信の遅延が過ぎるまで止められます。遅延の期間を過ぎた時点でメッセージを再配信できるようになります。
セッションによって消費された結果、ロールバックまたはリカバリしたすべてのメッセージは、ロールバックまたはリカバリ時にそのセッションの再配信遅延を受信します。単一のユーザー・トランザクションの一部として複数のセッションで消費されたメッセージは、個々のメッセージを消費したセッションの機能として異なる再配信遅延を受信します。意識的か、または失敗の結果、クライアントによる確認応答またはコミットされていないメッセージには、再配信遅延が割り当てられません。
再配信遅延の設定
セッションは、作成時に接続ファクトリから再配信遅延を継承します。接続ファクトリのRedeliveryDelay
属性は、WebLogic Server管理コンソールで構成します。
詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリの構成に関する項を参照してください。
セッションを作成するアプリケーションは、javax.jms.Session
インタフェースに対するWebLogic固有の拡張を使用して接続ファクトリ設定をオーバーライドできます。セッション属性は動的なので、いつでも変更できます。セッションの再配信遅延を変更すると、メッセージが非恒久トピックを使用するセッション内にある場合を除いて、変更後にそのセッションで消費およびロールバック(またはリカバリ)されるすべてのメッセージに影響します。
ノート:
セッションで非恒久トピックを使用している場合、setRedeliveryDelay
メソッドは適用されません。その結果、非恒久トピック・コンシューマを使用してワークフローを駆動している場合に予期しない動作が発生することがあります。
セッションに対して再配信遅延を設定するメソッドは、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
属性は、WebLogic Server管理コンソールで構成します。詳細は、次を参照してください。
-
Oracle WebLogic Server管理コンソール・オンライン・ヘルプのキューに関するメッセージ配信の失敗オプションの構成に関する項
-
Oracle WebLogic Server管理コンソール・オンライン・ヘルプのトピックに関するメッセージ配信の失敗オプションの構成に関する項
メッセージの再配信制限の設定
WebLogic JMSによるアプリケーションへのメッセージ再配信の試行回数に制限を設けることができます。宛先へのメッセージの再配信の失敗が指定した回数に達すると、そのメッセージ宛先に関連付けられたエラー宛先にメッセージをリダイレクトできます。再配信の制限が構成されていて、エラー宛先が構成されていない場合、永続メッセージまたは非永続メッセージは再配信の制限に達すると削除されます。
別の方法として、JMSProducerおよびMessageProducer属性の設定で説明しているように、メッセージ・プロデューサのsetメソッドを使用して動的に再配信制限値を設定できます
宛先のメッセージ再配信制限の構成
宛先によるコンシューマへのメッセージ再配信の試行が指定した再配信制限に達すると、宛先はメッセージを配信不能にします。RedeliveryLimit
属性は、宛先で設定され、WebLogic Server管理コンソールで構成できます。この設定は、メッセージのプロデューサ側で設定された再配信制限をオーバーライドします。詳細は、次を参照してください。
-
Oracle WebLogic Server管理コンソール・オンライン・ヘルプのキューに関するメッセージ配信の失敗オプションの構成に関する項。
-
Oracle WebLogic Server管理コンソール・オンライン・ヘルプのトピックに関するメッセージ配信の失敗オプションの構成に関する項。
配信されなかったメッセージに対するエラー宛先の構成
配信されなかったメッセージのエラー宛先がJMSサーバーに構成されている場合は、宛先に配信できないと判断されたメッセージが指定したエラー宛先にリダイレクトされます。エラー宛先はトピックまたはキューのいずれかですが、定義されている宛先と同じJMSサーバーに構成する必要があります。エラー宛先が構成されていない場合、配信されなかったメッセージは削除されます。
ErrorDestination
属性は、WebLogic Server管理コンソールを使用して、スタンドアロンの宛先および共通分散宛先に構成します。詳細は、次を参照してください。
-
Oracle WebLogic Server管理コンソール・オンライン・ヘルプのキューに関するメッセージ配信の失敗オプションの構成に関する項。
-
Oracle WebLogic Server管理コンソール・オンライン・ヘルプのトピックに関するメッセージ配信の失敗オプションの構成に関する項。
-
Oracle WebLogic Server管理コンソール・オンライン・ヘルプの共通分散キュー - 配信の失敗パラメータの構成に関する項。
-
Oracle WebLogic Server管理コンソール・オンライン・ヘルプの共通分散トピック - 配信の失敗パラメータの構成に関する項。
メッセージの再配信の順序付け
ノート:
再配信の順序付けを使用しているアプリケーションは、メッセージ順序単位を使用するようにアップグレードすることをお薦めします。「メッセージ順序単位の使用」を参照してください。
プロデューサからコンシューマに最初に配信されるすべてのメッセージは、作成された順序でコンシューマに届くことが保証されます。WebLogic JMSはこの要件を満たすだけでなく、さらに「メッセージの再配信の順序付け」機能を提供しています。この機能は、再配信メッセージについても正しい順序を保証します。
この保証を提供するために、WebLogic JMSでは特定の制約を課す必要があります。制約は次のとおりです。
-
単独のコンシューマ — 順序付き再配信は、単独のコンシューマが存在する場合にのみ保証されます。複数のコンシューマが存在する場合、個々のコンシューマがメッセージを受信する順序は保証されません。
ノート:
MDB (メッセージドリブンBean)については、コンシューマ数は、ある特定のMDB用にデプロイされたMDBインスタンス数の関数です。インスタンス数の初期値および最大値は1に設定する必要があります。そうでない場合、再配信メッセージに関する順序付けは保証できません。
-
ソート順序: ある特定の宛先がソートの対象でJMS宛先キーが定義されている場合、別のメッセージが生成されて、そのメッセージが順序付けの先頭に置かれると、再配信される既存メッセージと配信される受信メッセージの間で順序の保証はできません。
-
メッセージの選択: コンシューマがセレクタを使用している場合、再配信での順序付けは、再配信対象のメッセージと、そのセレクタの基準に一致する他のメッセージの間でのみ保証されます。セレクタに一致しないメッセージに関しては順序は保証されません。
-
再配信の遅延: メッセージに再配信遅延期間が設定されており、リカバリまたはロールバックされた場合、そのメッセージはその期間にわたって使用できなくなります。この期間中は、他のメッセージを(遅延メッセージの後に送信されたものであっても)先に配信できます。
-
リカバリを保留しているメッセージ: 順序付き再配信は、サーバーの障害やシステムの再起動が原因で、リカバリ状態を保留することになった再配信メッセージには適用されません。
メッセージング・ブリッジおよびMDBで必須のメッセージ・パイプライン設定
WebLogicメッセージング・ブリッジまたはMDBを使用する非同期コンシューマやJMSアプリケーションでは、メッセージ・パイプラインのサイズを1に設定する必要があります。パイプラインのサイズは、受信側アプリケーションが使用するJMS接続ファクトリの「最大メッセージ数」属性を使用して設定します。1より大きい値は、再配信メッセージの前に追加の送信中メッセージがある可能性を示します。MDBアプリケーションでは、アプリケーションに固有のJMS接続ファクトリを定義し、その接続ファクトリの「最大メッセージ数」属性の値を1に設定する必要があります。さらに、MDBアプリケーションのEJB記述子で接続ファクトリを参照する必要があります。
EJBのプログラミングの詳細は、『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』のメッセージドリブンEJBに関する項を参照してください。
メッセージ配信時間の設定
アプリケーションへのメッセージ配信を、将来の指定した時間にスケジューリングできます。
短い期間(秒や分など)の後でメッセージを配信することも、長い期間をおいた後で配信(数時間単位でバッチ処理する場合など)することもできます。その配信時間になって配信されるまでメッセージは表示されないため、将来の特定の時間に作業をスケジューリングできます。
メッセージが送信されるのは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を参照してください。
メッセージに対する配信時間の設定
DeliveryTime
は、メッセージを配信するのに最も早い絶対時間を定義できるJMSメッセージ・ヘッダーです。つまり、メッセージはメッセージング・システムによって保持され、その時間になるまでどのコンシューマにも配信されません。
DeliveryTime
は、JMSヘッダー・フィールドとして宛先でのメッセージのソート、またはメッセージの選択に使用できます。データ型変換の目的で、配信時間は長整数として保存されます。
ノート:
メッセージの配信時間の値を設定しても、このフィールドには影響しません。これは、メッセージが送信またはパブリッシュされるたびに、JMSがこの値をプロデューサの値でオーバーライドするためです。ここで説明するメッセージ配信時間の方法は、プロデューサによって設定される他のJMSメッセージ・フィールド(配信モード、優先度、配信時間、存続時間、再配信遅延、再配信制限など)と似ています。特に、これらのフィールドの設定はJMSプロバイダ(WebLogic 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
属性を設定できます。
存続時間の値との関係
指定した存続時間の値(JMSExpiration
)が指定した配信時間と同じかそれより少ない場合、メッセージの配信は成功します。ただし、メッセージは通知されずに期限切れになります。
スケジューリング済み配信時間のオーバーライドの設定
スケジューリングされたTimeToDeliverOverride
属性はweblogic.jms.extensions.Schedule
クラスを使用しても指定できます。このクラスでは、スケジュールを取得し、次回のメッセージ配信時間を返すメソッドが提供されています。
表6-1 メッセージ配信スケジュール
例 | 説明 |
---|---|
0 0 0,30 * * * * |
次の最も近い30分 |
* * 0,30 4-5 * * * |
午前4時から午前5時までの30分間のうち最初の1分間の任意の時点 |
* * * 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時 |
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
クラスで使用するのと同じ範囲です。monthValue
のjava.util.Calendar
の範囲は、1-12ではなく0-11です。
この構文を使用すると、2つの時間の間のすべての時間を示す値の範囲で各フィールドを表すことができます。たとえば、dayOfWeek
フィールドの2-6
は、月曜から金曜まで(双方の曜日を含む)を示します。また、カンマ区切りのリストで各フィールドを指定することもできます。たとえば、分フィールドの0,15,30,45
は、1時間内の15分おきの値を示します。さらに、個々の値と値の範囲の組合せで各フィールドを定義することもできます。たとえば、時フィールドの9-17,0
は、午前9時と午後5時の間と深夜12時を示します。
補足のセマンティクスは以下のとおりです。
-
セミコロン(;)で区切って複数のスケジュールが指定されている場合、次のスケジュール時間は、最も早い値を戻すスケジュールを基に決定されます。この使い方としては、曜日を基に変更されるスケジュールを指定する場合などがあります(下記の例を参照)。
-
dayOfWeek
の値1は日曜日です。 -
値*は、そのフィールドのあらゆる時間を示します。たとえば、月フィールドの*は、毎月という意味です。時フィールドの*は、毎時という意味です。
-
値
l
、つまりlast
(大文字と小文字の区別はない)は、そのフィールドで可能な値で最も大きな値を示します。 -
日に対して月の最大値を超える値を指定すると、その月の最大値が指定されます。たとえば、うるう年の2月に対して31を指定した場合、スケジューラは、29と見なしてスケジューリングします。これは、月フィールドを31に設定すると、その月の最後の日が指定されるということです。
-
ミリ秒が指定される場合、1秒内で最も近い50番目の値に丸められます。値は0、19、39、59、...、979、および999です。したがって、0 - 40は0 - 39に丸められ、50 - 999は39 - 999に丸められます。
ノート:
このクラスの静的メソッドのいずれか1つに対するメソッド・パラメータとしてCalendarが指定されない場合、使用されるカレンダは、デフォルトの
java.util.TimeZone
およびデフォルトのjava.util.Locale
があるjava.util.GregorianCalendar
です。
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 {
接続の管理
JMS接続の管理方法を学習します。
接続例外リスナーの定義
例外リスナーは、接続に問題が発生するとアプリケーションに非同期的に通知します。このメカニズムは、通知されない限り接続がメッセージの消費を待ち続ける場合に役立ちます。
ノート:
例外リスナーの目的は、接続によってスローされたすべての例外をモニターすることではなく、本来なら配信されない例外を配信することです。
接続に対する例外リスナーを定義するには、次の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メソッドを示します。
表6-2 JMSメタデータ
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 (https://javaee.github.io/javaee-spec/javadocs/javax/jms/ConnectionMetaData.html
)を参照してください。
接続の開始、停止、クローズ
メッセージのフローを制御するために、次のstart()
メソッドとstop()
メソッドをそれぞれ使用して、接続を一時的に開始および停止できます。
start()
メソッドとstop()
メソッドの詳細は以下のとおりです。
public void start() throws JMSException public void stop() throws JMSException
新しく作成された接続は停止しています。接続が開始されるまで、メッセージは受信されません。一般に、他のJMSオブジェクトは、「JMSアプリケーションの設定」で説明するとおり、接続が開始される前からメッセージを処理するよう設定されますメッセージは、停止している接続上に作成することはできますが、停止している接続に届けることはできません。
接続が開始されていれば、stop()
メソッドを使用して接続を停止できます。このメソッドは、次のステップを実行します。
-
すべてのメッセージの配信を中断します。接続が再起動されるか、そのメッセージに関連付けられている存続時間に達するまで、メッセージの受信を待っているアプリケーションは何も返しません。
-
現在メッセージを処理しているすべてのメッセージ・リスナーが完了するまで待機します。
一般に、JMSプロバイダは接続を作成するときに大量のリソースを割り当てます。接続が使用されなくなったら、その接続をクローズしてリソースを解放する必要があります。接続をクローズするには、次のメソッドを使用します。
public void close( ) throws JMSException
このメソッドは、次のステップを実行して系統的にシャットダウンを行います。
-
保留中のすべてのメッセージの受信を終了させます。アプリケーションは、クローズ時にメッセージを受信できない場合はメッセージまたはnullを戻す場合があります。
-
現在メッセージを処理しているすべてのメッセージ・リスナーが完了するまで待機します。
-
処理中のトランザクションを、そのトランザクション・セッション上でロールバックします(こうしたトランザクションが外部JTAユーザー・トランザクションの一部である場合を除く)。JTAユーザー・トランザクションの詳細は、「JTAユーザー・トランザクションの使い方」を参照してください
-
クライアントが確認応答を行うセッションの確認応答は強制しません。確認応答を強制しないことにより、キューおよび信頼性の高い処理が要求される恒久サブスクリプション用のメッセージが失われなくなります。
接続をクローズすると、関連付けられているすべてのオブジェクトがクローズされます。受信メッセージのacknowledge()
メソッドを除いて、接続で作成または受信されたメッセージ・オブジェクトは引続き使用できます。クローズされた接続をクローズしても影響はありません。
ノート:
クローズされた接続のセッションから受信したメッセージを確認応答しようとすると、IllegalStateException
がスローされます。
セッションの管理
JMSセッションの管理方法を学習します。
セッション例外リスナーの定義
例外リスナーは、セッションに問題が発生すると、クライアントに非同期的に通知します。これは、通知されない限りセッションがメッセージの消費を待ち続ける場合に役立ちます。
ノート:
例外リスナーの目的は、セッションによってスローされたすべての例外をモニターすることではなく、本来なら通知されない例外を通知することです。
セッションに対する例外リスナーを定義するには、次の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つのスレッドしか存在しないので、例外リスナーとメッセージ・リスナー(非同期メッセージ配信用に使用される)を同時に実行することはできません。そのため、問題が発生したときにメッセージ・リスナーが実行されている場合、そのメッセージ・リスナーが実行を完了するまで例外リスナーはブロックされます。メッセージ・リスナーの詳細は、「クラシックAPIを使用したメッセージの非同期受信」を参照してください
セッションのクローズ
接続と同じように、JMSプロバイダはセッションを作成するときに大量のリソースを割り当てます。セッションが使用されなくなったら、そのセッションをクローズしてリソースを解放することをお薦めします。セッションをクローズするには、次のSession
メソッドを使用します。
public void close( ) throws JMSException
ノート:
close()
メソッドは、セッション・スレッドとは別個のスレッドから呼び出すことができる唯一のSessionメソッドです。
このメソッドは、次の手順を実行して系統的にシャットダウンを行います。
-
保留中のすべてのメッセージの受信を終了させます。アプリケーションは、接続のクローズ時にメッセージを受信できない場合はメッセージまたはnullを戻す場合があります。
-
現在メッセージを処理しているすべてのメッセージ・リスナーが完了するまで待機します。
-
処理中のトランザクションをロールバックします(こうしたトランザクションが外部JTAユーザー・トランザクションの一部である場合を除く)。JTAユーザー・トランザクションの詳細は、「JTAユーザー・トランザクションの使い方」を参照してください
-
クライアントが確認応答を行うセッションの確認応答は強制しません。これにより、キューおよび信頼性の高い処理が要求される恒久サブスクリプション用のメッセージが失われなくなります。
セッションをクローズすると、関連付けられているすべてのプロデューサとコンシューマもクローズされます。
ノート:
onMessage()
メソッド呼出し内でclose()
メソッドを発行する場合、システム管理者は接続ファクトリを構成するときに「メッセージの短縮を許可」チェック・ボックスを選択しなければなりません。
宛先の管理
宛先の動的作成
宛先を動的に作成する方法については、以下のトピックを参照してください。
-
「JMSモジュール・ヘルパーを使用したアプリケーションの管理」では、
weblogic.jms.extensions.JMSModuleHelper
の使用方法について説明します。JMSモジュール・ヘルパーの詳細は、「JMSモジュール・ヘルパーを使用したアプリケーションの管理」を参照してください -
「一時的な宛先の使い方」では、アプリケーションを有効化して要件に応じた宛先を作成する方法について説明します。一時的な宛先の使用方法の詳細は、「一時的な宛先の使い方」を参照してください
宛先の動的作成に関する手順については、以降の節で説明します。
宛先の動的削除
次のいずれかの方法を使用して、JMS宛先(キューまたはトピック)を動的に削除できます。
-
JMSModuleHelperクラス(「JMSモジュール・ヘルパーを使用したアプリケーションの管理」を参照)
-
管理コンソール
-
ユーザー定義JMXアプリケーション
JMSサーバーは削除された宛先をリアル・タイムに削除します。従って、削除を有効にするためにJMSサーバーを再デプロイする必要はありません。
宛先を削除するために必要な条件
宛先の削除を正常に完了するには、次の条件が満たされている必要があります。
-
削除する宛先は分散宛先のメンバーであってはなりません。詳細は、「分散宛先の使用」を参照してください。
-
削除する宛先は他の宛先のエラー宛先であってはなりません。詳細については、「配信されなかったメッセージに対するエラー宛先の構成」を参照してください
これらの条件のいずれかが満たされていない場合、削除は実行できません。
宛先削除後の動作
宛先を削除する場合、以下の動作とセマンティクスが適用されます。
-
既存メッセージの物理的な削除: 削除した宛先のすべての恒久サブスクライバが永続的に削除されます。削除した宛先に格納されているすべてのメッセージ(永続および非永続)が、メッセージング・システムから永続的に削除されます。
-
プロデューサ、コンシューマ、およびブラウザの作成不可: 宛先の削除後に、削除した宛先のプロデューサ、コンシューマ、またはブラウザをアプリケーションで作成することはできません。作成しようとすると、宛先が存在しない場合と同様に、アプリケーションは
InvalidDestinationException
を受け取ります。 -
コンシューマのクローズ: 削除した宛先の既存のコンシューマがすべてクローズされます。コンシューマのクローズによって
ConsumerClosedException
が生成され、親セッションのExceptionListener
(存在する場合)に配信されます。この例外には「Destination was deleted」と示されます。コンシューマがクローズされた時点でコンシューマに未処理の
receive()
処理がある場合、その処理は取り消され、呼出し側はメッセージが存在しないことを示すnull
値を受け取ります。アプリケーションでclose()
以外の実行を試みると、クローズされたコンシューマのIllegalStateException
が発生します。 -
ブラウザのクローズ: 削除した宛先のブラウザがすべてクローズされます。アプリケーションで
close()
以外の実行を試みると、クローズされたブラウザのIllegalStateException
が発生します。ブラウザのクローズにより、ブラウザに関連付けられたすべての列挙値が暗黙的にクローズされます。 -
列挙値のクローズ: 削除した宛先の列挙値がすべてクローズされます。列挙値がクローズされた後の動作は、列挙値のクローズ前に実行した最後の呼出しによって異なります。
hasMoreElements()
の呼出しでtrueの値が返され、以降にnextElement()
を呼び出していない場合は、列挙により次の要素を列挙できることが保証されます。その結果、詳細が生成されます。クローズ前の最後の呼出しがhasMoreElements()
を呼び出し、返された値がtrueであった場合は、以下の動作が適用されます。-
nextElement()
の最初の呼出しではメッセージが返されます。 -
以降の
nextElement()
の呼出しではNoSuchElementException
がスローされます。 -
nextElement()
の最初の呼出し前にhasMoreElements()
を呼び出すと、trueが返されます。 -
nextElement()
の最初の呼出し後にhasMoreElements()
を呼び出すと、falseが返されます。
ある特定の列挙値が一度も呼び出されていないか、クローズ前の最後の呼出しが
nextElement()
を呼び出した場合、またはクローズ前の最後の呼出しがhasMoreElements()
を呼び出し、返された値がfalseであった場合には、次の動作が適用されます。-
hasMoreElements()
の呼出しではfalseが返されます。 -
nextElement()
の呼出しではNoSuchElementException
がスローされます。
-
-
送信ブロック処理の取消し — 削除した宛先に対して送信された送信ブロック処理がすべて取り消されます。割当てを待機している送信処理は
ResourceAllocationException
を受け取ります。 -
コミットしていないトランザクションには影響しない: 宛先を削除しても、コミットしていない既存のトランザクションには影響しません。削除した宛先に関連付けられたコミットしていない作業は、トランザクションの一部として完了できます。ただし、宛先は削除されているため、すべての処理(ロールバック、コミットなど)で実際に実行されるのは関連付けられたメッセージの削除です。
削除された宛先のトラブルシューティングに使用するメッセージのタイムスタンプ
永続メッセージがある宛先が、削除されてからすぐに再作成され、そのときJMSサーバーが動作中でなかった場合、JMSサーバーは宛先のバージョン番号(構成ファイルconfig.xml
のCreationTime
フィールドを使用)と永続メッセージ内の宛先バージョン番号を比較します。この場合、古い宛先に残っている永続メッセージのバージョン番号は、config.xml
ファイルにある再作成された宛先のバージョン番号よりも古い番号になります。JMSサーバーが再起動すると、残っている永続メッセージは破棄されます。
ただし、永続メッセージのバージョン番号が、再作成された宛先のconfig.xml
にあるバージョン番号よりも新しい場合は、宛先が削除されてから(JMSサーバーが動作中でない状態で)再作成されたときにシステム・クロックがロールバックされたか、異なるconfig.xml
が使用されています。この場合、JMSサーバーの起動が失敗します。永続メッセージを保存するために、永続メッセージ内のバージョン番号に一致するバージョン番号(CreationTime
フィールド)をconfig.xml
に設定できます。または、config.xml
のバージョン番号を、永続メッセージ内のバージョン番号よりも新しい番号に変更できます。このようにすると、JMSサーバーは再起動時にメッセージを削除できます。
一時的な宛先の使い方
一時的な宛先を使用することで、サーバー定義の宛先の構成と作成に伴うシステム管理のオーバーヘッドを発生させずに、必要に応じてアプリケーションで宛先を作成できます。
JMSアプリケーションでは、JMSReplyTo
ヘッダー・フィールドを使用して、リクエストにレスポンスを戻すことができます。送信側アプリケーションでは、オプションとして、メッセージのJMSReplyTo
ヘッダー・フィールドをその一時的な宛先の名前に設定することで、使用している一時的な宛先を別のアプリケーションに対して公開できます。
一時的な宛先は、「一時的な宛先の削除」
の説明のとおりにdelete()メソッドを使用して削除されない限り、現在の接続が継続している間だけ存在します
サーバーが再起動すると、メッセージは使用できなくなるので、すべてのPERSISTENT
メッセージは自動的にNON_PERSISTENT
メッセージになります。そのため、一時的な宛先は、再起動によるデータの消失が許されないビジネス・ロジックには適していません。
ノート:
一時的な宛先は、JMSサーバーの一時的なテンプレートのホスト
属性ではデフォルトで有効化されています。ただし、一時的な宛先を特定の設定で作成する場合は、一時的なテンプレート
のデフォルト値を、JMSサーバーの一時的なテンプレート
および「一時的なテンプレートを含むモジュール」
属性を使用して変更する必要があります。詳細は、『Oracle WebLogic Server Administration Consoleオンラインヘルプ』のJMSサーバーの一般的なプロパティの構成に関する項を参照してください。
次の項では、一時的なキュー(ポイント・ツー・ポイント)または一時的なトピック(パブリッシュ/サブスクライブ)を作成する方法について説明します。
一時的なキューの作成
次のQueueSession
メソッドを使用して、一時的なキューを作成できます。
public TemporaryQueue createTemporaryQueue( ) throws JMSException
たとえば、現在の接続が継続している間だけ存在するTemporaryQueue
への参照を作成するには、次のメソッド呼出しを使用します。
QueueSender = Session.createTemporaryQueue();
一時的なトピックの作成
次のTopicSession
メソッドを使用して、一時的なトピックを作成できます。
public TemporaryTopic createTemporaryTopic( ) throws JMSException
たとえば、現在の接続が継続している間だけ存在する一時的なトピックへの参照を作成するには、次のメソッド呼出しを使用します。
TopicPublisher = Session.createTemporaryTopic();
恒久サブスクリプションの設定
WebLogic JMSでは、恒久サブスクリプションおよび非恒久サブスクリプションがサポートされています。アプリケーションに恒久サブスクリプションを設定する方法を学習します。
恒久サブスクリプションの場合、WebLogic JMSでは、メッセージはサブスクライバに配信されるか、または期限切れになるまで永続ファイルまたはデータベースに格納されます。この場合、メッセージの配信時にサブスクライバがアクティブな状態でなくてもかまいません。サブスクライバを表すJavaオブジェクトが存在していれば、サブスクライバはアクティブであるとみなされます。恒久サブスクリプションは、パブリッシュ/サブスクライブ・メッセージングのみにサポートされています。
ノート:
恒久サブスクリプションは、分散トピックに対しては作成できません。ただし、分散トピックのメンバーに対して恒久サブスクリプションを作成することはできます。こうすると、他のトピック・メンバーは、恒久サブスクリプションを持つメンバーにメッセージを転送します。「分散宛先の使用」を参照してください。
非恒久サブスクリプションの場合、WebLogic JMSでは、メッセージはアクティブ・セッションを持つアプリケーションにのみ配信されます。アプリケーションがリスニングしていない間にトピックへ送信されたメッセージは、二度とそのアプリケーションに配信されません。つまり、非恒久サブスクリプションは、そのサブスクライバ・オブジェクトが存在している間だけ存続します。デフォルトでは、サブスクライバは非恒久です。
以降の節で説明する内容は、次のとおりです。
永続ストアの定義
メッセージがサブスクライバに配信されるか、または期限切れになるまでWebLogic JMSがそのメッセージを保持できるようにするためには、永続ファイルまたはデータベース・ストアを構成してJMSサーバーに割り当てる必要があります。
-
「ストア」ノードを使用して、JMSファイル・ストアまたはJMS JDBCバッキング・ストアを作成します。
-
JMSサーバーの構成ページの「一般」タブにあるストア・フィールドのドロップダウン・リストから、構成したストアを選択してJMSサーバーに割り当てます。
ノート:
2つのJMSサーバーで同じバッキング・ストアを使用することはできません。
クライアントIDポリシーの設定
クライアントIDポリシーは、1つ以上のJMS接続がクラスタ内で同一のクライアントIDを使用できるかどうかを指定します。このポリシーの有効な値は次のとおりです。
-
RESTRICTED
: デフォルトです。このポリシーを使用する接続は、クラスタ内で特定のクライアントIDの所定の時間に1つのみ存在できます(接続が所定のクライアントIDを使用してすでに存在する場合、このポリシーを同一クライアントIDと併用して新しい接続を作成しようとする試行は、例外を表示して失敗します)。 -
UNRESTRICTED
: このポリシーを使用して作成された接続は、他の制限/無制限接続がすでに同一クライアントIDを使用する場合でも、任意のクライアントIDを指定できます。恒久サブスクリプションが無制限クライアントIDを使用して作成されるとき、それはweblogic.jms.extensions.WLJMSContext.unsubscribe(Topic topic, String name)
またはweblogic.jms.extensions.WLSession.unsubscribe(Topic topic, String name)
を使用してのみクリーンアップできます。「恒久サブスクリプションの管理」を参照してください。
特にサブスクリプション(恒久/非恒久)を共有する場合は、新しいアプリケーションに対してクライアントIDポリシーをUnrestricted
を設定することをお薦めします(使用するアプリケーションのアーキテクチャに排他的クライアントIDが必要な場合を除く)。異なるクライアントIDポリシーを使用して作成されたサブスクリプションは、常に単独のサブスクリプションとして扱われます。Oracle WebLogic Server MBeanリファレンスのClientIdPolicy
に関する項を参照してください。
WebLogicコンソールを使用して接続ファクトリ上で「クライアントIDポリシー」
属性を設定する場合、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの同一クライアントIDを使用した複数接続の構成に関する項を参照してください。接続ファクトリ設定は、Oracle WebLogic Server Java APIリファレンスのWLConnection
インタフェースのsetClientID
メソッドを使用して、プログラム的にオーバーライドできます。
高可用性アプリケーションの設計に必要な、高度な概念および共通分散トピック(UDT)の機能の詳細は、「共有サブスクリプションおよびクライアントIDポリシー」を参照してください
クライアントIDの定義
恒久サブスクリプションをサポートするには、接続に対してクライアントIDを定義する必要があります。
ノート:
JMSクライアントIDは、WebLogicセキュリティ・レルムでのユーザー認証で使用されるWebLogic Serverユーザー名とは必ずしも一致しません。使用するJMSアプリケーションにとって適切であれば、JMSクライアントIDにWebLogic Serverのユーザー名を設定しても構いません。
クライアントIDは、以下の2つの方法で設定できます。
-
最初の方法は、クライアントIDを使用する接続ファクトリを構成することです。WebLogic JMSでは、この方法は各クライアントIDの構成時に別々の接続ファクトリの定義を追加することになります。アプリケーションでは、JNDIでそれ自身のトピック接続ファクトリがルックアップされ、それを使用して自身のクライアントIDを含む接続が作成されます。詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプを参照してください。
-
または、望ましい方法として、接続を作成してからアプリケーションで次のConnectionメソッドを呼び出して、接続にクライアントIDを設定する方法もあります。
public void setClientID( String clientID ) throws JMSException
この代替方法を使用する場合は、デフォルトの接続ファクトリを使用すると(アプリケーションに適合している場合)、構成情報を変更する必要がありません。ただし、恒久サブスクリプションを含むアプリケーションでは、トピックの接続を作成した後で、すぐに
setClientID()
メソッドを呼び出す必要があります。クライアントIDが接続に対してすでに定義されている場合は、
IllegalStateException
がスローされます。指定したクライアントIDが別の接続に対してすでに定義されている場合は、InvalidClientIDException
がスローされます。ノート:
setClientID()
メソッドを使用してクライアントIDを指定する場合には、重複したクライアントIDが例外のスローなしに指定されてしまう危険性があります。たとえば、2つの異なる接続に対して、同じ値を持つクライアントIDが同時に設定されると、競合状態のまま、同じ値が両方の接続に割り当てられる場合があります。このような重複の危険性を回避するには、構成時にクライアントIDを指定します。クライアントIDを表示し、クライアントIDがすでに定義されているかどうかをテストするには、次のConnectionメソッドを使用します。
public String getClientID( ) throws JMSException
ノート:
恒久サブスクリプションのサポートは、パブリッシュ/サブスクライブ・メッセージング・モデル固有の機能なので、クライアントIDはトピック接続でしか使用できません。キュー接続にもクライアントIDがありますが、JMSでは使用されません。
恒久サブスクリプションは、一時的なトピックに対しては作成しないでください。一時的なトピックは、現在の接続が継続している間だけ存在するように設計されているからです。
共有サブスクリプション・ポリシーの作成
サブスクリプション共有ポリシーは、サブスクライバが同一接続上の他のサブスクライバとサブスクリプションを共有できるかどうかを指定します。このポリシーの有効な値は次のとおりです。
-
Exclusive
: デフォルトです。この接続ファクトリを使用して作成されるすべてのサブスクライバは、サブスクリプションを他のサブスクリプションと共有できません。このポリシーを使用してWebLogic Server 10.3.4.0以前の機能を保持できます。 -
Sharable:
この接続ファクトリを使用して作成されたサブスクライバは、サブスクライバが同一の接続ファクトリまたは異なる接続ファクトリのどちらを使用して作成されたかに関係なく、サブスクリプションを他のサブスクライバと共有できるようになります。コンシューマは、同一のクライアントIDおよびクライアントIDポリシーを持つ場合にのみ非永続サブスクリプションを共有できます。また、同一のクライアントID、クライアントIDポリシー、およびサブスクリプション名を持つ場合にのみ永続スクリプトを共有できます。
WebLogic JMSアプリケーションは、接続ファクトリの構成で指定されたサブスクリプション共有ポリシーをオーバーライドできます。それには、javax.jms.JMSContext
インスタンスをweblogic.jms.extensions.WLJMSContext
に、またはjavax.jms.Connection
インスタンスをweblogic.jms.extensions.WLConnection
にキャストして、 setSubscriptionSharingPolicy(String subscriptionSharingPolicy)
を呼び出します。
共有可能なサブスクリプション共有ポリシーを使用する大半のアプリケーションは、同一クライアントIDを使用する複数の接続が存続できることを保証するために無制限クライアントIDポリシーも使用できます。
同一クライアントIDおよびサブスクリプション名を持つ2つの恒久サブスクリプションは、異なるクライアントIDポリシーを持つ場合、2種類の独自のサブスクリプションとして扱われます。同様に、同一クライアントIDを持つ2つの共有可能な非恒久サブスクリプションは、異なるクライアントIDポリシーを持つ場合、2種類の独自のサブスクリプションとして扱われます。
サブスクリプション共有ポリシーを使用する方法の詳細は、次を参照してください。
-
Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリ・サブスクリプション共有ポリシーの構成に関する項
恒久サブスクリプション用のサブスクライバの作成
この項では、恒久サブスクリプション用のサブスクライバを作成する方法を説明します。次のトピックが含まれます。
JMS 2.0 APIの使用
非共有恒久サブスクリプション用のサブスクライバを作成するには、次のメソッドの1つを使用します。
public MessageConsumer createDurableConsumer( Topic topic, String name ) throws JMSException or public MessageConsumer createDurableConsumer( Topic topic, String name, String selector, boolean noLocal ) throws JMSException
JMS 1.1 APIの使用
以下のTopicSession
メソッドを使用して、恒久サブスクリプション用のサブスクライバを作成できます。
public TopicSubscriber createDurableSubscriber( Topic topic, String name ) throws JMSException or public TopicSubscriber createDurableSubscriber( Topic topic, String name, String messageSelector, boolean noLocal ) throws JMSException
サブスクライバを作成するトピックの名前と恒久サブスクリプションの名前を指定する必要があります。
ノート:
恒久サブスクリプションの名前に含めることのできない文字は、カンマ、等号、コロン、アスタリスク、パーセント記号、および疑問符です。
また、メッセージをフィルタ処理するためのメッセージ・セレクタ、およびnoLocal
フラグ(この節で後述)を指定することもできます。メッセージ・セレクタの詳細は、「メッセージのフィルタ処理」を参照してくださいselector
またはmessageSelector
を指定しない場合、デフォルトではすべてのメッセージが検索されます。
アプリケーションでは、JMS接続を使用して同じトピックに対してパブリッシュとサブスクライブの両方を行うことができます。トピック・メッセージはすべてのサブスクライバに配信されるので、アプリケーションは自身がパブリッシュしたメッセージを受信する可能性があります。これを防ぐために、JMSアプリケーションはnoLocal
フラグをtrue
に設定できます。noLocal
のデフォルト値はfalse
です。恒久サブスクリプションはファイルまたはデータベース内に格納されます。
ベスト・プラクティス:問題が発生したJMS ClientIDは常に閉じる
問題が発生したJMS接続については、ベスト・プラクティスとして、アプリケーションでJVMガベージ・コレクションを使用してクリーンアップするのではなく、JMSクライアントで常にclose()
メソッドを呼び出してクリーンアップすることをお薦めします。これは、JMS自動再接続機能では、問題が発生したJMS接続への参照が保持されるため、恒久サブスクリプションのClientIDに関しては特に重要です。したがって、常にconnection.close()
メソッドを使用して接続をクリーンアップします。また、接続リソースを確実にクリーンアップするため、finally
ブロックを使用することも検討してください。このようにしない場合、接続を使用可能な状態に維持するためにシステム・リソースが割り当てられてしまいます。
次のコード例では、close()
メソッドおよびfinally
ブロックをJMSクライアントで使用して問題が発生した接続リソースをクリーンアップする例を示しています。
JMSConnection con = null; try { con = cf.createConnection(); con.setClientID("Fred"); // Do some I/O stuff; } finally { if (con != null) con.close(); }
JMS自動再接続機能の詳細は、「JMSクライアントの自動フェイルオーバー」を参照してください
恒久サブスクリプションの削除
恒久サブスクリプションを削除するには、次のTopicSession
メソッドを使用します。
public void unsubscribe( String name ) throws JMSException
削除する恒久サブスクリプションの名前を指定する必要があります。
以下の条件のいずれかに当てはまる場合は、恒久サブスクリプションを削除できません:
-
TopicSubscriber
がセッションでまだアクティブです。 -
恒久サブスクリプションで受信したメッセージがトランザクションの一部であるか、またはセッションでまだ確認応答されていません。
ノート:
WebLogic Server管理コンソールを使用して恒久サブスクリプションを削除することもできます。恒久サブスクリプションの管理の詳細は、「恒久サブスクリプションの管理」を参照してください
恒久サブスクリプションの管理
WebLogic Server管理コンソールまたはパブリックな実行時APIを使用して、恒久トピック・サブスクライバをモニターおよび管理できます。恒久サブスクライバ上のすべてのメッセージを表示、参照したり、ほとんどのメッセージを操作したりすることもできます。こうした管理機能には、メッセージの参照(ソート目的)、メッセージの操作(移動、削除など)、メッセージのインポートとエクスポートなどがあります。詳細は、『Oracle WebLogic Server JMSリソースの管理』のJMSメッセージの管理に関する項を参照してください。
メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドの設定と参照
WebLogic JMSには、メッセージの識別および転送を定義できる一連の標準ヘッダー・フィールドが用意されています。さらに、プロパティ・フィールドを使用すると、標準セットを拡張した、アプリケーション固有のヘッダー・フィールドをメッセージ内に含めることができます。メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドを使用して、通信しているプロセス間で情報をやり取りできます。
データをメッセージ本文ではなくプロパティ・フィールドに含める主要な理由は、メッセージ・セレクタを使用したメッセージのフィルタ処理をサポートするためです。XMLメッセージ拡張機能以外では、メッセージ・セレクタからメッセージ本文のデータにアクセスすることはできません。たとえば、プロパティ・フィールドを使用して、あるメッセージに高い優先度を割り当てると仮定します。その場合、このプロパティ・フィールドにアクセスし、至急の優先度が指定されたメッセージだけを選択するメッセージ・セレクタを含むメッセージ・コンシューマを作成できます。「メッセージのフィルタ処理」を参照してください。
メッセージ・ヘッダー・フィールドの設定
JMSメッセージには、常にメッセージと共に送信されるヘッダー・フィールドの標準セットが含まれます。これらはメッセージを受信するメッセージ・コンシューマで利用でき、また、一部のフィールドはメッセージを送信するメッセージ・プロデューサで設定できます。メッセージの受信後、ヘッダー・フィールドの値は変更できます。
ヘッダー・フィールドの値を変更(オーバーライド)する際は、メッセージ・フィールドがJMSサブシステムによってオーバーライドされる場合があることを考慮に入れる必要があります。たとえば、プロデューサで優先度を設定するとメッセージの優先度に影響しますが、send()
メソッドに提供された値はプロデューサの設定をオーバーライドします。同様に、宛先で設定した値は、プロデューサによって設定された値や、send()
メソッドに提供された値をオーバーライドします。ヘッダー・フィールドの値を検証するには、send()
メソッドの後にメッセージに対して問合せを実行するしかありません。
標準メッセージ・ヘッダー・フィールドの詳細は、「メッセージ・ヘッダー・フィールド」を参照してください
表6-3に、messageクラスのsetメソッドとgetメソッドを、サポートされているデータ型ごとに示します。
ノート:
set()
メソッドを使用して設定されたヘッダー・フィールド値は、send()
メソッドによってオーバーライドされる場合もあります(次表参照)。
表6-3 JMSヘッダー・フィールド・メソッド
ヘッダー・フィールド | setメソッド | getメソッド |
---|---|---|
JMSCorrelationID |
public void setJMSCorrelationID(String correlationID) throws JMSException |
public String getJMSCorrelationID() throws JMSException
|
JMSDestination 脚注1 |
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メソッドだけでなく、
|
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 |
JMSRedeliveryLimit1 |
public void setJMSRedeliveryLimit(int redelivered) throws JMSException |
public int getJMSRedeliveryLimit() 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 |
脚注1
send()
メソッドが実行されている場合、対応するset()
メソッドは、メッセージ・ヘッダー・フィールドに影響を与えません。ヘッダー・フィールド値が設定されている場合は、send()
メソッドの処理中に、このヘッダー・フィールド値がオーバーライドされます。
EXAMPLES_HOME
\wl_server\examples\src\examples\jms\sender
ディレクトリにあるWebLogic Server付属のexamples.jms.sender.SenderServlet
例(EXAMPLES_HOME
は、WebLogic Serverのサンプル・コードが構成されるディレクトリを表す)は、送信するメッセージのヘッダー・フィールドを設定する方法、および送信後にメッセージのヘッダー・フィールドを表示する方法を示します。
たとえば、send()
メソッドの後に置く次のコードは、WebLogic JMSによってメッセージに割り当てられたメッセージIDを表示します。
System.out.println("Sent message " + msg.getJMSMessageID() + " to " + msg.getJMSDestination());
メッセージ・プロパティ・フィールドの設定
プロパティ・フィールドを設定するには、適切なsetメソッドを呼び出して、プロパティ名と値を指定します。プロパティ・フィールドを参照するには、適切なget method
を呼び出して、プロパティ名を指定します。
送信側アプリケーションはメッセージにプロパティを設定でき、受信側アプリケーションはそのプロパティを表示できます。受信側アプリケーションがプロパティを変更するには、まず次のclearProperties()
メソッドを使用してプロパティを消去する必要があります。
public void clearProperties( ) throws JMSException
このメソッドは、メッセージ・ヘッダー・フィールドおよびメッセージ本文はクリアしません。
ノート:
JMS用にJMSX
というプロパティ名の接頭辞が予約されています。接続メタデータには、JMSX
プロパティのリストが含まれています。getJMSXPropertyNames()
メソッドを使用して、列挙リストとして、このリストにアクセスできます。詳細については、「接続メタデータへのアクセス」を参照してください
プロバイダ固有のプロパティ用にJMS_
というプロパティ名の接頭辞が予約されています。この接頭辞は標準のJMSメッセージングでは使用できません。
プロパティ・フィールドは、boolean、byte、double、float、int、long、shortまたはstring
の各データ型のいずれかに設定できます。次の表に、Messageクラスのset
メソッドとget
メソッドを、サポートされているデータ型ごとに示します。
表6-4 メッセージ・プロパティのデータ型ごとの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
このメソッドは、すべてのプロパティ・フィールド名を列挙して返します。その後、プロパティ・フィールドのデータ型に基づいて、表6-4で説明されている適切なget
メソッドにプロパティ・フィールド名を渡すことで、各プロパティ・フィールドの値を取り出すことができます。
表6-5は、メッセージ・プロパティの変換チャートです。この表から、読込み可能なデータ型を、書き込まれたデータ型に基づいて識別できます。左端以外の列のいずれかに挿入されている「可」は、左端の列にリストされている、メッセージが書き込まれたプロパティの各データ型に対して、各列の一番上にリストされているデータ型としてメッセージを読み込むことができるということを意味しています。
表6-5 メッセージ・プロパティの変換チャート
書き込まれたプロパティのデータ型 | boolean | byte | double | float | int | long | short | String |
---|---|---|---|---|---|---|---|---|
boolean |
はい |
いいえ |
いいえ |
いいえ |
いいえ |
いいえ |
いいえ |
はい |
byte |
いいえ |
はい |
いいえ |
いいえ |
はい |
はい |
はい |
はい |
double |
いいえ |
いいえ |
はい |
いいえ |
いいえ |
いいえ |
いいえ |
はい |
float |
いいえ |
いいえ |
はい |
はい |
いいえ |
いいえ |
いいえ |
はい |
int |
いいえ |
いいえ |
いいえ |
いいえ |
はい |
はい |
いいえ |
はい |
long |
いいえ |
いいえ |
いいえ |
いいえ |
いいえ |
はい |
いいえ |
はい |
Object |
はい |
はい |
はい |
はい |
はい |
はい |
はい |
はい |
short |
いいえ |
いいえ |
いいえ |
いいえ |
はい |
はい |
はい |
はい |
String |
はい |
はい |
はい |
はい |
はい |
はい |
はい |
はい |
次の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 (https://javaee.github.io/javaee-spec/javadocs/javax/jms/Message.html
)を参照してください。
メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドの参照
ノート:
参照できるのは、キューのメッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドだけです。トピックのメッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドは参照できません。
以下の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
EXAMPLES_HOME
\wl_server\examples\src\examples\jms\queue
ディレクトリにあるWebLogic Server付属のexamples.jms.queue.QueueBrowser
例(EXAMPLES_HOME
は、WebLogic Serverのサンプル・コードが構成されるディレクトリを表す)は、受信したメッセージのヘッダー・フィールドにアクセスする方法を示します。
たとえば、次の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 (https://javaee.github.io/javaee-spec/javadocs/javax/jms/QueueBrowser.html
)を参照してください。
メッセージのフィルタ処理
多くの場合、アプリケーションでは、配信されるすべてのメッセージが通知される必要はありません。メッセージ・セレクタを使用して不要なメッセージをフィルタ処理することで、ネットワーク・トラフィックへの影響が最小限になり、パフォーマンスが向上します。
メッセージ・セレクタは、以下のように動作します。
-
送信側アプリケーションでは、標準化された方法でメッセージを説明したり分類したりするためのメッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドが設定されます。
-
受信側アプリケーションでは、単純な問合せ文字列を指定することで、アプリケーションで受信するメッセージがフィルタ処理されます。
メッセージ・セレクタはメッセージの内容(本文)を参照することができないため、情報の一部をメッセージ・プロパティ・フィールドに複製することもできます(XMLメッセージの場合を除く)。
キュー・レシーバまたはトピック・サブスクライバの作成時に、それぞれQueueSession.createReceiver()
メソッドまたはTopicSession.createSubscriber()
メソッドの引数としてセレクタを指定します。キュー・レシーバおよびトピック・サブスクライバの作成については、「ステップ5: メッセージ・プロデューサとメッセージ・コンシューマを作成する」を参照してください
WebLogic JMSは、状態または現在の処理状態を処理中のメッセージに割り当てます。このような状態をセレクタとして使用できます。有効なメッセージ状態の詳細は、Oracle WebLogic Server Java APIリファレンスのweblogic.jms.extensions.JMSMessageInfoに関する項を参照してください。
以降の節では、SQL文とXMLセレクタ・メソッドを使用してメッセージ・セレクタを定義する方法、およびメッセージ・セレクタを更新する方法について説明します。ヘッダー・フィールドおよびプロパティ・フィールドの設定の詳細は、それぞれ「メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドの設定と参照」、「メッセージ・プロパティ・フィールドの設定」を参照してください。
SQL文を使用したメッセージ・セレクタの定義
メッセージ・セレクタはブール式です。これは、SQL select
文の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 (https://javaee.github.io/javaee-spec/javadocs/javax/jms/Message.html
)を参照してください。
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値を返します。
-
メッセージによって解析されない場合
-
メッセージによって解析されるが、要素がない場合
-
メッセージによって解析され、要素も存在するが、メッセージに値が含まれていない場合(たとえば、
<order></order>
)
たとえば、次の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メッセージ・プロパティではない任意の文字列です(たとえば、JMSCorrelationID
でもJMSType
でもない文字列)。複数のサブスクライバが同じ識別子を共有できます。
WebLogic JMSでは、このメッセージ・セレクタ構文を、内部サブスクライバ索引を構築するためのヒントとして使用します。構文に従っていないメッセージ・セレクタ、または追加のOR
句およびAND
句を含むメッセージ・セレクタも受け付けられますが、最適化はアクティブ化されません。
このメッセージ・セレクタ構文を使用してサブスクライバを登録すると、トピックにパブリッシュされるメッセージは、1つまたは複数の識別子をメッセージのユーザー・プロパティに追加することにより、特定のサブスクライバをターゲットにすることが可能です。次に例を示します。
// Set up a named subscriber, where "wilma" is the name of // the subscriber and subscriberSession is a JMS TopicSession. // Note that the selector syntax used activates the optimization. TopicSubscriber topicSubscriber = subscriberSession.createSubscriber( (Topic)context.lookup("IMTopic"), "Wilma IS NOT NULL", /* noLocal= */ true); // Send a message to subscribers "Fred" and "Wilma", // where publisherSession is a JMS TopicSession. Subscribers // with message selector expressions "Wilma IS NOT NULL" // or "Fred IS NOT NULL" will receive this message. 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
確認応答モードを使用しているアプリケーションには効果がありません。このようなアプリケーションは、メッセージの選択がサーバー側ではなくクライアント側で行われるため、拡張の必要性はありません。
XMLメッセージの送信
WebLogic Server JMS APIでは、XMLメッセージを送信するためのドキュメント・オブジェクト・モデル(DOM)のネイティブ・サポートも提供されています。
ノート:
このリリースでは、ストリーミングはサポートされていません。サポートされるのは、XMLドキュメントのテキスト表現とDOM表現のみです。
以下の節では、XMLメッセージの拡張サポートを提供するWebLogic JMS APIの拡張機能について説明します。
WebLogic XML API
String
表現とDOM
表現の間のXML変換には、以下のWebLogic XML APIを使用できます。
-
XMLMessage
: XMLコンテンツを含むメッセージの送信に使用します。 -
WLSession.createXMLMessage
: XMLメッセージの作成に使用します。
XMLMessage
のペイロードは、あるXML表現を使用して設定し、別の表現を使用して取得できます。たとえば、XMLMessageの本文をString
表現を使用して設定し、DOM表現を使用して取得することも可能です。
String表現の使用
string
型を使用してXMLメッセージをパブリッシュするには、次のステップに従います。
- XMLを
StringWriter
にシリアライズします。 StringWriter
のtoString
を呼び出し、それをmessage.setText
に渡します。- メッセージをパブリッシュします。