JNI(Java Native Interface)の使用方法に誤りがないか、チェックできますか?
Interstage Application Serverのよくあるご質問を検索できます。
Interstage Application Serverの技術情報はこちら
- JNI(Java Native Interface)の使用方法に誤りがないか、チェックできますか?
- JDK1.3.1_04以降、またはJDK1.4以降をご使用であれば、java起動時のオプションに次のオプションを指定することにより、実行時のJNIの引数チェックなどができます。
-Xcheck:jni
異常がある場合、以下のメッセージが表示されます。"FATAL ERROR in native method: XXXX"
XXXX部は以下のとおりです。メッセージに従って、処理を確認してください。- "JNI received a class argument that is not a class"
例:
char buf[1];
(*env)->AllocObject(env, (jclass)buf); //jclass型の第2引数に違う型を指定
- "JNI received a null class"
例:
(*env)->AllocObject(env, NULL); //jclass型の第2引数にNULLを指定
- "JNI string operation received a non-string"
例:
(*env)->GetStringUTFChars(env, NULL, 0); //jstring型の第2引数にNULLを指定
- "Non-array passed to JNI array operations"
例:
(*env)->GetArrayLength(env, (jarray)(*env)->NewStringUTF(env, "abc"));
//jarray型の第2引数に配列でない型を指定
ただし、以下の場合は、“-Xcheck:jni”オプションによるメッセージは出力されません。
char buf[1];
(*env)->GetArrayLength(env, (jarray)buf);
- "Static field ID passed to JNI"
例:
jclass cls = (*env)->GetObjectClass(env, obj);
jfieldID fid = (*env)->GetFieldID(env, cls, "static_data", "I");
//jfieldID型の第3引数にstaticフィールドを指定
(*env)->GetIntField(env, obj, fid);
- "Null object passed to JNI"
例:
jclass cls = (*env)->GetObjectClass(env, obj);
jfieldID fid = (*env)->GetFieldID(env, cls, "instance_data", "I");
(*env)->GetIntField(env, NULL, fid); //object型の第2引数にNULLを指定
instance変数かどうかのチェック時だけに出力されるメッセージです。
以下の場合は、“-Xcheck:jni”オプションによるメッセージは出力されません。
(*env)->GetObjectClass(env, NULL); //object型の第2引数にNULLを指定
- "Wrong field ID passed to JNI"
例:
(*env)->GetIntField(env, obj, -1); //jfieldID型の第3引数に数値を指定
instance変数かどうかのチェック時だけに出力されるメッセージです。
- "Non-static field ID passed to JNI"
例:
jclass cls = (*env)->GetObjectClass(env, obj);
(*env)->GetStaticIntField(env, cls, -1); //jfieldID型第3引数に数値を指定
ただし、以下の場合は、“-Xcheck:jni”オプションによるメッセージは出力されません。
jclass cls = (*env)->GetObjectClass(env, obj);
jfieldID fid = (*env)->GetStaticFieldID(env, cls, "instance_data", "I");
//第3引数は、本来staticのフィールド
(*env)->GetStaticIntField(env, cls, fid);
- "Array element type mismatch in JNI"
例:
jintArray intarray = (*env)->NewIntArray(env, 2);
(*env)->GetFloatArrayElements(env, intarray, 0);
//floatArray型の第2引数にjintArrayを指定
- "Object array expected but not received for JNI array operation"
例:
jclass cls = (*env)->GetObjectClass(env, obj);
jobjectArray objarray = (*env)->NewObjectArray(env, 1, cls, obj);
(*env)->GetIntArrayElements(env, objarray, 0);
//intArray型の第2引数にjobjectArray型を指定
- "Unknown array object passed to JNI array operations"
- "Field type (static) mismatch in JNI get/set field operations"
例:
jclass cls = (*env)->GetObjectClass(env, obj);
jfieldID fid = (*env)->GetStaticFieldID(env, cls, "static_data", "I");
(*env)->GetStaticFloatField(env, cls, fid);
//GetStaticFloatFieldではなくGetStaticIntFieldでなければならない
- "Static field not found in JNI get/set field operations"
- "Field type (instance) mismatch in JNI get/set field operations"
例:
jclass cls = (*env)->GetObjectClass(env, obj);
jfieldID fid = (*env)->GetFieldID(env, cls, "instance_data", "I");
(*env)->GetFloatField(env, obj, fid);
//GetFloatFieldではなくGetIntFieldでなければならない
- "Instance field not found in JNI get/set field operations"
- "Wrong static field ID passed to JNI"
例:
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);
//第2引数はcls2ではなくclsでなければならない
- "Wrong object class or methodID passed to JNI call"
- "Bad global or local ref passed to JNI"
- "Using JNIEnv in the wrong thread"
実行しているスレッドのためのものではないJNIEnvを使用したためのエラーです。
Java VMは、JNIインタフェースポインタ(JNIEnv)が参照する領域をスレッド固有のデータ領域に割り当てることがあります。このため、JNIインタフェースポインタは、カレントスレッドに対してだけ、有効です。ネイティブメソッドは、JNIインタフェースポインタを別のスレッドに渡すといった使い方はできません。製品・サービス区分 Interstage 製品・サービス情報 対象製品 Interstage Application Server バージョン V9, V8, V7, V6, V5 プラットフォーム Windows, Solaris, Linux アンサー種別 共通 - "JNI received a null class"
- "JNI received a class argument that is not a class"