2009-09-29 9 views
0

J'ai créé une extension PHP (écrite en C). J'utilise JNI pour faire des appels Java. J'utilise jni_CreateJavaVM pour créer une JVM. Cela fonctionne très bien dans:Impossible de créer une JVM à l'aide de l'API jni_CreateJavaVM dans Fedora 8

  • IIS (windows)
  • Apache (fenêtres)
  • CLI PHP (Fedora 8)

Mais lorsque je tente de charger la même extension d'Apache (en Fedore 8), le create jni_ CreateJavaVM retourne JNI _ERROR. J'appelle jni _CreateJavaVM de PHP _RINIT _FUNCTION.

Je pense qu'il se peut que mon extension ne puisse pas libérer libjvm.so. Donc, dans le même code, avant d'appeler jni_ CreateJavaVM, j'ai essayé de charger la librairie libjvm.so, et cela a réussi. Seulement quand j'appelle la fonction jni, elle renvoie JNI_ERROR.

J'ai utilisé la fonction LD_LOAD pour charger libjvm.so. Après avoir chargé la bibliothèque, j'obtiens un pointeur vers la méthode jni_ CreateJavaVM qui a réussi. Seulement quand je fais un appel, en utilisant le pointeur ou l'appel direct jni_ CreateJavaVM, il renvoie -1.

Existe-t-il un moyen de savoir ce qui s'est passé lors de l'initialisation?

platfrom: Fedora 8 Java: JDK 1.5 update 8 Php: Version 5.3 Php

Voici le code que je l'ai écrit pour initialiser 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

Comment avez-vous essayé de charger libjvm.so? en utilisant un chemin absolu? Ou juste le nom du fichier et il a ramassé de la variable d'environnement PATH? – vpram86

+0

J'ai créé un lien symbolique de libjvm.so dans usr/lib. J'ai passé seulement le nom de fichier. – ata

+0

Avez-vous essayé de placer le chemin vers libjvm.so à l'intérieur de la structure JRE originale dans LD_LIBRARY_PATH au lieu d'un lien symbolique. jvm utilise le chemin relatif à partir de son emplacement actuel pour trouver d'autres fichiers requis. Atleast dans les fenêtres, il attend! Ça vaut le coup d'essayer. – vpram86

Répondre

0

Cette question a cinq ans. Je suis tombé dessus en faisant des recherches sur l'état de la fonction JNI_GetDefaultJavaVMInitArgs sur différentes plates-formes. Cela semble être une fonction inutile à appeler et peut même être déconseillée sur certaines plateformes. Mais en utilisant le current documentation from Oracle (pour Java 1.7 et 1.8) comme référence principale, il est clair que le code ci-dessus a un bug sérieux. Seul le champ vm_args.version doit être défini avant l'appel à JNI_GetDefaultJavaVMInitArgs. Tous les autres champs doivent être définis après l'appel de JNI_GetDefaultJavaVMInitArgs. Mais sur la plupart des plates-formes, vous pouvez probablement supprimer l'appel de JNI_GetDefaultJavaVMInitArgs.

Questions connexes