Sometimes, you want to change native code while JVM is running. In Java, it is not easy to reload native library. However, you can always make a trick by loading it in a wrapper library. In this scenario, what you do is loading native library each time you want to call native code.

There is one step that is important here. You have to make sure to load and call the code from shared library that you want to use
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
JNIEXPORT void JNICALL Java_recipeNo018_ReloadLib_displayMessage (JNIEnv *env, jobject obj) { /* dynamic library will be handled by the variables below */ void *lib_handle; void (*fn)(); char *error; /* make sure to put libfoo on the LIBRARY_PATH */ lib_handle = dlopen("libReloadLib.dylib", RTLD_NOW); if (!lib_handle) { fprintf(stderr, "%s\n", dlerror()); exit(1); } /* get the location of the given function inside library we will use it later on to call the function */ fn = dlsym(lib_handle, "foo"); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); exit(1); } /* call the function from external library */ (*fn)(); /* close shared library and check the error code */ int result = dlclose(lib_handle); if (((error = dlerror()) != NULL) || result != 0) { fprintf(stderr, "%s\n", error); exit(1); } } |
What are the possible cases where you can use this approach?
– you want to change native code while Java application is running
– you want to switch between native implementations that are called from Java (debug/release)
– you want to simulate reloading shared library in Java (note that reloading JNI code in Java is quite cumbersome)