ページの先頭行へ戻る
Interstage Application Server V12.0.0 チューニングガイド
FUJITSU Software

10.5.9 JNI処理異常時のメッセージ出力

Java以外の言語と連携する場合、Java Native Interface(JNI)を使用します。
しかし、JNIの使用方法を誤ると、Javaプロセスの終了(異常終了)などの原因となります。

このとき、以下のオプションを指定することにより、JNI処理で異常が発生した場合にメッセージが出力されますので、JNIのパラメーターなどの確認に活用してください。

JNI処理異常時にメッセージを出力するオプション

-Xcheck:jni

“-Xcheck:jni”パラメーターを指定したときに、以下のメッセージが出力されることがあります。

JNI処理異常時に出力されるメッセージ

FATAL ERROR in native method: (詳細メッセージ)

(詳細メッセージ)

以降で説明する文字列が出力されます。

(詳細メッセージ)が出力される例と注意事項を説明します。
以降の説明を参考にして、JNIの処理部分を見直してください。

メッセージの説明

JNI received a class argument that is not a class

[異常例] AllocObject関数の第2引数にJNIハンドル経由で受け取ったjclass型ではない型(buf)を指定した場合:

(*env)->AllocObject(env, (jclass)buf);

JNI string operation received a non-string

[異常例] GetStringUTFChars関数の第2引数にNULLを指定した場合:

(*env)->GetStringUTFChars(env, NULL, 0);

Non-array passed to JNI array operations

[異常例] GetArrayLength関数の第2引数にjarray型ではない型を指定した場合:

(*env)->GetArrayLength(env, (jarray)(*env)->NewStringUTF(env, "abc"));

Static field ID passed to JNI

[異常例] GetIntField関数の第3引数にstaticフィールドを指定した場合:

jclass cls = (*env)->GetObjectClass(env, obj);
jjfieldID fid = (*env)->GetFieldID(env, cls, "static_data", "I");
(*env)->GetIntField(env, obj, fid);

"static_data"は、JNIハンドル経由で受け取ったobjオブジェクトのstaticフィールド名

Null object passed to JNI

[異常例] GetIntField関数の第2引数にNULLを指定した場合:

jclass cls = (*env)->GetObjectClass(env, obj);
jfieldID fid = (*env)->GetFieldID(env, cls, "instance_data", "I");
(*env)->GetIntField(env, NULL, fid);

"instance_data" は、JNIハンドル経由で受け取ったobjオブジェクトのinstanceフィールド名

注意

instance変数かどうかのチェック時だけに出力されるメッセージです。

以下のように、GetObjectClass関数の第2引数にNULLを指定した場合、 “-Xcheck:jni”オプションによるメッセージは出力されません。

(*env)->GetObjectClass(env, NULL);

Wrong field ID passed to JNI

[異常例] GetIntFieldの第3引数に数値を指定した場合:

(*env)->GetIntField(env, obj, -1);

注意

instance変数かどうかのチェック時だけに出力されるメッセージです。

Non-static field ID passed to JNI

[異常例] GetStaticIntField関数の第3引数に数値を指定した場合:

jclass cls = (*env)->GetObjectClass(env, obj);
(*env)->GetStaticIntField(env, cls, -1);

注意

以下のように、GetStaticFieldID関数の第2引数にinstanceフィールド名を指定した場合、“-Xcheck:jni”オプションによるメッセージは出力されません。

jclass cls = (*env)->GetObjectClass(env, obj);
jfieldID fid = (*env)->GetStaticFieldID(env, cls, "instance_data", "I");
(*env)->GetStaticIntField(env, cls, fid);

"instance_data" は、JNIハンドル経由で受け取ったobjオブジェクトのinstanceフィールド名

Array element type mismatch in JNI

[異常例] GetFloatArrayElements関数の第2引数にjintArray型を指定した場合:

jintArray intarray = (*env)->NewIntArray(env, 2);

(*env)->GetFloatArrayElements(env, intarray, 0)

Object array expected but not received for JNI array operation

[異常例] GetIntArrayElements関数の第2引数にjobjectArray型を指定した場合:

jclass cls = (*env)->GetObjectClass(env, obj);
jobjectArray objarray = (*env)->NewObjectArray(env, 1, cls, obj);
(*env)->GetIntArrayElements(env, objarray, 0);

Field type (static) mismatch in JNI get/set field operations

[異常例] GetStaticFloatField関数の第3引数にint型のjfieldIDを指定した場合:

jclass cls = (*env)->GetObjectClass(env, obj);
jfieldID fid = (*env)->GetStaticFieldID(env, cls, "static_data", "I");
(*env)->GetStaticFloatField(env, cls, fid);

"static_data"は、JNIハンドル経由で受け取ったobjオブジェクトのstaticフィールド名

Field type (instance) mismatch in JNI get/set field operations

[異常例] GetFloatField関数の第3引数にint型のjfieldIDを指定した場合:

jclass cls = (*env)->GetObjectClass(env, obj);
jfieldID fid = (*env)->GetFieldID(env, cls, "instance_data", "I");
(*env)->GetFloatField(env, obj, fid);

"instance_data" は、JNIハンドル経由で受け取ったobjオブジェクトのinstanceフィールド名

Wrong static field ID passed to JNI

[異常例] GetStaticObjectField関数の第2引数に不正なjclassを指定した場合:

jclass cls = (*env)->GetObjectClass(env, obj);
jclass cls2 = (*env)->GetObjectClass(env, (*env)->NewStringUTF(env, "abc"));
jfieldID fid = (*env)->GetStaticFieldID(env, cls, "static_data", "I");
(*env)->GetStaticObjectField(env, cls2, fid);

"static_data"は、JNIハンドル経由で受け取ったobjオブジェクトのstaticフィールド名

Using JNIEnv in the wrong thread

[解説]

実行しているスレッドのためのものではないJNIEnvを使用したためのエラーです。
Java VMは、JNIインタフェースポインタ(JNIEnv)が参照する領域を、スレッド固有のデータ領域に割り当てることがあります。このため、JNIインタフェースポインタは、カレントスレッドに対してだけ有効です。ネイティブメソッドは、JNIインタフェースポインタを別のスレッドに渡すといった使い方はできません。

JNI call made with exception pending

[解説]

ネイティブプログラムで何らかの例外が発生後、その例外を処理せずに引き続きJNI関数を実行したためのエラーです。
ネイティブプログラムでJNI関数を呼び出した後は、その都度ExceptionOccurredを使用して例外の発生状況をチェックし、必要に応じて、例外のクリア、または、例外を上位メソッドへスローしてください。