Is it possible to create a JVM from within a JNI method using the JNI API?
I've tried to do this using the JNI function "JNI_CreateJavaVM()", but it's not working (the function keeps returning a value less than zero).
Here is the basic code I'm using (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 */
Where USER_CLASSPATH contains the path to the classes I want to load. After the above code executes, res < 0, indicating that JNI_CreateJavaVM() failed. The code above is part of a native method written in C++ called from Java. Any ideas on how to get this to work?
Thanks.
The JNI framework lets a native method use Java objects in the same way that Java code uses these objects. A native method can create Java objects and then inspect and use these objects to perform its tasks. A native method can also inspect and use objects created by Java application code.
The Java Native Interface (JNI) establishes a well-defined and platform-independent interface between the two. Native code can be used together with Java in two distinct ways: as "native methods" in a running JVM and as the code that creates a JVM using the "Invocation API".
Introduction to Java Native Interface: Establishing a bridge between Java and C/C++ JNI (Java Native Interface) is a foreign function interface that allows code running on JVM to call (or be called by) native applications. Using JNI, one can call methods written in C/C++ or even access assembly language.
No, you can't. It's a documented restriction that you can only have one JVM at a time. The API is designed for the possibility of extension, but the extension has never happened.
If you are in a JNI method, then there is already one JVM, and one JVM per process is all you get.
I see what you mean: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4479303
The bug report says it's not possible to run multiple JVMs in the same address space. I have to say I'm a little surprised that JNI_CreateJavaVM() doesn't fork off a new JVM in a different address space.
Since JNI_CreateJavaVM() doesn't fork a new process itself, is it possible to manually fork off another JVM process from within a JNI method and subsequently use IPC to manage it? If so, what's the best way to do this? A literal fork()/exec() doesn't seem like a good idea because it would copy the entire (probably very large) address space of the JVM only to throw it away immediately afterward.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With