2010-02-14 44 views
7

是否可以使用JNI API在JNI方法内创建JVM?我试过使用JNI函数“JNI_CreateJavaVM()”来做到这一点,但它不工作(函数保持返回小于零的值)。从JNI方法中创建JVM

这里是我使用的基本代码(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()失败。上面的代码是用Java编写的用C++编写的本地方法的一部分。任何想法如何让这个工作?

谢谢。

+0

定义了“PATH_SEPARATOR”吗? – trashgod 2010-02-14 03:18:10

+0

我要问的是,如果可以在调用JVM的C++应用程序中有'JNIEXPORT'函数,并且我认为这个问题回答了我的问题(否)。 – StockB 2013-01-18 18:18:32

回答

5

不,你不能。这是一个有记录的限制,一次只能有一个JVM。该API旨在扩展的可能性,但扩展从未发生过。

如果您使用的是JNI方法,那么已经有一个JVM,每个进程只有一个JVM。

+0

你为什么说他一次有很多JVM?有一个#if。根据JDK版本,他只启动一个 – 2011-06-14 08:50:11

+3

如果他已经在JNI方法中,那么他有一个JVM,并且正在尝试创建第二个JVM。 – bmargulies 2011-06-14 10:43:17

+0

好吧,我跳过了他从Java调用C++的事实,虽然主进程是C++,那就是当您使用JNI_CreateJavaVM() – 2011-06-26 20:18:23

1

我明白你的意思: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4479303

bug报告说,这是不可能在同一个地址空间中运行多个JVM。我不得不说,我有点惊讶,JNI_CreateJavaVM()没有在不同的地址空间中分离出一个新的JVM。

由于JNI_CreateJavaVM()不会自动分叉新进程,是否可以从JNI方法中手动切断另一个JVM进程并随后使用IPC进行管理?如果是这样,那么做到这一点的最好方法是什么?字面fork()/ exec()似乎不是一个好主意,因为它会复制JVM的整个(可能非常大的)地址空间,然后立即将其扔掉。

+0

有趣。我有点想试试这个,只是为了它。 :) – Tom 2010-02-14 18:04:03