2009-09-29 3 views
0

PHP 확장을 만들었습니다 (C로 작성). Java 호출을 만들기 위해 JNI를 사용하고 있습니다.Fedora 8에서 jni_CreateJavaVM API를 사용하여 JVM을 만들 수 없습니다.

jni_CreateJavaVM을 사용하여 JVM을 만듭니다. 이에서 잘 작동 :

  • IIS (창)
  • 아파치 (창)
  • PHP CLI (페도라 8)

그러나이 난에 (아파치에서 같은 확장을로드 할 때 Fedore 8), jni_ CreateJavaVM을 작성하면 JNI _ERROR가 리턴됩니다. PHP _RINIT _FUNCTION에서 jni _CreateJavaVM을 호출합니다.

내 확장 프로그램이 libjvm.so를 loacate 할 수는 없지만. 따라서 동일한 코드에서 jni_ CreateJavaVM을 호출하기 전에 libjvm.so 라이브러리를로드하려고 시도했지만 성공했습니다. jni 함수를 호출 할 때만 JNI_ERROR를 반환합니다.

libjvm.so를로드하기 위해 LD_ LOAD 함수를 사용했습니다. 라이브러리를로드 한 후 jni_ CreateJavaVM 메소드에 대한 포인터를 얻습니다. 이는 성공적입니다. 포인터를 사용하거나 jni_ CreateJavaVM 호출을 호출 할 때만 -1을 리턴합니다.

초기화 중에 무엇이 잘못되었는지 알아낼 방법이 있습니까?

Platfrom : 페도라 8 자바 : JDK 1.5 업데이트를 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 
} 
+0

libjvm.so를 어떻게로드하려고 시도 했습니까? 절대 경로를 사용하여? 또는 파일 이름과 PATH env 변수에서 선택 했습니까? – vpram86

+0

usr/lib에 libjvm.so의 소프트 링크를 만들었습니다. 파일 이름 만 전달했습니다. – ata

+0

심볼릭 링크 대신 LD_LIBRARY_PATH의 원래 JRE 구조 안에 libjvm.so 경로를 넣으려고 했습니까? jvm은 실제 위치에서 상대 경로를 사용하여 필요한 다른 파일을 찾습니다. 창문에서 상상해보십시오! 한번 시도해 볼 가치가 있습니다. – vpram86

답변

0

이 질문은 5 살입니다. 다른 플랫폼에서 JNI_GetDefaultJavaVMInitArgs 함수의 상태에 대해 조사하면서 우연히 발견했습니다. 그것은 불필요한 기능이며, 일부 플랫폼에서는 더 이상 사용되지 않을 수도 있습니다. 그러나 기본 참조로 current documentation from Oracle (Java 1.7 및 1.8)을 사용하면 위의 코드에 심각한 버그가 있음을 알 수 있습니다. JNI_GetDefaultJavaVMInitArgs를 호출하기 전에 vm_args.version 필드 만 설정해야합니다. 다른 모든 필드는 JNI_GetDefaultJavaVMInitArgs를 호출 한 후 설정해야합니다.

하지만 대부분의 플랫폼에서는 JNI_GetDefaultJavaVMInitArgs에 대한 호출을 간단하게 제거 할 수 있습니다.

관련 문제