Embed Java VM in Executables using Java Native Interface (JNI)

Java Native Interface is a standard programming interface for writing Java native methods and embedding the Java virtual machine into native applications. The primary goal is binary compatibility of native method libraries across all Java virtual machine implementations on a given platform. We can embed java inside any application developed using C/C++ using Java Native Interface.

Here InvokeJVM.C which illustrates some calls in JNI. Please ensure that you are compiling in a multithreaded environment and with JDK117B or JDK12 Header files.

#include <jni.h>
#include <windows.h>

#define PATH_SEPARATOR ';' /* platform dependent */
#define USER_CLASSPATH "." /* directory where Sample.class is present */

typedef jint (*P_JNI_GetDefaultJavaVMInitArgs)(void *args);
typedef jint (*P_JNI_CreateJavaVM)(JavaVM **pvm, JNIEnv ** penv, void *args);

void __cdecl main(int argc, char **argv) {
    char classpath[1024];           /* Class Path */
    JNIEnv          *env = NULL;    /* Environment */
    JavaVM          *jvm = NULL;    /* Virtual Machine */
    JDK1_1InitArgs  vm_args;        /* Initializing arguments */
    jint            res = -1;
    jclass          cls;
    jmethodID       mid;
    jstring         jstr;
    jobjectArray    args;
    HANDLE          hLib = NULL; 

    /* Pointer to required functions */
    P_JNI_GetDefaultJavaVMInitArgs pfnGetDefaultJavaVMInitArgs = NULL;
    P_JNI_CreateJavaVM             pfnCreateJavaVM = NULL;

    if(argc < 3){
        printf("Usage : InvokeJVM <javai.dll> <Sample>\n");
        exit(-1);
    }

    /* Load the library */
    printf("Loading Library .... <%s>\n",argv[1]);
    hLib = LoadLibrary(argv[1]);

    if(hLib == NULL) {
        printf("Unable to Load Library.... exitting....");
        exit(-1);
    }

    /* Store the function pointer for getting default arguments */
    pfnGetDefaultJavaVMInitArgs = (P_JNI_GetDefaultJavaVMInitArgs) GetProcAddress(hLib, "JNI_GetDefaultJavaVMInitArgs");

    /* IMPORTANT: specify vm_args version # if you use JDK1.1.2 and beyond */
    vm_args.version = 0x00010001;

    /* Get the default arguments */
    if(pfnGetDefaultJavaVMInitArgs != NULL)
        (*pfnGetDefaultJavaVMInitArgs)(&vm_args);

    /* Append USER_CLASSPATH to the end of default system class path */
    if(vm_args.classpath != NULL)
        sprintf(classpath, "%s%c%s", vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH);
    else 
        sprintf(classpath, "%s", USER_CLASSPATH);
    
    vm_args.classpath = classpath;

    /* Store the function pointer for creating the VM */
    pfnCreateJavaVM = (P_JNI_CreateJavaVM) GetProcAddress(hLib, "JNI_CreateJavaVM");

    /* Create the Java VM */
    if(pfnCreateJavaVM != NULL)
        res = (*pfnCreateJavaVM)(&jvm,&env,&vm_args);
    if (res < 0) {
        fprintf(stderr, "Can't create Java VM\n");
        exit(1);
    }

    /* Find the class that we need to use */
    cls = (*env)->FindClass(env, argv[2]);
    if (cls == 0) {
        fprintf(stderr, "Can't find %s.class\n",argv[2]);
        exit(1);
    }
 
    /* get a id to the "main" method */
    mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
    if (mid == 0) {
        fprintf(stderr, "Can't find main function in %s.class\n",argv[2]);
        exit(1);
    }

    /* create a new string to pass as parameter */
    jstr = (*env)->NewStringUTF(env, "Hello World!!!");
    if (jstr == 0) {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }

    /* create a new array */
    args = (*env)->NewObjectArray(env, 1, (*env)->FindClass(env, "java/lang/String"), jstr);
    if (args == 0) {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }
    
    /* Ready to rock'n'roll */
    (*env)->CallStaticVoidMethod(env, cls, mid, args);

    /* All's well that ends well */
    (*jvm)->DestroyJavaVM(jvm);
}

Here is a Sample.java file which has a main() function.

import java.lang.*;
import java.io.*;

/* Sample Class does nothing. It just prints its arguments */
public class Sample
{
    static public void main (String argv[])
    {
        System.out.println(">>>> Java Version : " + System.getProperty("java.version"));
        System.out.println(">>>> Java Vendor  : " + System.getProperty("java.vendor"));
        System.out.println(">>>> Sample.class started successfully with " + argv.length + " argument(s)");
        for(int i=0;i<argv.length;i++)
           System.out.println(">>>> args ["+i+"] : " + argv[i]);
    }
}

Set the PATH, CLASSPATH as follows and then use InvokeJVM JDK12
SET PATH=D:\JDK1.2\BIN;D:\JDK1.2\JRE\BIN\CLASSIC; SET CLASSPATH=.; INVOKEJVM jvm Sample
JDK117B
SET PATH=D:\JDK1.1.7B\BIN; SET CLASSPATH=D:\JDK1.1.7B\LIB\CLASSES.ZIP;.; INVOKEJVM javai Sample
JDK116
SET PATH=D:\JDK1.1.6\BIN; SET CLASSPATH=D:\JDK1.1.6\LIB\CLASSES.ZIP;.; INVOKEJVM javai Sample
IE - If you have installed the latest Microsoft VM
SET PATH=C:\WINNT40\SYSTEM32; SET CLASSPATH=.; INVOKEJVM msjava Sample

Sample Output for JDK1.1.7B

Loading Library .... >>>> Java Version : 1.1.7B >>>> Java Vendor : Sun Microsystems Inc. >>>> Sample.class started successfully with 1 argument(s) >>>> args [0] : Hello World!!!
More Information
JDK 1.2 JNI - Java Native Interface Specification

JDK 1.1 JNI - Java Native Interface Specification

Download demo project - 9 KB

Date Last Updated: April 3, 1999



Comments

  • Unhandled win32 exception

    Posted by Legacy on 02/04/2004 12:00am

    Originally posted by: Hannne

    When I run the the prog with jvm I get unhandled win32 exception, and when I try with msjava it works, the problem is that it's spesified that I'm to use Sun's java vm.

    I use java2sdk 1.4.02 and visual studio 6 on win xp..

    Reply
  • I received "Can't create Java VM". Where is the problem?

    Posted by Legacy on 09/12/2000 12:00am

    Originally posted by: Alexi Jordanov

    Hi, I try to use your example but I'm receiving Can't create Java VM error. This is the way for executing :

    1) SET PATH=C:\JDK\1.2.2\BIN;C:\JDK\1.2.2\JRE\BIN\CLASSIC;%PATH%
    2) SET CLASSPATH=.;C:\JDK\1.2.2\lib\tools.jar;C:\JDK\1.2.2\jre\lib\rt.jar;
    3) SET JVMDLL=jvm
    4) INVOKEJVM %JVMDLL% Sample

    Where is then the problem?

    Best regards, Alex

    PS :
    C:\>java -version
    java version "1.2.2"
    Classic VM (build JDK-1.2.2-W, native threads, symcjit)

    Reply
  • TLS not working

    Posted by Legacy on 06/25/1999 12:00am

    Originally posted by: Ulrich Waibel

    Hi,

    if you are calling a function which resides in an other .dll or .lib and this function uses Thread loacal storage, it doesn't work with JDK 1.1.x and 1.2
    On sun's developer connection you will find a very short message about this.


    Regards Uli

    Reply
  • missing jni.h file

    Posted by Legacy on 05/18/1999 12:00am

    Originally posted by: bob

    I compiled it with vc++ 5.0. jni.h not included.
    I just like to know how to get it.
    thanks.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Wednesday, September 24, 2014 8:00 AM - 9:00 AM PDT According to a recent Forrester Research report, many companies are choosing low-code platforms over traditional programming platforms, due to the speed with which low-code apps can be assembled and tested. With customer-facing applications on the rise, traditional programming platforms simply can't keep up with the "short schedules and rapid change cycles" required to develop these applications. Check out this upcoming webinar and join Clay Richardson from …

  • Live Event Date: September 10, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild". This loop of continuous delivery and continuous feedback is …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds