2010-02-14 15 views
7

È possibile creare una JVM da un metodo JNI utilizzando l'API JNI?creazione di una JVM da un metodo JNI

Ho provato a farlo utilizzando la funzione JNI "JNI_CreateJavaVM()", ma non funziona (la funzione continua a restituire un valore inferiore a zero).

Ecco il codice di base che sto utilizzando (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 */ 

Dove USER_CLASSPATH contiene il percorso per le classi che voglio caricare. Dopo aver eseguito il codice sopra riportato, res < 0, indicando che JNI_CreateJavaVM() non è riuscito. Il codice sopra fa parte di un metodo nativo scritto in C++ chiamato da Java. Qualche idea su come farlo funzionare?

Grazie.

+0

È definito 'PATH_SEPARATOR'? – trashgod

+0

Stavo per chiedere se è possibile avere funzioni 'JNIEXPORT' in un'applicazione C++ che invoca una JVM, e penso che questa domanda risponda al mio (no). – StockB

risposta

5

No, non è possibile. È una limitazione documentata che puoi avere solo una JVM alla volta. L'API è progettata per la possibilità di estensione, ma l'estensione non è mai avvenuta.

Se si utilizza un metodo JNI, esiste già una JVM e una sola JVM per processo è tutto ciò che si ottiene.

+0

Perché dici che ha molte JVM alla volta. C'è un #if. Ne inizia solo uno a seconda della versione JDK –

+3

Se è * già in un metodo JNI *, allora ha una JVM e sta tentando di crearne una seconda. – bmargulies

+0

OK, ho saltato il fatto che stava chiamando C++ da Java, anche se il processo principale era C++, cioè quando si utilizza JNI_CreateJavaVM() –

1

vedo quello che vuoi dire: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4479303

Il bug report dice che non è possibile eseguire più JVM nello stesso spazio di indirizzi. Devo dire che sono un po 'sorpreso dal fatto che JNI_CreateJavaVM() non stacchi una nuova JVM in uno spazio indirizzo diverso.

Poiché JNI_CreateJavaVM() non esegue il fork di un nuovo processo stesso, è possibile distribuire manualmente un altro processo JVM da un metodo JNI e successivamente utilizzare IPC per gestirlo? Se è così, qual è il modo migliore per farlo? Un fork letterale()/exec() non sembra una buona idea perché copierebbe l'intero spazio di indirizzo (probabilmente molto grande) della JVM solo per buttarlo via subito dopo.

+0

Interessante. Voglio provarlo solo per il gusto di farlo. :) – Tom

Problemi correlati