JNI(Java Native Interface)の使用方法に誤りがないか、チェックできますか?

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
アンサー種別 共通
このページの先頭へ