Creating a JVM from a C ProgramFirst, here's the completed C program for reference. Our program dispenses with niceties like error checking that you, of course, would like to do in your real programs: #include <stdio.h> #include <jni.h> JNIEnv* create_vm() { JavaVM* jvm; JNIEnv* env; JavaVMInitArgs args; JavaVMOption options[1]; /* There is a new JNI_VERSION_1_4, but it doesn't add anything for the purposes of our example. */ args.version = JNI_VERSION_1_2; args.nOptions = 1; options[0].optionString = "-Djava.class.path=c:\\projects\\local\\inonit\\classes"; args.options = options; args.ignoreUnrecognized = JNI_FALSE; JNI_CreateJavaVM(&jvm, (void **)&env, &args); return env; } void invoke_class(JNIEnv* env) { jclass helloWorldClass; jmethodID mainMethod; jobjectArray applicationArgs; jstring applicationArg0; helloWorldClass = (*env)->FindClass(env, "example/jni/InvocationHelloWorld"); mainMethod = (*env)->GetStaticMethodID(env, helloWorldClass, "main", "([Ljava/lang/String;)V"); applicationArgs = (*env)->NewObjectArray(env, 1, (*env)->FindClass(env, "java/lang/String"), NULL); applicationArg0 = (*env)->NewStringUTF(env, "From-C-program"); (*env)->SetObjectArrayElement(env, applicationArgs, 0, applicationArg0); (*env)->CallStaticVoidMethod(env, helloWorldClass, mainMethod, applicationArgs); } int main(int argc, char **argv) { JNIEnv* env = create_vm(); invoke_class( env ); }
In this section, we're going to look at the
The function's main task is to invoke the jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args);The first argument is a pointer to a JavaVM pointer. The JavaVM structure can be used to
attach and detach native threads to/from the virtual machine, and (sort of) to destroy the VM (destroying a VM is
not supported as of JDK 1.4. The DestroyJavaVM call simply waits until all user threads besides the
current thread die, and then returns an error code). Our program (somewhat unrealistically) discards the JavaVM
pointer when create_vm() returns; one would normally want to provide access to it so that the
attach/detach/destroy functionality was available to the C program.
The second argument is a pointer to a
The third argument is a pointer to an arbitrary pointer, and consists of the VM arguments. In JDK 1.1, there was
a structure ( typedef struct JavaVMInitArgs { jint version; // must be JNI_VERSION_1_2 or JNI_VERSION_1_4 or JVM will // interpret pointer as a JDK1_1InitArgs jint nOptions; // number of options JavaVMOption *options; // see definition of JavaVMOption below jboolean ignoreUnrecognized; // if JNI_TRUE, ignore options VM does not understand; // otherwise return JNI_ERR if there are any unrecognized options } JavaVMInitArgs; typedef struct JavaVMOption { char *optionString; // a string containing the argument void *extraInfo; // not important except for esoteric options // (e.g., providing alternative exit() hook) } JavaVMOption;
We create a
Our
After creating the VM, we return the |