1

I have a file.c in my project which has #include <jni.h> header file. What is the process to include this header file in project or macOS?

Aleksey Potapov
  • 3,683
  • 5
  • 42
  • 65
karthi
  • 49
  • 4
  • Does [this](https://stackoverflow.com/a/20783713/1040347) answer your question? – Aleksey Potapov Dec 26 '19 at 12:30
  • @AlekseyPotapov i found location of header file in system folder.but i am struggling to connect that header file with xCode – karthi Dec 26 '19 at 12:42
  • In Xcode open Build Settings and check the `header search paths`, there should be the path to your library. [This might](https://stackoverflow.com/a/3428303/1040347) answer your question – Aleksey Potapov Dec 26 '19 at 13:09
  • 1
    @ AlekseyPotapov your suggestion helped me to fix the issue – karthi Dec 26 '19 at 14:28
  • Does this answer your question? [Adding system header search path to Xcode](https://stackoverflow.com/questions/3428216/adding-system-header-search-path-to-xcode) – Aleksey Potapov Dec 26 '19 at 14:57
  • Moderation: I just marked the question as duplicate. – Aleksey Potapov Dec 26 '19 at 14:58
  • Does this answer your question? [how to make jni.h be found?](https://stackoverflow.com/questions/14529720/how-to-make-jni-h-be-found) – Asperi Dec 27 '19 at 09:28

1 Answers1

2

Let's say you have following code

#include "jni.h"
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        JNIEnv *env;
        JavaVM *jvm;
        JavaVMInitArgs vm_args;
        JavaVMOption options[3];

        options[0].optionString = "-Djava.class.path=_HERE_GOES_LOCATION_OF_JNICOOKBOK_/jnicookbook/recipeNo051/target";

        vm_args.options = options;
        vm_args.ignoreUnrecognized = 0;
        vm_args.version = JNI_VERSION_1_8;
        vm_args.nOptions = 1;           

        int status = JNI_CreateJavaVM (&jvm, (void **) &env, &vm_args);
        if (status < 0 || !env) {
          printf ("Error - JVM creation failed\n");
          return 1;
        }

        jclass cls_Main = (*env)->FindClass (env, "recipeNo051/Main");

        jmethodID method_displayMessage = (*env)->GetStaticMethodID (env, cls_Main, "displayMessage", "()V");
        (*env)->CallStaticVoidMethod(env, cls_Main, method_displayMessage);

        (*jvm)->DestroyJavaVM( jvm );
    }

    return 0;
}

in order to run it you will need

  • location of libjvm.dylib
  • location of headers
  • location of compiled Java classes that are called from main.m

Let's start with libs and headers. You have to make sure that following paths are searched for includes (note that I am using jdk-11.0.4):

/Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home/include
/Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home/include/darwin/

You have to make sure that following path is added to Library Search Path and to Runpath Search Paths

/Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home/lib/server

You should have settings like that:

enter image description here

Make sure you are linking your code with libjvm.dylib. Add it inside Build Phases

enter image description here

where you can specify it's location by choosing Add Other...

enter image description here

Run your code, but! Make sure to ignore SIGSEGV before calling method JNI_CreateJavaVM. You can ignore it inside lldb console

(lldb) process handle --pass true --stop false SIGSEGV

enter image description here

After you continue, you can see your JVM instance calling classes from the recipeNo051.

enter image description here

Source code of class: recipeNo051/Main can be found here: https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo051

Update

Oo.oO
  • 12,464
  • 3
  • 23
  • 45