Why using System.loadLibrary() doesn't seem to work on jshell command prompt?

232 views Asked by At

Consider the simplest possible example of using JNI consisting of a C file

#include <jni.h>

#include <stdio.h>
#include <syslog.h>

JNIEXPORT void JNICALL Java_org_example_hi_sayHi(JNIEnv*, jobject) {
    puts("hi from native code");
    syslog(LOG_NOTICE, "hi from native code");
} 

and Java file hi.java in the org/example subdirectory:

package org.example;

public class hi {
    // THE LINE REFERENCED BELOW: static { System.loadLibrary("hi"); }
    public native void sayHi();
} 

Compiling and running the following Java program

import org.example.hi;

public class sayhi {
    public static void main(String[] args) {
        System.loadLibrary("hi");
        new hi().sayHi();
    }
} 

works perfectly fine.

However doing the same thing from jshell prompt fails:

$ jshell -v
|  Welcome to JShell -- Version 11.0.8
|  For an introduction type: /help intro

jshell> import org.example.hi;

jshell> System.loadLibrary("hi");

jshell> new hi().sayHi();
|  Exception java.lang.UnsatisfiedLinkError: 'void org.example.hi.sayHi()'
|        at hi.sayHi (Native Method)
|        at (#3:1)

and I don't understand why. Loading the library succeeds, as can be seen by either using a non-existing library name in jshell (this results in an error) or by examining the child java process used by jshell process using lsof: I can see that libhi.so is not used by it before the loadLibrary() call but is used after it.

Moreover, uncommenting the commented out line in hi.java makes it work in jshell too, i.e. if loadLibrary() is executed as part of loading the package and not typed at jshell prompt itself, everything works as expected (except that puts() output is nowhere to be seen, apparently because java stdout is redirected somewhere, but syslog() output can be seen and there is no UnsatisfiedLinkError).

But it seems like doing this in jshell should work too -- yet it doesn't. Does anybody have an explanation for this?

FWIW this is not Linux-specific, it is just simpler to test this under Linux. I observe exactly the same behaviour with Java 12 under Windows too.

0

There are 0 answers