ヘッダーをスキップ
Oracle® Fusion Middleware Oracle WebLogic Server JMSのプログラミング
11gリリース1 (10.3.6)
B61629-04
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

15 WebLogic JMS C API

この章では、WebLogic JMS C APIを使用して、JMSアプリケーションとリソースにアクセスできるCクライアントを作成するために必要な要件、設計上の原則、セキュリティの考慮事項および実装のガイドラインについて説明します。

WebLogic JMS C APIとは

WebLogic JMS C APIは、WebLogic JMSアプリケーションおよびリソースにアクセスできるCクライアント・アプリケーションを作成するためのアプリケーション・プログラム・インタフェースです。Cクライアント・アプリケーションでは、Javaネイティブ・インタフェース(JNI) (http://download.oracle.com/javase/1.5.0/docs/guide/jni/index.html)を使用してクライアント側のJava JMSクラスにアクセスします。図15-1を参照してください。

このリリースのWebLogic JMS C APIは、Java JMS 1.1コードの移植を容易にするため、JMSバージョン1.1仕様に準拠しています。詳細は、Oracle WebLogic Server JMS C APIリファレンスを参照してください。

図15-1 WebLogic JMS C APIクライアント・アプリケーション環境

図15-1の説明が続きます
「図15-1 WebLogic JMS C APIクライアント・アプリケーション環境」の説明

システム要件

ここでは、それぞれの環境でWebLogic JMS C APIを使用するためのシステム要件を示します。

設計上の原則

以下の節では、WebLogic JMS C APIのアプリケーションを移植または開発する上での原則について説明します。

ハンドルへのJavaオブジェクトのマッピング

WebLogic JMS C APIは、モジュール形式でコードを実装するハンドル・ベースのAPIです。つまり、アプリケーションではCコードのハンドルとしてJavaオブジェクトを実装します。JMSオブジェクトの実装方法の詳細はハンドル内に隠されます。ただし、Javaとは異なり、ハンドルを使用して実装したら、対応するCloseまたはDestroyメソッドを呼び出してハンドルを明示的に開放する必要があります。「メモリー割当てとガベージ・コレクション」を参照してください。

スレッドの利用

WebLogic JMS C APIから返されるハンドルがスレッド・セーフかどうかは、対応するJava型がスレッド・セーフかどうかによって決まります。例:

  • javax.jms.Sessionオブジェクトはスレッド・セーフではありません。これに対応するWebLogic JMS C APIハンドルJmsSessionもスレッド・セーフではありません。

  • java.jms.Connectionオブジェクトはスレッド・セーフです。これに対応するWebLogic JMS C APIハンドルJmsConnectionもスレッド・セーフです。

同時実行性制御をCクライアント・アプリケーションで管理しているかぎり、WebLogic JMS C APIが戻すすべてのオブジェクトはどのスレッドでも使用される可能性があります。

例外処理


注意:

WebLogic JMS C APIでは、整数のリターン・コードを使用します。

WebLogic JMS C APIでの例外は、実行スレッドに対してローカルです。WebLogic JMS C APIには、以下の型の例外があります。

  • JavaThrowableは、クラスjava.lang.Throwableを表します。

  • JavaExceptionは、クラスjava.lang.Exceptionを表します。

  • JmsExceptionは、クラスjavax.jms.JMSExceptionを表します。JMSExceptionのすべての標準サブクラスは、例外の型記述子内のビットによって判別されます。型記述子は、JmsGetLastExceptionを呼び出すと返されます。

型の変換

JavaコードとCコードを相互運用する場合、主なタスクの1つになるのがC型からJava型への変換です。たとえば、short型は、JavaでもCでも2バイト・エンティティです。以下の型変換では、特別な処理が必要になります。

Integer (int)

Integer (int)は、JMS32I (4バイト符号付き値)に変換します。

Long (long)

Long (long)は、JMS64I (8バイト符号付き値)に変換します。

Character (char)

Character (char)は、short (2バイトJava文字)に変換します。

String

Stringは、JmsStringに変換します。

Java文字列は、2バイト文字の配列です。Cの文字列は、通常はUTF-8エンコードの1バイト文字の配列です。純粋なASCII文字列はUTF-8仕様にも適合します。UTF-8文字列の詳細は、www.unicode.orgを参照してください。Cプログラマにとって、すべての文字列を2バイトJavaエンコーディングに変換するのは不便です。JmsString構造体を使用すると、アプリケーションの要件に応じ、Cクライアントでネイティブ文字列またはJava文字列を使用できます。

JmsStringでは、以下の2種類の文字列がサポートされます。

  • ネイティブC string (CSTRING)

  • JavaString (UNISTRING)

uniOrCというUNISTRINGCSTRINGのユニオンにはstringという文字ポインタがあり、これをNULLで終了するUTF-8エンコードのC文字列に使用できます。uniOrCユニオンは、文字列データと整数長(バイト)のvoidポインタを含むuniStringという構造体を提供します。

JmsStringstringType要素を入力として使用する場合、文字列入力の型に応じてCSTRINGまたはUNISTRINGを設定する必要があります。対応するデータ・フィールドには、入力として使用する文字列が含まれます。

UNISTRINGエンコーディングでは、すべての2バイトが単一のJava文字としてエンコードされます。2バイト・シーケンスはビッグエンディアンです。Unicodeでは、このエンコーディングをUTF-16BEと呼びます(2バイト・シーケンスがリトルエンディアンの場合はUTF-16LE)。CSTRINGエンコーディングでは、UTF-8でエンコードされた文字列が想定されます。

JmsStringstringType要素を出力として使用する場合、APIがmallocを使用して出力に十分なスペースを割り当てるようにするか、呼出し側でスペースを割り当てて、返された文字列がそのスペースにコピーされるようにするかを選択できます。ユニオン内の適切なフィールド(stringまたはdata)がNULLである場合は、APIがmallocを使用して出力に十分なスペースを割り当てます。この方法で割り当てたスペースは、メモリーをそれ以上使用しなくなったときに、呼出し側でfreeを使用して開放する必要があります。ユニオン内の適切なフィールド(stringまたはdata)がNULLでない場合は、JmsStringallocatedSizeフィールドに書込み可能なバイト数が指定されている必要があります。

文字列内に出力全体を格納するための十分なスペースがない場合は、allocatedSizeに必要なスペースの量が設定され、呼び出されたAPIがJMS_NEED_SPACEを返します。JmsStringの適切なフィールド(stringまたはdata)には、allocatedSizeバイトを限度として格納できるだけのデータが格納されます。この場合、返されるC文字列データの最後に、NULL文字が書き込まれる場合と書き込まれない場合があります。次に例を示します。

テキスト・メッセージからの文字列出力に100バイトを割り当てるため、データ・ポインタを設定し、allocatedSizeフィールドを100に設定したとします。JmsMessageGetTextMessage APIは、allocatedSizeが200に設定されたJMS_NEED_SPACEを返します。元の文字列でreallocを呼び出してデータ・ポインタをリセットし、関数をもう一度呼び出します。今回は呼出しが成功し、メッセージ・ハンドルから文字列を抽出できます。かわりに、元のバッファを開放して、正しいサイズの新しいバッファを割り当てることも可能です。

メモリー割当てとガベージ・コレクション

割り当てるすべてのリソースも、適切に破棄する必要があります。Javaでは、参照されなくなったすべてのオブジェクトは、ガベージ・コレクションによってクリーンアップされます。しかし、Cではすべてのオブジェクトを明示的にクリーンアップする必要があります。ユーザーに提供されたすべてのWebLogic JMS C APIハンドルは、明示的に破棄しなければなりません。ハンドルの動詞が、Closeで終わる場合とDestroyで終わる場合があることに注意してください。この規約に基づいて、closeメソッドを含むJavaオブジェクトと含まないJavaオブジェクトを区別できます。次に例を示します。

  • javax.jms.Sessionオブジェクトにはcloseメソッドが含まれているので、WebLogic JMS C APIにはJmsSessionClose関数があります。

  • javax.jms.ConnectionFactoryオブジェクトにはcloseメソッドが含まれていないので、WebLogic JMS C APIにはJmsConnectionFactoryDestroy関数があります。


    注意:

    クローズまたは破棄したハンドルは、再び参照しないようにしてください。

接続のクローズ

Java JMSでは、接続を暗黙的にクローズすると、従属するすべてのセッション、プロデューサ、およびコンシューマがクローズされます。WebLogic JMS C APIでは、接続をクローズしても、従属するセッション、プロデューサ、およびコンシューマはクローズされません。接続をクローズしたら、従属するすべてのハンドルは使用できなくなり、明示的にクローズする必要があります。

ヘルパー関数

WebLogic JMS C APIに用意されているヘルパー関数の中には、WebLogic JMSに存在しないものもあります。これらのヘルパーの詳細は、『Oracle WebLogic Server JMS C APIリファレンス』を参照してください。例:

JmsMessageGetSubclassJmsMessageハンドルで動作し、メッセージのサブクラスに対応する整数を返します。JMSでは、instanceofを使用してこの機能を実現できます。

セキュリティの考慮事項

WebLogic JMS C APIでは、usernamepasswordに基づくWebLogic互換性レルム・セキュリティ・モードがサポートされています。usernamepasswordは、InitialContextオブジェクトの作成に使用するハッシュ表のSECURITY_PRINCIPALおよびSECURITY_CREDENTIALSフィールドの初期コンテキストに渡す必要があります。

実装のガイドライン

WebLogic JMS C APIを実装する際は、以下の点に注意してください。

クライアントのクラッシュにおけるスレッドのデタッチ問題の回避策

JMS Cクライアント・ライブラリを使用するCプログラムは、JVMの障害によりクラッシュする可能性があります。この問題は、特定のJVM製品でのみ起きることが知られている断続的な競合状況に関連している可能性があります。失敗の可能性はJVMのバージョンとパッチ・レベル、オペレーティング・システム、およびハードウェアによって変わります。特に、JMS Cクライアント・ライブラリは暗黙的にCスレッドをJVMにアタッチしますが、実行後にそのスレッドをデタッチすることができません。推奨される回避策は、以下のとおりです。

例15-1のJava JNIのサンプル・コードでは、JVMからスレッドをデタッチする方法を示しています。

例15-1 Java JNIのサンプル・コード

#include <jni.h>

...

JavaVM *jvmList[JVM_LIST_SIZE];
jsize retSize = -1;
jint retVal = JNI_GetCreatedJavaVMs(jvmList, JVM_LIST_SIZE, &retSize);
if ((retVal != 0) || (retSize < 1) ) {
  printf('ERROR: got %d/%d on JNI_getCreatedJavaVMs\n', retVal, retSize);
  return;
}
printf('INFO: got %d/%d on JNI_getCreatedJavaVMs\n', retVal, retSize);
/* The following line assumes that there's exactly one JVM: */
(*(jvmList[0]))->DetachCurrentThread(jvmList[0]);

プログラムが直接JNI呼出しを実行しない場合は、Java JNIライブラリにアクセスするためにコンパイラおよびリンカーのパラメータを追加しなければならない場合があります。たとえば、MicroSoft Visual C++の場合は、次のパラメータを追加します。