16 WebLogic JMS C API
WebLogic JMS C APIを使用してWebLogic JMSアプリケーションおよびリソースにアクセスできるCクライアントを作成するために必要な要件、設計上の原則、セキュリティの考慮事項および実装のガイドラインについて説明します。
WebLogic JMS C APIとは
WebLogic JMS C APIは、WebLogic JMSアプリケーションおよびリソースにアクセスできるCクライアント・アプリケーションを作成するためのアプリケーション・プログラム・インタフェースです。
Cクライアント・アプリケーションでは、Java Native Interface (JNI)(http://docs.oracle.com/javase/8/docs/technotes/guides/jni/index.html
)を使用してクライアント側のJava JMSクラスにアクセスします。図16-1を参照してください。
このリリースのWebLogic JMS C APIは、Java JMS 1.1コードの移植を容易にするため、JMSバージョン1.1仕様に準拠しています。Oracle WebLogic Server JMS C APIリファレンスを参照してください。
システム要件
それぞれの環境でWebLogic JMS C APIを使用するためのシステム要件を示します。
-
WebLogic JMS C APIに対してサポートされているオペレーティング・システムのリストは、Oracle Fusion Middlewareのサポートされているシステム構成のページを参照してください。『Oracle WebLogic Serverの新機能』のサポートされる構成に関する項を参照してください。
-
使用しているオペレーティング・システムでサポートされるJVM。
-
使用しているオペレーティング・システム用のANSI Cコンパイラ。
-
Cクライアント・アプリケーションからJMSアプリケーションへの接続には、次のWebLogicクライアントのいずれかを使用します。
-
WebLogic Thin T3クライアントjar (
wlthint3client.jar
)。詳細は、『Oracle WebLogic Serverスタンドアロン・クライアントの開発』のWebLogic Thin T3クライアントの開発に関する項を参照してください。
-
WebLogicインストール・クライアント(
weblogic.jar
ファイル)。『Oracle WebLogic Serverスタンドアロン・クライアントの開発』のWebLogicインストール・クライアントに関する項を参照してください。
-
設計上の原則
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バイト・エンティティです。以下の型変換では、特別な処理が必要になります。
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
というUNISTRING
とCSTRING
のユニオンにはstring
という文字ポインタがあり、これをNULL
で終了するUTF-8エンコードのC文字列に使用できます。uniOrC
ユニオンは、文字列データと整数長(バイト)のvoidポインタを含むuniString
という構造体を提供します。
JmsString
のstringType
要素を入力として使用する場合、文字列入力の型に応じてCSTRING
またはUNISTRING
を設定する必要があります。対応するデータ・フィールドには、入力として使用する文字列が含まれます。
UNISTRING
エンコーディングでは、すべての2バイトが単一のJava文字としてエンコードされます。2バイト・シーケンスはビッグエンディアンです。Unicodeでは、このエンコーディングをUTF-16BEと呼びます(2バイト・シーケンスがリトルエンディアンの場合はUTF-16LE)。CSTRING
エンコーディングでは、UTF-8でエンコードされた文字列が想定されます。
JmsString
のstringType
要素を出力として使用する場合、APIがmalloc
を使用して出力に十分なスペースを割り当てるようにするか、呼出し側でスペースを割り当てて、返された文字列がそのスペースにコピーされるようにするかを選択できます。ユニオン内の適切なフィールド(stringまたはdata)がNULLである場合は、APIがmalloc
を使用して出力に十分なスペースを割り当てます。この方法で割り当てたスペースは、メモリーをそれ以上使用しなくなったときに、呼出し側でfree
を使用して開放する必要があります。ユニオン内の適切なフィールド(stringまたはdata)がNULLでない場合は、JmsString
のallocatedSize
フィールドに書込み可能なバイト数が指定されている必要があります。
文字列内に出力全体を格納するための十分なスペースがない場合は、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リファレンスを参照してください。たとえば:
JmsMessageGetSubclass
はJmsMessage
ハンドルで動作し、メッセージのサブクラスに対応する整数を返します。JMSでは、instanceof
を使用してこの機能を実現できます。
セキュリティの考慮事項
WebLogic JMS C APIでは、username
とpassword
に基づくWebLogic互換性レルム・セキュリティ・モードがサポートされています。
username
とpassword
は、InitialContext
オブジェクトの作成に使用するハッシュ表のSECURITY_PRINCIPAL
およびSECURITY_CREDENTIALS
フィールドの初期コンテキストに渡す必要があります。
実装のガイドライン
WebLogic JMS C APIを実装する際の制限事項について説明します。
-
WebLogic Server JMS拡張(XMLメッセージを含む)はサポートされません。
-
JMSオブジェクト・メッセージはサポートされません。
-
クライアントでエラーが検知されるとエラー・ログが作成されます。このエラー・ログの名前は
ULOG.mmddyy
(月/日/年)になります。このログ・ファイルは、クライアントのNLSPATH
、LOCALE
、およびLANG
環境変数を使用して完全に国際化されます。 -
メッセージ・カタログを翻訳する場合は、Windowsの
gencat
ユーティリティまたはホスト・プラットフォームのgencat
ユーティリティを使用できます。生成されたカタログ・ファイルがNLSPATH
、LOCALE
、およびLANG
変数に従って配置されていれば、ログ・ファイルにメッセージを書き込む際に翻訳済みのカタログが使用されます。 -
クライアント環境では、以下の環境変数を設定できます。
-
JMSDEBUG
: クライアントからの出力の冗長デバッグを提供します。 -
JMSJVMOPTS
: クライアントによってロードされたJVMに追加の引数を提供します。 -
ULOGPFX
: エラー・ログ・ファイルを配置する場所のパス名とファイル接頭辞を構成します。
-
クライアントのパッケージ化の要件
Cアプリケーションをパッケージ化する際には、JMS C APIライブラリおよびその他のファイルを含める必要があります。
Cアプリケーションの実行可能ファイルとともに、次のファイルを含めます。
-
使用しているオペレーティング・システムでサポートされるJVM。
-
アプリケーションを実行するマシン上にWebLogic Serverがインストールされていない場合、WebLogic JMSクライアントjarファイル(通常はwlthint3client.jar)。詳細は、『Oracle WebLogic Serverスタンドアロン・クライアントの開発』のWebLogic Thin T3クライアントの開発に関する項を参照してください。
-
クライアントの実行可能ファイルがそのJMS Cライブラリを動的にリンクする場合は、アプリケーションを実行するプラットフォームに固有のJMS C APIライブラリを含めます。JMS C API動的ライブラリは、WebLogic Serverインストールの次の場所からコピーできます。
-
server/native/aix/ppc/libjmsc.so
-
server/native/aix/ppc64/libjmsc.so
-
server/native/hpux11/IPF64/libjmsc.so
-
server/native/linux/i686/libjmsc.so
-
server/native/linux/ia64/libjmsc.so
-
server/native/linux/s390x/libjmsc.so
-
server/native/linux/x86_64/libjmsc.so
-
server/native/solaris/sparc/libjmsc.so
-
server/native/solaris/sparc64/libjmsc.so
-
server/native/solaris/x64/libjmsc.so
-
server/native/solaris/x86/libjmsc.so
-
server/native/win/32/jmsc.dll
-
server/native/win/64/jmsc.dll
-
server/native/win/x64/jmsc.dll
-
クライアントの失敗におけるスレッドのデタッチ問題の回避策
JMS Cクライアント・ライブラリを使用するCプログラムは、暗黙的に組み込まれたJVMの障害により失敗する可能性があります。
JMSクライアントの失敗は、特定のJVM製品でのみ起きることが知られている断続的な競合状況に関連している可能性があります。失敗の可能性はJVMのバージョンとパッチ・レベル、オペレーティング・システム、およびハードウェアによって変わります。特に、JMS Cクライアント・ライブラリは暗黙的にCスレッドをJVMにアタッチしますが、実行後にそのスレッドをデタッチすることができません。推奨される回避策は、次のとおりです。
-
以前にJMS C-APIを呼び出した既存のCスレッドからJVMをデタッチするコードをクライアントに追加します。
-
以前にJMS C-APIにコールされたCスレッドが、プロセス全体が終了する前に終了することを禁止します。
例16-1のJava JNIのサンプル・コードでは、JVMからスレッドをデタッチする方法を示しています。
例16-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++の場合は、次のパラメータを追加します。
-
-I$(JAVA_HOME)/include
および-I$(JAVA_HOME)/include/win32
(コンパイル) -
$(JAVA_HOME)/lib/jvm.lib
(リンク)