Search code examples
javaandroidmultithreadingjava-native-interface

Is `JNI_OnLoad` always invoked in main thread?


Is JNI_OnLoad() always invoked in main thread or in System.load()/System.loadLibrary() invocation thread? To be more detailed i'm talking about Android (but i think it does not make sense if it's Android or pure Oracle Java).


Solution

  • According to Oracle docs,

    jint JNI_OnLoad(JavaVM *vm, void *reserved);

    The VM calls JNI_OnLoad when the native library is loaded (for example, through System.loadLibrary). ...

    it is not clear what threading policy should be chosen by implementation. But maybe somewhere it is described in more precise manner.

    Anyway, at least on Android JNI_OnLoad() is called synchronously, before control returns from System.load*(). And it occurs in the same thread where System.load*() was called. To ensure you can dig a bit into

    Also you may try to experiment with it: add logs before and after System.load*() and inside JNI_OnLoad(), then analyse log order ant thread IDs.

    And few thoughts at the end. As per spec JNI_Onload() may abort loading:

    If the VM does not recognize the version number returned by JNI_OnLoad, the native library cannot be loaded.

    So, if it returns something other than valid JNI_VERSION_* constant - System.load*() must fail. Consequently, JNI_ONload() must return earlier that corresponding System.load*(). In multithread environment such behavior may be achieved in two ways:

    • run JNI_ONLoad() directly inside of System.load*()
    • proxy it to other thread and block System.load*() until it finishes

    The second one seems to be overcomplicated and wasteful. So IMO the first one is the only clear choose.