Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

While loading JNI library, how the mapping happens with the actual library name

We load any native library by using

System.loadLibrary("hello")

Now I came to know that this library name refers to hello.dll for windows and libhello.so for unix based system.

So where these platform dependent changes happens?

Is JRE doing this?

like image 383
Onki Avatar asked May 13 '16 06:05

Onki


People also ask

What is JNI and how it works?

JNI is the Java Native Interface. It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++).

What is Jclass in JNI?

The jclass instance is your object on which a method will be invoked; you'll need to look up the getName method ID on the Class class, then invoke it on the jclass instance using CallObjectMethod to obtain a jstring result. So in short yes, you just call the getName function and look at the jstring result.

What is JNI libs?

jni/libs folder is where your shared library files are built from the C/C++ sources. Your native code gets compiled and depending on the value you had set in your application.mk file for the parameter APP_ABI: = <all | x86 | armv7a | armeabi-v7 | mips>


1 Answers

tl;dr

The platform dependent library name is built in native methods of the Java Virtual Machine. The actual algorithm simply prepends/appends a platform specific prefix/suffix to the name:

  • Windows: "hello" -> "hello.dll"
  • Linux/Solaris: "hello" "libhello.so"
  • Mac: "hello" -> "libhello.dylib"

Long version:

There are a couple of JDK Java methods which deal with loading libraries and/or library names:

java.lang.System.loadLibrary(String name)
java.lang.System.mapLibraryName(String name)
java.lang.Runtime.loadLibrary(String name) 
java.lang.ClassLoader.loadLibrary(String name)

The famous System.loadLibrary actually calls Runtime.loadLibrary which calls ClassLoader.loadLibrary. In the end the implementations of these methods call the following native methods which translate the given library name into the platform specific name:

native java.lang.System.mapLibraryName(String name)
native java.lang.ClassLoader$NativeLibrary.findBuiltinLib(String name) 

The implementations of these native methods can be found in (link to the OpenJDK versions):

  • http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/native/java/lang/System.c#l466
  • http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/native/java/lang/ClassLoader.c#l495

Both methods implement the same algorithm to build the actual library name, prepending the prefix JNI_LIB_PREFIX and appending the suffix JNI_LIB_SUFFIX.

In the end the macros JNI_LIB_PREFIX and JNI_LIB_SUFFIX are defined in platform dependent include files, namely

  • http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/windows/javavm/export/jvm_md.h#l42
  • http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/solaris/javavm/export/jvm_md.h#l43
  • http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/macosx/javavm/export/jvm_md.h#l43
like image 88
wero Avatar answered Sep 30 '22 09:09

wero