2010-02-14 12 views
7

Czy można utworzyć wirtualną maszynę JVM z poziomu metody JNI za pomocą interfejsu API JNI?tworzenie JVM z metody JNI

Próbowałem to zrobić za pomocą funkcji JNI "JNI_CreateJavaVM()", ale nie działa (funkcja zwraca wartość mniejszą od zera).

Oto kod podstawowy używam (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 */ 

Gdzie USER_CLASSPATH zawiera ścieżkę do klas I chcą, aby załadować. Po wykonaniu powyższego kodu, res < 0, wskazuje, że JNI_CreateJavaVM() nie powiodło się. Powyższy kod jest częścią natywnej metody napisanej w języku C++ wywoływanej z języka Java. Wszelkie pomysły, jak to zrobić?

Dzięki.

+0

Czy zdefiniowano "PATH_SEPARATOR"? – trashgod

+0

Zamierzałem zapytać SO, czy możliwe jest posiadanie funkcji 'JNIEXPORT' w aplikacji C++, która wywołuje maszynę JVM, i myślę, że to pytanie odpowiada na moje pytanie (nie). – StockB

Odpowiedz

5

Nie, nie możesz. To udokumentowane ograniczenie, że możesz mieć tylko jedną JVM naraz. Interfejs API został zaprojektowany z myślą o możliwości rozszerzenia, ale rozszerzenie nigdy nie miało miejsca.

W przypadku metody JNI istnieje już jedna JVM, a jedna JVM na proces to wszystko, co można uzyskać.

+0

Dlaczego mówisz, że ma on wiele JVM naraz. Istnieje #if. Zaczyna tylko jeden w zależności od wersji JDK –

+3

Jeśli jest * już w metodzie JNI *, to ma jedną maszynę JVM i próbuje utworzyć drugą. – bmargulies

+0

OK, pominąłem fakt, że wywoływał C++ z Javy, chociaż głównym procesem było C++, to jest kiedy używasz JNI_CreateJavaVM() –

1

Rozumiem co masz na myśli: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4479303

raportu o błędzie mówi, że nie jest możliwe uruchamianie wielu JVMs w tej samej przestrzeni adresowej. Muszę powiedzieć, że jestem trochę zaskoczony, że JNI_CreateJavaVM() nie otwiera nowej maszyny JVM w innej przestrzeni adresowej.

Skoro JNI_CreateJavaVM() nie rozwiąże nowego procesu, czy możliwe jest ręczne rozwidlenie innego procesu JVM z poziomu metody JNI, a następnie użycie IPC do zarządzania nim? Jeśli tak, jaki jest najlepszy sposób na zrobienie tego? Dosłowne fork()/exec() nie wydaje się dobrym pomysłem, ponieważ skopiowałoby to całą (prawdopodobnie bardzo dużą) przestrzeń adresową maszyny JVM tylko po to, by ją natychmiast wyrzucić.

+0

Interesujące. W pewnym sensie chcę to wypróbować właśnie dla tego. :) – Tom