Действительно ли возможно создать JVM из метода JNI с помощью API JNI?
Я попытался сделать это использование функции JNI "JNI_CreateJavaVM ()", но это не работает (функция продолжает возвращать значение меньше, чем нуль).
Вот абсолютный код, который я использую (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 */
Где USER_CLASSPATH содержит путь к классам, я хочу загрузиться. После того, как вышеупомянутый код выполняется, res <0, указывая, что JNI_CreateJavaVM () перестал работать. Код выше является частью собственного метода, записанного в C++, названном от Java. Какие-либо идеи о том, как заставить это работать?
Спасибо.
Я понимаю, что вы имеете в виду: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id= 4479303
В отчете об ошибке говорится, что невозможно запустить несколько JVM в одном адресном пространстве. Должен сказать, я немного удивлен, что JNI_CreateJavaVM () не отключает новую JVM в другом адресном пространстве.
Поскольку JNI_CreateJavaVM () сам по себе не разветвляет новый процесс, возможно ли вручную разделить другой процесс JVM из метода JNI и впоследствии использовать IPC для управления им? Если да, то как лучше всего это сделать? Буквальный fork () / exec () не кажется хорошей идеей, потому что он копирует все (возможно, очень большое) адресное пространство JVM только для того, чтобы сразу же выбросить его.
Нет, не можете. Это задокументированное ограничение, согласно которому вы можете иметь только одну JVM одновременно. API рассчитан на возможность расширения, но расширения никогда не было.
Если вы работаете с методом JNI, то уже существует одна JVM, и все, что у вас есть, - это одна JVM на процесс.