java - System.loadLibrary does not work. UnsatisfiedLinkError for the second lib in chain -


i have java program client.class uses cpp shared library libclient.so via jni. libclient.so built shared , uses cpp shared library libhttp.so.

libclient.so , libhttp.so placed in folder /home/client/lib64
client.class placed in /home/client/bin

client can load library with

  1. system.load , environment variable ld_library_path
  2. system.loadlibrary , -djava.library.path

the first way works fine.

export ld_library_path = /home/client/lib64

java -classpath ./bin client

the secon way fails.

java -classpath ./bin -djava.library.path=./../lib64 client

java.lang.unsatisfiedlinkerror: /home/client/lib64/libclient.so: libhttp.so: cannot open shared object file: no such file or directory 

when put libhttp.so /usr/lib64 second way works fine.

why libclient.so looking libhttp.so in /usr/lib64 if use system.loadlibrary? how can fix without coping libhttp.so /usr/lib64?

my loading code:

    //try load -djava.library.path             boolean found = false;     string lib = "client";     try {        system.loadlibrary(lib);        found = true;     } catch (unsatisfiedlinkerror e) {        e.printstacktrace();     }     //try load ld_library_path     if (!found) {        lib = "libclient.so";        string ld_lib_path = system.getenv("ld_library_path");        string[] paths = ld_lib_path.split(":");        for(int i=0; i<paths.length; i++) {           string p = paths[i];           file x = new file(p, lib);           if (x.exists()) {              system.load(x.getabsolutepath());              found = true;              break;           }        }     } 

additional information.

if test libclient.so ldd see: libhttp.so => not found if set export ld_library_path = /home/client/lib64 see: libhttp.so => /home/client/lib64/libhttp.so

the reason libclient.so loaded jvm, looks in java.library.path. however, when libclient.so tries load libhttp.so, knows nothing java , uses regular linux way of loading shared libraries (the dynamic linker ld.so), looks in ld_library_path , common directories /usr/lib64.

i go using ld_library_path set start script of java application. if don't want use start script, in theory set ld_library_path within process itself. however, java not allow (there system.getenv(), not system.setenv()), need write small c library called java , calls putenv() setting ld_library_path.

if build libclient.so itself, can use -rpath linker flag specify path dynamic linker should further required libraries. careful if specify relative path here, interpreted relative current working directory of running application, not relative location of libclient.so. achieve this, need use $origin argument -rpath , careful shell not expand this.

so, if want have libclient.so , libhttp.so in same directory, need use

-rpath '$origin' 

as argument linker when building libclient.so. if not call linker directly let compiler call it, need add following compiler's command line:

-wl,-rpath,'$origin' 

more information can found in man page ld.so.


Popular posts from this blog

How to calculate SNR of signals in MATLAB? -

c# - Attempting to upload to FTP: System.Net.WebException: System error -

ios - UISlider customization: how to properly add shadow to custom knob image -