Search code examples
javacjava-native-interface

JNI Java From C Multiple Java Dependencies


I'm using JNI to call Java from C code. My Java project is dependent on many classes and external jars. I am confused how to package my java project so that it may be called within C.

To my understanding JNI uses a single class file, but if that class is dependent on many other classes, how would this work?


Solution

  • When you use Java from C (and not the other way round), you first start the JVM and then run some Java code. When you start the JVM, you can specify a classpath that would typically include several jar files each containing several Java class. It is by no means restricted to a single class file.

    Specifically note the optionString below:

    #include <jni.h>
    #include <stdio.h>
    
    int main() {
      JavaVM *vm;
      JNIEnv *env; 
      JavaVMInitArgs vm_args;
      JavaVMOption options[1];   
      options[0].optionString = "-Djava.class.path=./lib/jarfile1.jar;./lib/jarfile2.jar"; 
      vm_args.version = JNI_VERSION_1_2;
      vm_args.options = options;
      vm_args.nOptions = 1;
      vm_args.ignoreUnrecognized = 1;
      jstring jstr; 
      jobjectArray args; 
      jint res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args);
      if (res < 0) { 
        printf("Can't create Java VM\n"); 
        exit(1);
        } 
      jclass cls = env->FindClass("YourMainClass");
      if (cls == 0) { 
        printf("YourMainClass class not found\n"); 
        exit(1); 
        } 
      jmethodID mid = 
        env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); 
      if (mid == 0) { 
        printf("main() method not found\n"); 
        exit(1); 
        } 
      jstring argString = env->NewStringUTF(""); //empty arg list
      jobjectArray args = 
         env->NewObjectArray(1, env->FindClass("java/lang/String"), jstr); 
      if (args == 0) { 
        printf("Out of memory\n"); 
        exit(1); 
        } 
      env->CallStaticVoidMethod(cls, mid, args); 
      return 0;
    }