4 プログラミングの考慮事項

この章では、JMS .NETクライアント・アプリケーションを作成する際のプログラミングの考慮事項とベスト・プラクティスを示します。

この章の内容は次のとおりです。

WebLogic JMS拡張機能の使用

表4-1では、このリリースのJMS .NETクライアントでサポートされるWebLogic JMS拡張機能を示します。メッセージングを構成するにはいくつかの方法があります。

  • 接続ファクトリでの構成 - この方法では主にデフォルトの構成設定を定義します。

  • APIを使用してアプリケーションでプログラム的に構成 - 特定のプログラミング構成で接続ファクトリの構成をオーバーライドできます。

  • サーバーでの構成 - 特定の設定で接続ファクトリとプログラム構成の両方をオーバーライドできます。

JMS .NETクライアントとJavaクライアントでは、拡張機能の構成方法や動作に違いがある場合もあります。たとえば、拡張機能によっては、JMS .NET APIを使用してプログラム的に有効にすることはできず、構成を通じてのみ有効にできるものもあります。以下の表にその違いをまとめています。それ以降の節では、必要に応じて、追加の詳細情報を示しています。

表4-1 JMS .NETクライアントでサポートされるWebLogic JMS拡張機能

機能 接続ファクトリで構成可能 サーバーで構成可能 Java API JMS .NETAPI 説明

分散宛先(共通、重み設定)

詳細は、次を参照してください:

はい

はい

いいえ

いいえ

フロー制御プロデューサ

詳細は、『Oracle WebLogic Serverのパフォーマンスのチューニング』JMSサーバーおよび宛先のメッセージのフロー制御に関する項を参照してください。

はい

はい

いいえ

いいえ

割当て条件内でのプロデューサのブロック

詳細は、『Oracle WebLogic Serverのパフォーマンスのチューニング』接続ファクトリでの送信タイムアウトの定義に関する項を参照してください。

はい

はい

いいえ

いいえ

WebLogic Serverのリモート・インスタンス用の外部宛先

詳細は、『Oracle WebLogic Server JMSリソースの管理』外部サーバー・リソースからサード・パーティJMSプロバイダへのアクセスの構成に関する項を参照してください。

いいえ

はい

いいえ

いいえ

「以前のリリースのWebLogic Serverとの相互運用」を参照してください

ストア・アンド・フォワード(SAF)インポート済み宛先

詳細は、『Oracle WebLogic Serverストア・アンド・フォワード・サービスの管理』SAFインポート済宛先に関する項を参照してください。

いいえ

はい

いいえ

いいえ

再配信制限

詳細は、『Oracle WebLogic Server JMSアプリケーションの開発』メッセージの再配信制限の設定に関する項を参照してください。

いいえ

はい

はい

いいえ

再配信遅延

詳細は、『Oracle WebLogic Server JMSアプリケーションの開発』メッセージの再配信遅延の設定に関する項を参照してください。

はい

いいえ

はい

いいえ

エラー宛先

詳細は、『Oracle WebLogic Server JMSアプリケーションの開発』配信されなかったメッセージのエラー宛先の構成に関する項を参照してください。

いいえ

はい

いいえ

いいえ

WLDestination.getCreateDestinationArgument

いいえ

いいえ

はい

はい

「確認応答なし」モード

詳細は、『Oracle WebLogic Server JMSアプリケーションの開発』NO_ACKNOWLEDGEの使用に関する項を参照してください。

いいえ

いいえ

はい

はい

順序単位

詳細は、次を参照してください:

はい

はい

はい

はい

「順序単位」を参照してください。

メッセージ配信のスケジューリング

詳細は、『Oracle WebLogic Server JMSアプリケーションの開発』メッセージ配信時間の設定に関する項を参照してください。

はい

はい

はい

はい

「メッセージ配信時間」を参照してください

非同期コンシューマのメッセージ最大パイプライン

はい

いいえ

はい

いいえ

メッセージの圧縮

詳細は、『Oracle WebLogic Server JMSアプリケーションの開発』メッセージ圧縮に関する項を参照してください。

はい

いいえ

はい

いいえ

「メッセージの圧縮」を参照してください。

割当て

詳細は、『Oracle WebLogic Serverのパフォーマンスのチューニング』割当ての定義に関する項を参照してください。

いいえ

はい

いいえ

いいえ

一方向のメッセージ送信

詳細は、『Oracle WebLogic Serverのパフォーマンスのチューニング』一方向のメッセージ送信の使用に関する項を参照してください

はい

いいえ

いいえ

いいえ

「一方向のメッセージ送信」を参照してください

確認応答ポリシー

詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプJMS接続ファクトリ: 構成: クライアントに関する項を参照してください。

はい

いいえ

いいえ

いいえ

メッセージ・プロパティJMSXUserIDとして自動的にuser-idを含む

はい

はい

いいえ

いいえ

「JMSXUserIdとしてのuser-idの使用」を参照してください

メッセージ・プロパティJMSXDeliveryCountとして配信試行回数を取得

いいえ

いいえ

いいえ

いいえ

「メッセージ配信の試行」を参照してください

メッセージの圧縮

このリリースでは、JMS .NETクライアントとWebLogic Server上で実行されるJMS .NETクライアント・ホストの間のメッセージ送信において、メッセージの自動圧縮はサポートされていません。ただし、接続ファクトリで圧縮が設定されている場合、.NETクライアント・ホストと宛先の間でのメッセージ圧縮の動作は、Javaクライアントの場合と同じになります。動作は次のとおりです。

  • クライアント・ホストと宛先がWebLogic Serverの別々のインスタンス上で実行されている場合、送信されたメッセージはクライアント・ホストにおいて自動的に圧縮されます。

  • クライアント・ホストと宛先がWebLogic Serverの同じインスタンス上で実行されている場合、送信されたメッセージは圧縮されません。

圧縮されたメッセージは、.NETクライアントが受信するときに、JMS .NETクライアント・ホストによってサーバー側で解凍されます。

詳細は、『Oracle WebLogic Server JMSアプリケーションの開発』メッセージ圧縮に関する項を参照してください。

順序単位

JMS .NET APIで順序単位(UOO)を指定する方法はJava APIとは異なります。JMS .NET APIで順序単位を設定するには、希望するUOOを持つメッセージにConstants.MessagePropertyNames.UNIT_OF_ORDER_PROPERTY_NAMEという文字列プロパティを追加します。

詳細は、『Oracle WebLogic Server JMSアプリケーションの開発』メッセージ順序単位の使用に関する項を参照してください。

メッセージ配信時間

JMS .NET APIでメッセージ配信時間を指定する方法はJava APIとは異なります。JMS .NET APIでメッセージ配信時間を設定するには、long型のプロパティConstants.MessagePropertyNames.DELIVERY_TIME_PROPERTY_NAMEをメッセージに追加します。この値は、メッセージが配信される将来のミリ秒数です。

一方向のメッセージ送信

接続ファクトリで一方向のメッセージ送信を構成することはできますが、この動作はJMS .NETクライアントでは完全にサポートされていません。一方向送信として送信されたメッセージは、.NETクライアントと.NETクライアント・ホストの間では自動的に双方向送信となり、.NETクライアント・ホストとJMS接続ホストの間では一方向送信になります。

JMSXUserIdとしてのuser-idの使用

受信メッセージに対するシステム生成のメッセージ・プロパティJMSXUserId (オプション)では、元の送信者の資格証明を指定します。このプロパティを有効にするには、宛先、分散宛先、またはテンプレートで[センダー資格証明をアタッチ]属性を構成し、接続ファクトリで「JMSXUserIdをアタッチ」属性を構成します。取得するには、msg.GetStringProperty(Constants.MessagePropertyNames.USER_ID_PROPERTY_NAME)を呼び出します。

メッセージ配信の試行

受信メッセージに対するシステム生成のメッセージ・プロパティJMSXDeliveryCountでは、メッセージ配信の試行回数を指定します。最初の試行は1になります。値を取得するには、msg.GetIntProperty(Constants.MessagePropertyNames.DELIVERY_COUNT_PROPERTY_NAME)を呼び出します。

WebLogic JMS .NETクライアントの使用に関する制限事項

以下の節では、JMS .NETクライアントでサポートされないJMS機能について説明します。

サポートされないJMS 1.1の標準機能

このリリースでは、以下のJMS 1.1の標準機能はサポートされません。

  • 一時的な宛先の作成とクローズ(javax.jms.TemporaryQueueおよびjavax.jms.TemporaryTopic)。ただし、受信メッセージのJMSReplyToヘッダーから宛先オブジェクトを取得する場合は、Javaクライアントで作成された一時的な宛先に対してJMS .NETクライアントはメッセージを生成できます。

  • javax.jms.QueueRequesterおよびjavax.jms.TopicRequester.(これらのヘルパー・クラスは一時的な宛先に関連しています)。

  • キュー・ブラウザ(javax.jms.QueueBrowser)。

  • キューおよびトピックのインタフェース(QueueConnectionFactoryTopicConnectionFactoryQueueConnectionTopicConnectionQueueSessionTopicSession)。これらのキューとトピックのインタフェースはJMS 1.0.2のレガシー・インタフェースであり、JMS 1.1の共通インタフェースで置き換えられました。

サポートされないJMS 1.1のオプション機能

このリリースでは、以下のJMS 1.1のオプション機能はサポートされません。

  • XAインタフェース(XAConnectionFactoryXAConnection、およびXASession)。

  • グローバルXAトランザクションへの参加(「トランザクション」を参照)。

  • 接続コンシューマとサーバー・セッション・プール(javax.jms.ConnectionConsumerServerSessionPool、およびServerSession)。これらはJava EE MDBで置き換えられたオプション機能であり、WebLogic Java JMSクライアントではサポートされていません。

  • MessageProducer.setDisableMessageTimestampメソッド。WebLogic JMS Javaクライアントはこのメソッドを無視します。

サポートされないWebLogic JMS拡張機能

このリリースでは、以下のWebLogic JMS拡張機能はサポートされません。

  • SSL

  • HTTPトンネリング

  • SAFクライアント - Oracle WebLogic Serverスタンドアロン・クライアントの開発JMS SAFクライアントによる確実なメッセージ送信を参照してください。

  • マルチキャスト・サブスクライバについては、『Oracle WebLogic Server JMSアプリケーションの開発』「WebLogic JMSでのマルチキャストの使い方」を参照してください

  • 自動再接続 - 『Oracle WebLogic Server JMSアプリケーションの開発』JMSクライアントの自動フェイルオーバーに関する項を参照してください。

  • 作業単位(UOW) - .NETクライアントがメッセージにUOWプロパティを設定しようとすると、Weblogic.Messaging.MessageExceptionが生成されます。また、.NETコンシューマは、Javaクライアントによって送信されたデシリアライズ可能なコンテンツを持つUOWメッセージを受信します。この場合、コンシューマは、ObjectMessageObjectMessage.getObject()メッセージを呼び出すと、MessageFormatExceptionを受け取ります。作業単位はサポートされませんが、より一般的な拡張機能である順序単位は完全にサポートされています。順序単位の詳細は、 「順序単位」を参照してください

    ノート:

    JMS .NET APIではJMSリソース(トピックやキューなど)をプログラム的に構成するための拡張機能は提供していません。Javaでプログラム的に構成するには、JMX MBeansまたはweblogic.jms.extensions.JMSModuleHelperヘルパー・クラスを使用します。JMSを構成するその他の方法としては、WLSTスクリプトやWebLogic Server管理コンソールがあります。

トランザクション

このリリースでは、JMS .NETクライアントはJMS仕様での定義にのみ従ってトランザクション・セッションをサポートします。トランザクション・セッションは標準のローカル・トランザクションの機能を提供します。Javaクライアントの場合と同様に、同じクラスタ内の1つまたは複数のWebLogic JMS宛先がトランザクション・セッションのローカル・トランザクションに参加できますが、他のリソースは参加できません(他のクラスタ内のJMSサーバー、データベース、外部JMSプロバイダなど)。

グローバルXAトランザクションはサポートされないため、JMSは.NETトランザクションには参加できません。接続ファクトリのXAの設定は.NETクライアントによって無視されます。JMS .NETクライアントの処理は.NETトランザクションには参加できません。

異なる言語環境間でのメッセージの交換

.NETプロデューサとJavaまたはCコンシューマ、あるいはJavaまたはCプロデューサと.NETコンシューマの間で、以下のJava JMSメッセージ・タイプを交換できます。

  • Message

  • BytesMessage

  • StreamMessage

  • MapMessage

  • TextMessage

ただし、ObjectMessageタイプは一方の言語から別の言語に送信することはできますが、そのメッセージは同じ言語で記述されない限り、解釈可能になりません。ObjectMessageタイプのプロデューサとコンシューマは同じ言語で記述する必要があります。不一致が生じた場合、つまり、.NET ObjectMessageがJavaコンシューマで受信されたり、Java ObjectMessageが.NETコンシューマで受信されたりした場合、message.getObject()MessageFormatExceptionを送出します。

URLフォーマットの指定

Provider_URLには、以下のフォーマットを使用して、カンマで区切って複数のアドレスを格納できます。

t3://address [,address]...

特定のアドレスで複数のポート範囲を指定できます。

複数のアドレスを指定する構文は次のとおりです。

address = hostlist : portlist

説明:

hostlist = hostname [, hostname]...
portlist = portrange [+ portrange]...
portrange = port [- port]

port -portを使用してポート範囲を指定し、+ (プラス記号)を使用して複数のポート範囲を区切ります。

表4-2に、URLフォーマットの例を示します。

表4-2 URLフォーマットの例

フォーマット 可能なフォーマット

t3://hostA:7001 t3://hostA,hostB:7001,hostC:7002

t3://hostA:7001,hostB:7001,hostC:7002

t3://hostA:7001+7005+7007,hostB:7001

t3://hostA:7001,hostA:7005,hostA:7007, hostB:7001

t3://hostA:7001-7003+7005+7007,hostB:8001

t3://hostA:7001,hostA:7002,hostA:7003, hostA:7005,hostA:7007,hostB:8001

DNS別名ホスト名の使用

複数のホストに展開されるDNS別名ホスト名を指定することもできます。たとえば、DNS別名myclusterhost1,host2に解決される場合、URL t3://mycluster:7001はアドレス・リストt3://host1:7001,host2:7001に展開されます。このURLを指定して作成されたコンテキストでは常に、host1にアクセスできない場合はhost2を使って再試行します。DNS別名は通常、ネットワーク管理者が構成します。

JMS .NETクライアントでのセキュリティの実装

JMS .NETクライアントを作成する場合は以下のセキュリティの考慮事項に注意する必要があります。

  • サーバー上のセキュアなJNDIおよびJMSリソースにアクセスするために、JMS .NETクライアント・アプリケーションは以下のようにユーザー名とパスワードを提示できます。

    • ContextFactory.CreateContext()を使用して、サーバーへの初期コンテキストを確立します。サーバー上のセキュアなJNDIおよびJMSリソースにアクセスするための認証では、初期コンテキストの作成時に提示された資格証明が使用されます。

    • IConnectionFactory.createConnection()メソッドを使用して接続を作成します。この場合、接続の作成時に提示された資格証明が、初期コンテキストで提示された資格証明をオーバーライドします。たとえば、初期コンテキストでユーザーFredが提示され、接続の作成時にユーザーTonyが提示された場合、セキュアなJMSリソースにアクセスするための認証では、ユーザーTonyの資格証明が使用されます。

      ノート:

      どちらのインスタンスでもパスワードは暗号化されます。リソースがセキュアでない場合は、ユーザー名とパスワードは省略可能です。

      ノート:

      ユーザー名とパスワードは保護され、パスワードは暗号化されますが、高度なユーザーや侵入者によって保護メカニズムが破られる可能性があります。ユーザー名とパスワードを提示する場合には、ネットワーク接続を保護するようにしてください。

  • .NETクライアントの認証は、セキュアなリソースを呼び出すJMSオブジェクトに関連付けられています。つまり、JMSオブジェクトの資格証明は親のJMSコンテキストから継承されるか、接続の作成時に資格証明が提示された場合には接続オーバーライドから継承されます。この点は、資格証明が現在のスレッドに関連付けられているJavaクライアントのセキュリティとは異なります。

  • このリリースのJMS .NETクライアントではSSLはサポートされません。そのため、オペレーティング・システムが提供するネットワーク・サービスを保護するほかに、ネットワーク接続を保護することが重要です。詳細は、『Oracle WebLogic Server本番環境の保護』ネットワークの保護に関する項を参照してください。

  • Javaクライアントと同様に、JMS .NETクライアントはメッセージ・レベルの暗号化をサポートしません。

  • 暗号化されていない通信を使用すると、アプリケーション・トラフィックの傍受が可能になります(http://www.owasp.org/index.php/Sniffing_application_traffic_attackを参照)。このようなリスクを受け入れるか、攻撃を防御するためにファイアウォールを使用するなどの対策を取る必要があります。

  • 管理ポートが構成された場合は、SSLトラフィックのみを受け入れ、ポートを経由するすべての接続は管理者権限を必要とします。また、管理ポートが構成された場合、他のすべてのポートは管理者権限を持つ接続を拒否します。このリリースのJMS .NETクライアントではSSLがサポートされていないため、管理ポートが構成されている場合でも、管理者権限を持つユーザーをサポートできません。

ロギングとデバッグの構成

サーバー側の転送と、WebLogic Server上で実行される.NETクライアント・ホストにおいて、基本的なロギングとデバッグを使用できます。

サーバー側

サーバー側でデバッグを有効にするには、以下のコマンドを使用します。

-Dweblogic.debug.DebugJMSDotNetT3Server=true
-Dweblogic.debug.Debug.JMSDotNetProxy=true 

クライアント側

クライアント側のロギングとデバッグを有効にして制御するには、アプリケーション構成ファイル内の様々な構成設定を使用します。生成されたビルド・ファイルに対するアプリケーション構成ファイルの名前はyourapplicationname.exe.configです。yourapplicationnameはメッセージング・クライアントを実行するアプリケーションの名前です。

例4-1では、ロギングとデバッグを構成するためにアプリケーション構成ファイルに追加する必要のあるXMLコンテンツを示します。その後の節で、各種の設定の詳細について補足します。すでにyourapplicationname.exe.configファイルがある場合は、以下のリストで示すXMLコンテンツをファイルに追加してください。そうでない場合は、ファイルを作成して、yourapplicationname.exeファイルと同じディレクトリに格納してください。

ノート:

Visual Studioを使用している場合は、例4-1に示すロギングとデバッグの設定をApp.configファイルに追加する必要があります。Visual Studio環境でC#プロジェクトにApp.configファイルを追加するには、Microsoft Webサイトhttp://msdn.microsoft.com/en-us/library/ms184658.aspxの指示に従ってください。

例4-1 yourapplicationname.exe.configファイルのXMLファイル・コンテンツ

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <!-- To forward log output to a file, please uncomment the following line, and replace the file name with the desired one -->
    <!--- <add key="weblogic.debug.JMSDotNet.config.LogFileName" value="c:\test\MyLogFile.log" /> -->
    
    <!-- To prevent log messages from displaying to the console, use the value 'false' -->
    <!-- <add key="weblogic.debug.JMSDotNet.config.IsLogToConsole" value="false" /> -->    
  </appSettings>
  <system.diagnostics>
    <switches>
      <!-- Please set the switch value as desired for logging to each Category -->
      <!-- value for Off=0, Error=1, Warning=2, Info=3, Verbose=4    -->
 
      <!-- if "AllLogger" is enabled (no zero for the value), every individual category is set to the same level as the AllLogger,
            no matter how individual category's value is set -->
      <add name="weblogic.debug.JMSDotNet.All" value="0" />
      <add name="weblogic.debug.JMSDotNet.Socket" value="0" />
      <add name="weblogic.debug.JMSDotNet.T3" value="0" />
      <add name="weblogic.debug.JMSDotNet.Transport" value="0" />
      <add name="weblogic.debug.JMSDotNet.PhysicalMsg" value="0" />
      <add name="weblogic.debug.JMSDotNet.LogicalMsg" value="0" />
    </switches>
  </system.diagnostics>
</configuration>
メッセージ出力

ログ・メッセージをコンソールに出力するか、ファイルに保存するかを指定するには、表4-3に示すように、<appSettings>要素を使用します。

表4-3 appSettingsの値

キー 設定

weblogic.debug.JMSDotNet.config.LogFileName

String

ログ・ファイルの絶対パスとファイル名(c:\test\MyLogFile.logなど)。

ノート: デフォルトのログ・ファイル・サイズ制限は500KB。ログ・ファイルがこのサイズに達するたびに、サーバーはログ・ファイルの名前を変更し、新しいMyLogFile.logを作成して新しいメッセージを格納します。デフォルトでは、ローテーションされるログ・ファイルには、MyLogFile.log.0MyLogFile.log.1MyLogFile.log.2...のように作成順に番号が付けられます。MyLogFile.log.0に最新のログ・メッセージが格納されます。

weblogic.debug.JMSDotNet.config.IsLogToConsole

Boolean

  • True — ログ・メッセージをコンソールに表示します。

  • False — ログ・メッセージをコンソールに表示しません。

ログのカテゴリとレベル

クライアント側のロギングは以下のカテゴリに分類されます。

  • Socket

  • T3

  • Transport

  • PhysicalMsg

  • LogicalMsg

  • All (上記の個々のカテゴリのすべてを表す)

カテゴリごとに次のロギング・レベルを指定できます。

Off(0), Error(1), Warning(2), Info(3), Verbose(4)

Allカテゴリの重大度レベルは個々のカテゴリの設定をオーバーライドすることに注意してください。

ソケットとスレッドの動作の理解

WebLogic JMS .NETクライアントは他のタイプのWebLogicクライアントと同じWebLogic Server T3ポートを共有します。.NETクライアントはContextFactoryクラスを使用してIContext初期コンテキストを作成するときに、サーバー上のT3対応のポートを参照するURLを指定します。要求されたネットワーク接続を処理するために、1つのソケット・ペアが暗黙的に作成されます。ソケット・ペアはクライアント上の1つのソケットと、WebLogic Server JMS .NETクライアント・ホスト上のもう1つのソケットから成ります。.NETコンテキストから取得されたJMSオブジェクトに対するJMS操作はすべて、コンテキストの暗黙的なネットワーク接続を通じてルーティングされます。

同じ.NET CLR上で2つのIContext初期コンテキスト・インスタンスが、同じWebLogic Server JMS .NETクライアント・ホストに同時に接続した場合は、2つのネットワーク接続が作成されます。各ネットワーク接続はそれぞれ1組のソケット(サーバー側ソケットとクライアント側ソケット)を保持します。したがって、2つのネットワーク接続が作成された場合は、CLRクライアント上で2つのソケットが作成され、JMS .NETクライアント・ホストとして機能するWebLogic Server上でも2つのソケットが作成されます。この動作はWebLogic Javaクライアントとは対照的です。WebLogic Javaクライアントでは、リモートのJVMへのネットワーク接続が重複していれば自動的に検出し、重複した接続を閉じます。かわりに、特定のリモートJVMとの間のすべてのトラフィックを、1つのネットワーク接続上で暗黙的に多重化します。

JMS .NETクライアントのサーバー側ソケットは、他のタイプのWebLogicクライアントと同じWebLogic Serverソケット・リーダー・マルチプレクサ・スレッド・プールによって提供されます。JMS .NETクライアントのリクエストを処理する場合、ソケット・リーダー・マルチプレクサ・スレッド・プールは受信リクエストをソケットから読み取り、WebLogic Serverのデフォルト・スレッド・プールに作業をディスパッチします。デフォルト・スレッド・プールでは、リクエストを処理してクライアントに応答を返送します。

JMS .NETクライアントでは、ネットワーク接続ごとに(つまり、各IContext初期コンテキスト・インスタンスに対して)新しい内部スレッドが自動的に作成されます。この専用のスレッドがクライアントで受信するすべてのデータを読み取り、関連する作業をCLRスレッド・プールにディスパッチします。つまり、.NETクライアント・アプリケーションの非同期メッセージ・イベント・ハンドラはCLRスレッド・プール内で実行されます。

ノート:

CLRスレッド・プールは.NET FrameworkのSystem.Threading.ThreadPoolクラスで提供されます。1つのプロセスにつき1つのスレッド・プールが存在します。スレッド・プールのデフォルト・サイズは1プロセッサ当たり25スレッドであるが、ThreadPool.SetMaxThreadsメソッドを使用すると、スレッド・プール内のスレッド数を変更できます。スレッド・プール内の各スレッドはデフォルトのスタック・サイズを使用し、デフォルトの優先度で実行されます。詳細は、Microsoft .NET FrameworkのドキュメントでSystem.Threading.ThreadPoolクラスを参照してください。

JMS .NETアプリケーションで同時に多数の初期コンテキストが作成され、そのすべてが同じWebLogic Server .NETクライアント・ホストに接続する場合は、1つの共有初期コンテキストを使用するようにアプリケーションを変更すると、パフォーマンスを改善できます。共有コンテキストを使用すると、クライアントは1つのネットワーク接続のみを作成するようになります。

Javaおよび.NET間のデータ変換

エンディアンの変換

Javaと.NETではプリミティブ型を格納するために異なる形式のバイト順序を使用しています。

  • Microsoft Windows .NETはリトル・エンディアン(下位順序)形式を使用

  • Javaはビッグ・エンディアン(上位順序)形式を使用

Javaと.NETの相互運用性をサポートするために、データはビッグ・エンディアン形式を使用してネットワーク上で転送されます。.NETアプリケーションがJMS .NET APIを使用してプリミティブの読み書きを行うときに、データは必要に応じて自動的に、ビッグ・エンディアンとリトル・エンディアンの間で変換されます。たとえば、JMS .NET APIのBytesMessage.WriteIntを使用する場合、データは常にビッグ・エンディアンで格納され、Java APIとJMS .NET APIの両方のバイト・メッセージ読込み整数メソッドを使用して読み込むことができます。

JMS .NET APIを使用してプリミティブを渡すかわりに、未加工のバイト配列を使用してプリミティブ・データを転送する特殊なアプリケーションの場合は、Javaとやり取りする際にバイト形式をビッグ・エンディアンに手動で変換する必要があります。アプリケーションでエンディアンの手動変換を実行する必要がある場合は、JMS .NETクライアント・ライブラリで提供されているユーティリティ・クラスWebLogic.Messaging.Transport.Util.EndianConvertorの以下のヘルパー・メソッドを使用できます。

public static char SwitchEndian(char x)
public static short SwitchEndian(short x)
public static int SwitchEndian(int x)
public static long SwitchEndian(long x)
public static ushort SwitchEndian(ushort x)
public static uint SwitchEndian(uint x)
public static ulong SwitchEndian(ulong x)
public static double SwitchEndian(double x)
public static float SwitchEndian(float x)
public static byte[] SwitchEndian(byte[] x) 

たとえば、未加工のバイト配列との間でプリミティブの読み書きを行う標準の.NETクラスSystem.IO.BinaryReaderSystem.IO.BinaryWriterでは、リトル・エンディアンを使用します。以下のコードの抜粋は、.NETのバイト配列との間で整数を格納および取得する方法を示しています。

binaryWriter.WriteInt(EndianConverter.SwitchEndian(i))
i=EndianConverter.SwitchEndian(binaryReader.ReadInt())

符号付きバイトと符号なしバイトの変換

Javaプリミティブ・データ型のそれぞれに同じ名前と定義のC#データ型が対応していますが、byteデータ型については例外があります。以下の表に、C#とJavaで符号付きバイトと符号なしバイトに使用される異なる名前を示します。

表4-4 C#とJavaのバイト・プリミティブ・データ型

C# Java 説明

byte

N/A

符号なしバイト

sbyte

byte

符号付きバイト

表4-4に示すように、Microsoft .NETでは、byte (符号なしバイト)とsbyte (符号付きバイト)の両方をプリミティブ・データ型としてサポートしていますが、Javaでは、byte (符号付きバイト)のみを直接のプリミティブ型としてサポートしています。どちらの言語の標準規約でもbyteデータ型の使用が規定されていますが、.NETでは符号なしバイトを表し、Javaでは符号付きバイトを表します。

.NETとJavaの間の相互運用性を確保するため、JMS .NETクライアントではバイトの読み書きに符号付きバイトのみを使用するようになっています。バイト値が127以下の場合は符号付きバイトと符号なしバイトの間に違いはありません。値が127以下の符号なしバイトはsbyteとして格納されます。ただし、.NETクライアントで127より大きな値の符号なしバイトを符号付きバイトに格納する必要があった場合は、その値を符号付きバイトから符号なしバイトに変換する必要が生じます。以下のサンプルでは、符号なしバイトを符号付きバイトとして読み書きするために使用できる変換メソッドを例示します。

  • C#でのバイト変換

    符号なしバイト値の255を次のように符号付きバイトとして渡すことができます。

    • byte unsignedByteValue = 255;

    • sbyte signedByteValue = unchecked ( (sbyte)unsignedByteValue ); //変換後の符号付き値 =-1

    同様に、以下のメソッドを使用して、符号付きバイト値を符号なしバイト値に変換できます。

    • sbyte signedByteValue = -1;

    • byte unsignedByteValue = unchecked ( (byte)signedByteValue ); //変換後の符号なし値 =255

  • Javaでのバイト変換

    次のように、符号なしバイトは符号付きバイトとして読み込んでから、符号なしバイト値に変換できます。

    • byte signedByteValue = -1;

    • int unsignedByteValue = 0xFF & signedByteValue; //変換後の符号付き値 = 255

    符号なしバイト値は次のように書き込むことができます。

    • Int unsignedByteValue = 255;

    • byte signedByteValue = 0xFF & unsignedByteValue; //変換後の符号付き値 =-1

JMS .NET APIでは1つのバイトを符号付きバイトとしてのみ格納できます。JMS .NET APIを使用してsbyteshortintlong、またはstringとして取得する場合、値は符号なしバイトではなくsbyteとして扱われます。たとえば、符号なしバイト値255をmessage.SetByteProperty("myvalue", unchecked( (sbyte)((byte)255) ))を使用して格納した場合、message.GetByteProperty("myvalue")またはmessage.GetShortProperty("myvalue")を呼び出すと「-1」が返されます。

バイト配列の転送

JMS .NETクライアントからWebLogic JMSにバイト配列を転送する場合、すべてのバイト配列(byte[])はそのまま渡されます(つまり、符号なしから符号付きへの変換はありません)。そのため、変換でデータが失われることはありません。

時間の変換

WebLogic JMS .NET APIでは、.NETの規約ではなくJavaの規約を使用して日付と時間を表現します。WebLogic.Messaging.IMessageメッセージ・インタフェースのJMSTimestampおよびJMSExpiration属性はlong型であり、Javaプログラミング言語で規定されているミリ秒の絶対時間を格納します。Javaのミリ秒の絶対時間の値は、協定世界時(UTC)の1970年1月1日午前0時から特定の時間までの差異をミリ秒単位で測定したものです。

以下の例では、.NET時間とJavaのミリ秒の絶対時間の値の変換方法を示します。

例4-2 現在の.NET時間をJavaのミリ秒時間に変換するC#サンプル・コード

// Example:  C# code for converting the current .NET time to Java millisecond time
DateTime baseTime = new DateTime(1970, 1, 1, 0, 0, 0);
DateTime utcNow = DateTime.UtcNow;
long timeInMillis = (utcNow.Ticks - baseTime.Ticks)/10000;
Console.WriteLine(timeInMillis);

例4-3 Javaのミリ秒時間を.NET時間に変換するC#サンプル・コード

// Example:  C# code for converting Java millisecond time to .NET time
DateTime baseTime = new DateTime(1970, 1, 1, 0, 0, 0);
long utcTimeTicks = (timeInMillis * 10000) + baseTime.Ticks;
DateTime utcTime = new DateTime(utcTimeTicks, DateTimeKind.Utc);
Console.WriteLine(utcTime);
Console.WriteLine(utcTime.ToLocalTime());

ベスト・プラクティス

以下の節では、JMS .NETクライアント・アプリケーションを作成する際のプログラミングのベスト・プラクティスを示します。

  • アイドル接続が失敗した場合にアプリケーションが対応する必要がある場合は、IConnectionを使用して接続例外リスナーを常に登録します。.NETクライアントとWebLogic .NETクライアント・ホストの間や、WebLogicホストとJMS接続ホストの間で通信エラーが発生した場合は、接続例外リスナーに非同期に通知されます。アプリケーションでは接続例外リスナー・コールバックを実装して、開いているすべてのリソースを閉じてから、定期的に再接続を試行することもできます。

  • パフォーマンスを向上させるには、複数の.NETクライアント・スレッドで1つのコンテキストを共有して、1つのソケットを使用するようにします。「ソケットとスレッドの動作の理解」を参照してください。1つのコンテキストで1つのソケットが作成され、コンテキストを閉じるとそのソケットも閉じられる点に留意してください。

  • コンテキスト、接続、セッション、プロデューサ、宛先、接続ファクトリなど、頻繁にアクセスするJMSリソースはキャッシュして再利用します。これらのリソースを作成してクローズすると、CPUとネットワーク帯域幅がかなり消費されます。

  • close()メソッドを除いて、JMSセッションとその子リソースはスレッド・セーフではありません。たとえば、プロデューサとコンシューマを同じセッションで作成した場合は、あるスレッドでプロデューサのsend()メソッドを呼び出し、並行して別のスレッドでコンシューマのreceive()メソッドを呼び出さないようにしてください。もう1つ例を挙げると、非同期コンシューマがあるセッションの任意のスレッドではclose()以外のメソッドを呼び出さないでください。メッセージの到着とコールバックの呼出しが同時に行われる可能性があるためです。

  • クラスタ内の複数のJMS .NETクライアント・ホスト・サーバーにわたってJMS .NETクライアントをロード・バランシングする場合は、DNS別名かカンマ区切りのアドレスを使用します。このリリースのJMS .NETクライアントでは、Javaクライアントで暗黙的に提供されるようなクラスタの自動ロード・バランシングはサポートしていません。