JNI(Java Native Interface)の使用方法に誤りがないか、チェックできますか?
Interstage Application Serverのよくあるご質問を検索できます。
Interstage Application Serverの技術情報はこちら
- JNI(Java Native Interface)の使用方法に誤りがないか、チェックできますか?
- 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インタフェースポインタを別のスレッドに渡すといった使い方はできません。
- "JNI received a class argument that is not a class"
製品・サービス区分 | Interstage | ||||||
---|---|---|---|---|---|---|---|
製品・サービス情報 |
|
||||||
アンサー種別 | 共通 |