富士通

よくあるご質問(FAQ) - Interstage Application Server

共通

  • 対象製品
    Interstage Application Server V5 / V6 / V7 / V8 / V9
  • 対象OS
    Windows / Solaris / Linux

Q

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

A

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インタフェースポインタを別のスレッドに渡すといった使い方はできません。