プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle WebLogic Server JMSアプリケーションの開発
12c (12.2.1.3.0)
E90332-02
目次へ移動
目次

前
次

7 アプリケーションの管理

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管理コンソールで構成します。詳細については、以下を参照してください。

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

WebLogic JMSによるアプリケーションへのメッセージ再配信の試行回数に制限を設けることができます。宛先へのメッセージの再配信の失敗が指定した回数に達すると、そのメッセージ宛先に関連付けられたエラー宛先にメッセージをリダイレクトできます。再配信の制限が構成されていて、エラー宛先が構成されていない場合、永続メッセージまたは非永続メッセージは再配信の制限に達すると削除されます。

別の方法として、JMSProducerおよびMessageProducer属性の設定で説明しているように、メッセージ・プロデューサのsetメソッドを使用して動的に再配信制限値を設定できます

宛先のメッセージ再配信制限の構成

宛先によるコンシューマへのメッセージ再配信の試行が指定した再配信制限に達すると、宛先はメッセージを配信不能にします。RedeliveryLimit属性は、宛先で設定され、WebLogic Server管理コンソールで構成できます。この設定は、メッセージのプロデューサ側で設定された再配信制限をオーバーライドします。詳細については、以下を参照してください。

配信されなかったメッセージに対するエラー宛先の構成

配信されなかったメッセージのエラー宛先がJMSサーバーに構成されている場合は、宛先に配信できないと判断されたメッセージが指定したエラー宛先にリダイレクトされます。エラー宛先はトピックまたはキューのいずれかですが、定義されている宛先と同じJMSサーバーに構成する必要があります。エラー宛先が構成されていない場合、配信されなかったメッセージは削除されます。

ErrorDestination属性は、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に関する項を参照してください。

パフォーマンスの制限

順序付き再配信機能を実装したJMSアプリケーションには、JTAトランザクション(具体的にはMDBおよびWebLogicメッセージング・ブリッジ)を使用する非同期コンシューマのパフォーマンス低下が伴います。原因は送信中メッセージ数が強制的に1に削減されることであり、そのためメッセージは集約されずにクライアントに送信されます。

期限切れメッセージの処理

WebLogic JMSには、アクティブなメッセージ有効期限ポリシーが用意されています。このポリシーでは、期限切れメッセージの検索方法と処理方法を設定できます。この機能では、単純に期限切れメッセージを破棄するか、期限切れメッセージを破棄してそれをログに記録するか、または期限切れメッセージをローカルJMSサーバーのエラー宛先に転送することによって期限切れメッセージが即座に消去できます。

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

アプリケーションへのメッセージ配信を、将来の指定した時間にスケジューリングできます。

短い期間(秒や分など)の後でメッセージを配信することも、長い期間をおいた後で配信(数時間単位でバッチ処理する場合など)することもできます。その配信時間になって配信されるまでメッセージは表示されないため、将来の特定の時間に作業をスケジューリングできます。

メッセージが送信されるのは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 Server管理コンソールで構成可能です。

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

スケジューリングされたTimeToDeliverOverride属性はweblogic.jms.extensions.Scheduleクラスを使用しても指定できます。このクラスでは、スケジュールを取得し、次回のメッセージ配信時間を返すメソッドが提供されています。

表7-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クラスで使用するのと同じ範囲です。monthValuejava.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メソッドを示します。

表7-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 (http://docs.oracle.com/javaee/7/api/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宛先の作成および削除方法について説明します。

宛先の動的作成

宛先を動的に作成する方法については、以下のトピックを参照してください。

  • 「JMSモジュール・ヘルパーを使用したアプリケーションの管理」では、weblogic.jms.extensions.JMSModuleHelperの使用方法について説明します。JMSモジュール・ヘルパーの詳細は、「JMSモジュール・ヘルパーを使用したアプリケーションの管理」を参照してください

  • 「一時的な宛先の使い方」では、アプリケーションを有効化して要件に応じた宛先を作成する方法について説明します。一時的な宛先の使用方法の詳細は、「一時的な宛先の使い方」を参照してください

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

宛先の動的削除

次のいずれかの方法を使用して、JMS宛先(キューまたはトピック)を動的に削除できます。

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.xmlCreationTimeフィールドを使用)と永続メッセージ内の宛先バージョン番号を比較します。この場合、古い宛先に残っている永続メッセージのバージョン番号は、config.xmlファイルにある再作成された宛先のバージョン番号よりも古い番号になります。JMSサーバーが再起動すると、残っている永続メッセージは破棄されます。

ただし、永続メッセージのバージョン番号が、再作成された宛先のconfig.xmlにあるバージョン番号よりも新しい場合は、宛先が削除されてから(JMSサーバーが動作中でない状態で)再作成されたときにシステム・クロックがロールバックされたか、異なるconfig.xmlが使用されています。この場合、JMSサーバーの起動が失敗します。永続メッセージを保存するために、永続メッセージ内のバージョン番号に一致するバージョン番号(CreationTimeフィールド)をconfig.xmlに設定できます。または、config.xmlのバージョン番号を、永続メッセージ内のバージョン番号よりも新しい番号に変更できます。このようにすると、JMSサーバーは再起動時にメッセージを削除できます。

削除した宛先の統計

削除した宛先およびホストする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();

一時的な宛先の削除

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

public void delete(
) throws JMSException

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

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種類の独自のサブスクリプションとして扱われます。

サブスクリプション共有ポリシーを使用する方法の詳細は、次を参照してください。

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

この項では、恒久サブスクリプション用のサブスクライバを作成する方法を説明します。次のトピックが含まれます。

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管理コンソールを使用して恒久サブスクリプションを削除することもできます。恒久サブスクリプションの管理の詳細は、「恒久サブスクリプションの管理」を参照してください

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

恒久サブスクリプションを変更するには、次のステップを実行します:

  1. 「恒久サブスクリプションの削除」の手順に従って恒久サブスクリプションを削除します。

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

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

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

    注意:

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

恒久サブスクリプションの管理

WebLogic Server管理コンソールまたはパブリックな実行時APIを使用して、恒久トピック・サブスクライバをモニターおよび管理できます。恒久サブスクライバ上のすべてのメッセージを表示、参照したり、ほとんどのメッセージを操作したりすることもできます。こうした管理機能には、メッセージの参照(ソート目的)、メッセージの操作(移動、削除など)、メッセージのインポートとエクスポートなどがあります。詳細は、『Oracle WebLogic Server JMSリソースの管理』のJMSメッセージの管理に関する項を参照してください。

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

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

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

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

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

ヘッダー・フィールドの値を変更(オーバーライド)する際は、メッセージ・フィールドがJMSサブシステムによってオーバーライドされる場合があることを考慮に入れる必要があります。たとえば、プロデューサで優先度を設定するとメッセージの優先度に影響しますが、send()メソッドに提供された値はプロデューサの設定をオーバーライドします。同様に、宛先で設定した値は、プロデューサによって設定された値や、send()メソッドに提供された値をオーバーライドします。ヘッダー・フィールドの値を検証するには、send()メソッドの後にメッセージに対して問合せを実行するしかありません。

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

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

注意:

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

表7-3 JMSヘッダー・フィールド・メソッド

ヘッダー・フィールド setメソッド getメソッド
JMSCorrelationID
public void setJMSCorrelationID(
 String correlationID
) throws JMSException
public String getJMSCorrelationID(
) throws JMSException

public byte[] getJMSCorrelationIDAsBytes(
) throws JMSException
JMSDestinationFoot 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メソッドだけでなく、weblogic.jms.extensions.JMSRuntimeHelperクラスには、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
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メソッドを、サポートされているデータ型ごとに示します。

表7-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

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

表7-5は、メッセージ・プロパティの変換チャートです。この表から、読込み可能なデータ型を、書き込まれたデータ型に基づいて識別できます。左端以外の列のいずれかに挿入されている「可」は、左端の列にリストされている、メッセージが書き込まれたプロパティの各データ型に対して、各列の一番上にリストされているデータ型としてメッセージを読み込むことができるということを意味しています。

表7-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 (http://docs.oracle.com/javaee/7/api/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 (http://docs.oracle.com/javaee/7/api/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 (http://docs.oracle.com/javaee/7/api/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メッセージをパブリッシュするには、次の手順に従います。

  1. XMLをStringWriterにシリアライズします。
  2. StringWritertoStringを呼び出し、それをmessage.setTextに渡します。
  3. メッセージをパブリッシュします。

DOM表現の使用

XMLメッセージをDOM表現を使用して送信すると、Stringとしてメッセージを送信する場合に比べパフォーマンスがかなり向上します。DOM表現を使用してXMLメッセージをパブリッシュするには、次の手順に従います。

  1. 必要に応じて、XMLソースからDOMドキュメントを生成します。
  2. DOMドキュメントをXMLMessage.setDocumentに渡します。
  3. メッセージをパブリッシュします。