0

I am learning graalvm, and I was wondering if it is possible that I can use JNI to call a java native-built shared library?

Let's say there are two Java source codes, the first would be compiled as a shared library ahead of time with graalvm, and the second one would be run on JVM, which would load the shared library generated by the first source code in runtime. I find this difficult in practice since the header files generated by JNI and graalvm native-build are different in their signature.

Is there any good way I can do this?

The two source codes and their generated header files are as follows:

LibEnvMap.java:

import org.graalvm.nativeimage.IsolateThread;
import org.graalvm.nativeimage.c.function.CEntryPoint;
public class LibEnvMap {
    //NOTE: this class has no main() method

    @CEntryPoint(name = "Java_Main_HelloWorld")
    private static int HelloWorld(IsolateThread thread, Object object){
        System.out.println("Hello Native World!");
        return 0;
    }
}
#ifndef __LIBENVMAP_H
#define __LIBENVMAP_H

#include <graal_isolate.h>


#if defined(__cplusplus)
extern "C" {
#endif

int filter_env(graal_isolatethread_t*, char*);

#if defined(__cplusplus)
}
#endif
#endif

Main.java:

public class Main {
    static {
        System.load("/Users/nealshinoda/Repos/HelloWorld/out/production/HelloWorld/LibEnvMap.dylib");
    }

    private native int HelloWorld();
    public static void main(String[] args) {
        System.out.println("Hello world!");
        new Main().HelloWorld();
    }
}
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Main */

#ifndef _Included_Main
#define _Included_Main
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Main
 * Method:    HelloWorld
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_Main_HelloWorld
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

As you can see from the two header files: their signatures are incompatible and it is difficult to hack the type of the parameter since they are all machine-generated.

One potential solution that comes to my mind is that I could use another C/C++ code as a "middle layer", and then the call stack could be JNI ==> C/C++ ==> graalvm native library. However, this solution seems too complicated, and is there any better practice?

N.Shinoda
  • 11
  • 2

0 Answers0