2010-02-14 9 views
7

Est-il possible de créer une JVM à partir d'une méthode JNI à l'aide de l'API JNI?Création d'une JVM à partir d'une méthode JNI

J'ai essayé de le faire en utilisant la fonction JNI "JNI_CreateJavaVM()", mais cela ne fonctionne pas (la fonction continue à renvoyer une valeur inférieure à zéro).

Voici le code de base que je utilise (C++):

JNIEnv *env; 
JavaVM *jvm; 
jint res; 

#ifdef JNI_VERSION_1_2 
JavaVMInitArgs vm_args; 
JavaVMOption options[2]; 
options[0].optionString = 
    "-Djava.class.path=" USER_CLASSPATH; 
options[1].optionString = "-verbose:jni"; 
vm_args.version = JNI_VERSION_1_2; 
vm_args.options = options; 
vm_args.nOptions = 2; 
vm_args.ignoreUnrecognized = JNI_TRUE; 
/* Create the Java VM */ 
res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); 

#else 

JDK1_1InitArgs vm_args; 
char classpath[1024]; 
vm_args.version = 0x00010001; 
JNI_GetDefaultJavaVMInitArgs(&vm_args); 
/* Append USER_CLASSPATH to the default system class path */ 
sprintf(classpath, "%s%c%s", 
     vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH); 
vm_args.classpath = classpath; 
/* Create the Java VM */ 
res = JNI_CreateJavaVM(&jvm, &env, &vm_args); 

#endif /* JNI_VERSION_1_2 */ 

Où USER_CLASSPATH contient le chemin des classes que je veux charger. Après l'exécution du code ci-dessus, res < 0, indiquant que JNI_CreateJavaVM() a échoué. Le code ci-dessus fait partie d'une méthode native écrite en C++ appelée depuis Java. Des idées sur comment faire fonctionner ça?

Merci.

+0

Est-ce que 'PATH_SEPARATOR' est défini? – trashgod

+0

J'allais demander à SO s'il est possible d'avoir des fonctions 'JNIEXPORT' dans une application C++ qui appelle une machine virtuelle Java, et je pense que cette question répond à la mienne (non). – StockB

Répondre

5

Non, vous ne pouvez pas. C'est une restriction documentée que vous ne pouvez avoir qu'une JVM à la fois. L'API est conçue pour la possibilité d'extension, mais l'extension n'a jamais eu lieu.

Si vous utilisez une méthode JNI, alors il y a déjà une machine virtuelle Java et une seule machine virtuelle par processus est tout ce que vous obtenez.

+0

Pourquoi dites-vous qu'il a beaucoup de JVM à la fois. Il y a un #if. Il n'en démarre qu'un en fonction de la version du JDK –

+3

S'il est * déjà dans une méthode JNI *, il a une JVM et tente d'en créer une seconde. – bmargulies

+0

OK, j'ai sauté le fait qu'il appelait C++ de Java, je pensais que le processus principal était C++, c'est quand vous utilisez JNI_CreateJavaVM() –

1

Je vois ce que vous entendez: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4479303

Le rapport de bogue dit qu'il est impossible d'exécuter plusieurs JVMs dans le même espace d'adressage. Je dois dire que je suis un peu surpris que JNI_CreateJavaVM() ne bifurque pas une nouvelle JVM dans un espace d'adressage différent.

Étant donné que JNI_CreateJavaVM() ne structure pas lui-même un nouveau processus, est-il possible de séparer manuellement un autre processus JVM d'une méthode JNI et de l'utiliser ensuite pour le gérer? Si oui, quelle est la meilleure façon de le faire? Un fork()/exec() littéral ne semble pas être une bonne idée car il copierait l'espace d'adressage entier (probablement très grand) de la JVM uniquement pour le jeter immédiatement après.

+0

Intéressant. Je veux juste essayer ça juste pour le plaisir. :) – Tom

Questions connexes