1

PHP 拡張機能 (C で作成) を作成しました。JNIを使​​用してJava呼び出しを行っています。

jni_CreateJavaVM を使用して JVM を作成します。これは次の場合に正常に機能します。

  • IIS (ウィンドウズ)
  • アパッチ (Windows)
  • PHP CLI (フェドラ 8)

しかし、(Fedore 8 で) Apache から同じ拡張機能をロードしようとすると、create jni_ CreateJavaVM が JNI _ERROR を返します。PHP _RINIT _FUNCTION から jni _CreateJavaVM を呼び出します。

私の拡張機能がlibjvm.soを見つけられない可能性があると思いました。同じコードで、jni_CreateJavaVM を呼び出す前に、libjvm.so ライブラリをロードしようとしましたが、成功しました。jni 関数を呼び出した場合にのみ、JNI_ERROR が返されます。

LD_LOAD 関数を使用して libjvm.so をロードしました。ライブラリをロードした後、成功した jni_ CreateJavaVM メソッドへのポインタを取得します。ポインターまたは直接の jni_ CreateJavaVM 呼び出しを使用して呼び出しを行った場合にのみ、-1 が返されます。

初期化中に何が問題だったのかを調べる方法はありますか?

プラットフォーム: Fedora 8 Java: Jdk 1.5 update 8 Php: Php バージョン 5.3

JVM を初期化するために作成したコードを次に示します。

typedef jint (JNICALL CreateJavaVM_t)(JavaVM **pvm, void **env, void *args);
typedef jint (JNICALL* GetDefaultJavaVMInitArgs_t)(void*);

CreateJavaVM_t *CreateJavaVM;
GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs;
JavaVM* jvm;
JNIEnv* env;

void create_vm(void)
{       
    JavaVMOption vm_options;
    JavaVMInitArgs vm_args;
    int retval = 0;

    dl_handle = DL_LOAD("libjvm.so");       
    //The call is successful and I get the handle

    CreateJavaVM = (CreateJavaVM_t*)DL_FETCH_SYMBOL(dl_handle, "JNI_CreateJavaVM");
    //The call is successful and I get pointer to function

    GetDefaultJavaVMInitArgs = (GetDefaultJavaVMInitArgs_t)DL_FETCH_SYMBOL(dl_handle,"JNI_GetDefaultJavaVMInitArgs");
    //The call is successful and I get pointer to function

    vm_args.version = JNI_VERSION_1_4;
    vm_args.options = &vm_options;
    vm_args.nOptions = 0;
    vm_args.ignoreUnrecognized = JNI_FALSE;

(*GetDefaultJavaVMInitArgs)(&vm_args);

    retval = CreateJavaVM(&jvm, (void **)&env, &vm_args);
    //The retval is -1.

    //And if I do
    retval = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    //This also returns -1
}
4

1 に答える 1

0

この質問は 5 年前のものです。さまざまなプラットフォームでの関数 JNI_GetDefaultJavaVMINitArgs のステータスについて調べているときに、偶然見つけました。呼び出す必要のない関数のようで、一部のプラットフォームでは廃止される可能性さえあります。しかし、Oracle の現在のドキュメント(Java 1.7 および 1.8 用) を主な参考資料として使用すると、上記のコードに深刻なバグがあることは明らかです。JNI_GetDefaultJavaVMInitArgs を呼び出す前に、vm_args.version フィールドのみを設定する必要があります。他のすべてのフィールドは、JNI_GetDefaultJavaVMInitArgs を呼び出した後に設定する必要があります。

しかし、ほとんどのプラットフォームでは、おそらく JNI_GetDefaultJavaVMInitArgs への呼び出しを単純に削除できます。

于 2015-07-27T22:09:18.590 に答える