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

前
次

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ネイティブ・インタフェース(JNI)(http://docs.oracle.com/javase/6/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リファレンスを参照してください。

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

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

システム要件

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

  • WebLogic JMS C APIに対してサポートされているオペレーティング・システムのリストは、Oracle Fusion Middlewareのサポートされているシステム構成のページを参照してください。『Oracle WebLogic Serverの新機能』 12.2.1.3.0のサポートされる構成に関する項を参照してください。

  • 使用しているオペレーティング・システムでサポートされるJVM。

  • 使用しているオペレーティング・システム用のANSI Cコンパイラ。

  • Cクライアント・アプリケーションからJMSアプリケーションへの接続には、次のWebLogicクライアントのいずれかを使用します。

    • WebLogic Thin T3クライアントjar (wlthint3client.jar)。詳細は、『Oracle WebLogic Serverスタンドアロン・クライアントの開発』のWebLogic Thin T3クライアントの開発に関する項を参照してください。

    • WebLogicアプリケーション・クライアント(wlfullclient.jarファイル)。『Oracle WebLogic Serverスタンドアロン・クライアントの開発』のWebLogic JarBuilderツールの使用に関する項を参照してください。

    • WebLogic JMSシン・クライアント(wljmsclient.jarファイル)。『Oracle WebLogic Serverスタンドアロン・クライアントの開発』のWebLogic JMSシン・クライアントに関する項を参照してください。

設計上の原則

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を実装する際の制限事項について説明します。

  • WebLogic Server JMS拡張(XMLメッセージを含む)はサポートされません。

  • JMSオブジェクト・メッセージはサポートされません。

  • クライアントでエラーが検知されるとエラー・ログが作成されます。このエラー・ログの名前はULOG.mmddyy (月/日/年)になります。このログ・ファイルは、クライアントのNLSPATHLOCALE、およびLANG環境変数を使用して完全に国際化されます。

  • メッセージ・カタログを翻訳する場合は、Windowsのgencatユーティリティまたはホスト・プラットフォームのgencatユーティリティを使用できます。生成されたカタログ・ファイルがNLSPATHLOCALE、および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 (リンク)