Sunday, February 06, 2011

JVM Launcher

Introduction
This article explains how can we create a Java Virtual Machine Launcher (like java.exe or javaw.exe). It explores how the Java Virtual Machine launches a Java application. It gives you more ideas on the JDK or JRE you are using. This launcher is very useful in Cygwin (Linux emulator) with Java Native Interface. This article assumes a basic understanding of JNI.

How to Create (Launch) JVM ?

The standard launcher command (java or javaw.exe) in JDK or JRE is no more than a simple C program linked with the Java Virtual Machine. The launcher parses the command line arguments, loads the virtual machine, and runs Java applications through the invocation interface.
Before going further, let us discuss some of the structures and functions used to create the JVM.

JavaVMInitArgs

The arguments to the Java Virtual Machine are defined in jni.h as follows:

typedef struct JavaVMInitArgs {
   /*JVM Version .It must be JNI_VERSION_1_2 or JNI_VERSION_1_4 or JVM will
   interpret pointer as a JDK1_1InitArgs*/
   jint version;
   /*number of JVM options*/
   jint nOptions;
   JavaVMOption *options;     /*see definition of JavaVMOption below*/
   /*JVM option status.
   if JNI_TRUE, ignore options VM does not understand
   otherwise return JNI_ERR if there are any unrecognized options*/
   jboolean ignoreUnrecognized;
} JavaVMInitArgs;

/*Definition of JavaVMOption*/
typedef struct JavaVMOption {
   char *optionString;     /*a string containing the argument*/
   /*extra info to the JVM.Not important.*/
   void *extraInfo;
} JavaVMOption;

JNI_CreateJavaVM

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. The second argument is a pointer to a JNIEnv pointer. A JNIEnv structure is the main workhorse for JNI programming. It roughly corresponds to a particular Java thread. The JNIEnv returned from JNI_CreateJavaVM(), thus, represents the VM's main thread. The third argument is a pointer to an arbitrary pointer, and consists of the VM arguments. Here is the example code that creates a virtual machine instance:

  JavaVMInitArgs vm_args;
 JavaVMOption options[4];
 /* disable JIT */
 options[0].optionString ="-Djava.compiler=NONE";
 /* user classes */
 options[1].optionString = "-Djava.class.path=c:\\myclasses";
 /* native lib path */
 options[2].optionString = "-Djava.library.path=c:\\mylibs";
 options[3].optionString = "-verbose:jni";  /* print JNI msgs */
 vm_args.version = JNI_VERSION_1_2;
 vm_args.options = options;
 vm_args.nOptions = 4;
 vm_args.ignoreUnrecognized = TRUE;
 //Pointer to the function JNI_CreateJavaVM
 typedef jint (JNICALL CreateJavaVM_t)(JavaVM **pvm, void **env, void *args);
 //Load the jvm DLL (the jvm !)
 HINSTANCE hinst = LoadLibrary("jvm.dll")

Read more: Codeproject