Tuesday, June 11, 2013

Call Java method from C code (JNI-Java Native Interface)

Problem Statement

 


  • Call a Static Java method from C code.
  • Java method prints Hello World.

Environment

  • Java SDK 1.7.0
  • Visual studio 10.0 as C compiler.
  •  Set environment variable (path) for jvm.dll .This file is usually present at "C:\Program Files\Java\jdk1.6.0_32\jre\bin\server". Modify this path as per your java installation location.

 Steps to be followed

 

  1. Write the java class , in our case TestClass.java .
  2. Compile this java class.
  3. Write C-code that invokes this method, in our case TestClass.c.
  4. Compile this C-code as TestClass.exe.
  5. Run this TestClass.exe 

 

Step 1: Write TestClass.java


public class TestClass {
    public static void printHello(){
        System.out.println("Hello World");
    }
}

Step 2: Compile TestClass.java

Run javac testClass.java in command line. This generates TestClass.class file.

Step 3: Write C-code which invokes a Java method (TestClass.c)

  
#include <jni.h>
#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else
#define PATH_SEPARATOR ':'
#endif

 int main()
 {
   JavaVMOption options[1];
   JNIEnv *env;
   JavaVM *jvm;
   JavaVMInitArgs vm_args;
   long status;
   jclass cls;
   jmethodID mid;
   jint square;
   jboolean not;

   options[0].optionString = "-Djava.class.path=.";
   memset(&vm_args, 0, sizeof(vm_args));
   vm_args.version = JNI_VERSION_1_6;
   vm_args.nOptions = 1;
   vm_args.options = options;
   status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

   if (status != JNI_ERR)
   {    
     cls = (*env)->FindClass(env, "TestClass");    
     if(cls !=0)
     {      
       mid = (*env)->GetStaticMethodID(env,cls,"printHello","()V");
      
       if(mid !=0)
       {
        (*env)->CallStaticIntMethod(env, cls, mid, 5);              
       }     
     }
     (*jvm)->DestroyJavaVM(jvm);
     return 0;
   }
   else
   return -1;
 }


Step 4: Compile this C-code

 

  • Type vcvars32.bat in the command line to set environment for visual studio.

  • Type cl -I"C:\Program Files\Java\jdk1.6.0_32\include" -I"C:\Program Files\Java\jdk1.6.0_32\include\win32" TestClass.c -link "C:\Program Files\Java\jdk1.6.0_32\lib\jvm.lib". Modify as per java installation. This generates the TestClass.exe file.

Step 5: Run this EXE 

 

run TestClass in the command line. If everything is set as instructed then following output appears.


Note :

In  JNI function GetStaticMethodID, method signature is required. In our case signature is ()V. This signature tells the compiler about arguments and return type. Though this signature can be manually generated but to avoid any error Java sdk provides javap tool. To generate the signature type javap -s -p TestClass . This generates signatures for all the methods in our java class.




This output shows that in TestClass we have one method which is printHello and whose JNI signature is ()V.