2010-02-14 10 views
7

¿Es posible crear una JVM desde dentro de un método JNI usando la API JNI?creando una JVM desde dentro de un método JNI

He intentado hacer esto usando la función JNI "JNI_CreateJavaVM()", pero no está funcionando (la función sigue devolviendo un valor menor que cero).

Aquí es el código básico que estoy usando (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 */ 

Dónde USER_CLASSPATH contiene la ruta a las clases que desea cargar. Después de que se ejecuta el código anterior, res < 0, lo que indica que JNI_CreateJavaVM() falló. El código anterior es parte de un método nativo escrito en C++ llamado desde Java. ¿Alguna idea sobre cómo hacer que esto funcione?

Gracias.

+0

¿Se define 'PATH_SEPARATOR'? – trashgod

+0

Iba a preguntar SO si es posible tener funciones 'JNIEXPORT' en una aplicación C++ que invoca una JVM, y creo que esta pregunta responde a la mía (no). – StockB

Respuesta

5

No, no puedes. Es una restricción documentada que solo puede tener una JVM a la vez. La API está diseñada para la posibilidad de extensión, pero la extensión nunca ha sucedido.

Si está en un método JNI, entonces ya hay una JVM, y una JVM por proceso es todo lo que obtiene.

+0

¿Por qué dices que tiene muchas JVM a la vez? Hay un #if. Solo inicia uno dependiendo de la versión JDK –

+3

Si ya está * en un método JNI *, entonces tiene una JVM y está intentando crear una segunda. – bmargulies

+0

OK, me salté el hecho de que llamaba a C++ desde Java, aunque el proceso principal era C++, ahí es cuando utilizas JNI_CreateJavaVM() –

1

veo lo que quiere decir: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4479303

El informe de error dice que no es posible ejecutar varias JVM en el mismo espacio de direcciones. Debo decir que estoy un poco sorprendido de que JNI_CreateJavaVM() no bifurque una nueva JVM en un espacio de direcciones diferente.

Dado que JNI_CreateJavaVM() no bifurca un nuevo proceso en sí mismo, ¿es posible dividir manualmente otro proceso JVM desde un método JNI y posteriormente usar IPC para administrarlo? Si es así, ¿cuál es la mejor manera de hacer esto? Un literal fork()/exec() no parece una buena idea porque copiaría todo el espacio de direcciones (probablemente muy grande) de la JVM solo para descartarla inmediatamente después.

+0

Interesante. De alguna manera quiero probar esto solo por el gusto de hacerlo. :) – Tom

Cuestiones relacionadas