Click here to Skip to main content
Click here to Skip to main content

JVM Launcher

, 2 Feb 2007
Rate this:
Please Sign up or sign in to vote.
An article on creating a 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")

  //Get the address of the function
  CreateJavaVM_t *pfnCreateJavaVM = GetProcAddress(hinst, "JNI_CreateJavaVM");

  //Create JVM
  Int iRetval = pfnCreateJavaVM((&vm, (void **)&env,
                 &vm_args);

  //Error handling.
  if (res < 0) {
        ... /* error occurred
}

Invoking the Class

To launch any Java program, first we have to find out the class we specified and then we can call the main method of that class. We can pass arguments also to the Java program we are launching. The following piece of code illustrates this:

//Find the class
jclass    jcJclass = psJNIEnv->FindClass(mainClassName);

//Find the main method id
jmethodID jmMainMethod = 
    psJNIEnv-> GetStaticMethodID(jcJclass, "main", "([Ljava/lang/String;)V");

//Call the main method.
psJNIEnv->CallStaticVoidMethod(jcJclass, jmMainMethod, joApplicationArgs);

Where Can I Use this Launcher?

Have you ever tried to load the libraries which are compiled under cygwin from Java? You can see that your application hangs during System.loadLibrary(). The problem is, the library built under cygwin depends on cygwin1.dll. If there's no other cygwin-using process running, then dynamically loading a DLL which depends (at load-time) on cygwin causes the process to deadlock. So we need a cygwin process to launch the JVM.

About Cygwin

Cygwin is a Linux-like environment for Windows. It consists of two parts:

  1. A DLL (cygwin1.dll) which acts as a Linux API emulation layer providing substantial Linux API functionality.
  2. A collection of tools which provide Linux look and feel. Using Cygwin, programs written for compilation under Linux can often be cross-compiled for Win32 with minimal changes. It also helps to work in Windows with the Linux libraries.

Using the Code

The code for this launcher is written mainly to work with eclipse. Now it handles only basic JVM arguments.

How to Compile the Code

->Open a cygwin shell ->Run the compiler. (g++ cvm.cpp -o javaw)

How to Use the Launcher

  • Copy the javaw.exe to the bin directory of the JRE you are using. (Make a copy of your original javaw.exe).
  • Make sure that you are using the correct JRE under eclipse.
  • Start eclipse from the cygwin shell. It may not start, if you type eclipse, because the PATH may not set. You can set the path by:

    export PATH=/cygdrive/c/tools/eclipse3.2/:$PATH
  • Now it may not load your JNI library because the PATH may not be set. Close eclipse, set the path by using the export command e.g.:

    export PATH=/cygdrive/c/tutorial/jni_libs/:$PATH
  • Start eclipse from the same shell where you set the path.

Note: This launcher may not work with all JRE/JDK versions, because, the arguments to the JVM differ from version to version. I tested with j2re1.4.2_06 and it works.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

jafarmlp
Software Developer (Senior)
India India
Jafar is working in software field for the last five years. He is from Moonniyoor, a village of north Kerala,India.
Visit Jafar's home page http://jafarmlp.googlepages.com/

Comments and Discussions

 
Questionthanks PinmemberMember 866479622-Feb-12 2:10 
AnswerRe: thanks Pinmemberjafarmlp22-Feb-12 20:19 
QuestionHow can I close JVM once DLL completes an operation. Pinmemberaditya_a_a6-Nov-08 23:53 
AnswerRe: How can I close JVM once DLL completes an operation. Pinmemberdentak28-Nov-08 8:05 
AnswerRe: How can I close JVM once DLL completes an operation. Pinmemberweird.dreams10-Oct-11 23:54 
QuestionJNI_CreateJavaVM gives me -1 always. which jvm.dll ishould use for windows? PinmemberGeckops11-Dec-07 1:12 
AnswerRe: JNI_CreateJavaVM gives me -1 always. which jvm.dll ishould use for windows? Pinmemberjafarmlp12-Apr-08 10:51 
GeneralRe: JNI_CreateJavaVM gives me -1 always. which jvm.dll ishould use for windows? Pinmembermariahayek5-May-08 11:50 
GeneralRe: JNI_CreateJavaVM gives me -1 always. which jvm.dll ishould use for windows? Pinmemberaditya_a_a5-Nov-08 18:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140827.1 | Last Updated 2 Feb 2007
Article Copyright 2007 by jafarmlp
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid