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

I have a Client.class java program that uses cpp shared library libclient.so through JNI. libclient.so is built as shared and uses the cpp shared library libhttp.so.

libclient.so and libhttp.so are placed in the folder /home/client/lib64
Client.class is placed in /home/client/bin

The client can load the library using

  • System.load variable and environment LD_LIBRARY_PATH
  • System.loadLibrary and -Djava.library.path

The first method works fine.

export LD_LIBRARY_PATH = /home/client/lib64

java -classpath./bin Client

Failed to execute secon path.

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 I put libhttp.so in / usr / lib 64, the second way works fine.

Why is libclient.so looking for libhttp.so in / usr / lib 64 if I use System.loadLibrary? How can I fix this without iterating through libhttp.so in / usr / lib 64?

My download code:

  //Try load from -Djava.library.path boolean found = false; String lib = "client"; try { System.loadLibrary(lib); found = true; } catch (UnsatisfiedLinkError e) { e.printStackTrace(); } //Try load from 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 I test libclient.so with ldd, then I see: libhttp.so => ​​not found; If I set the export LD_LIBRARY_PATH = / home / client / lib64, then I see: libhttp.so => ​​/ home / client / lib64 / libhttp.so

+6
source share
3 answers

The reason for this is that libclient.so is loaded from your JVM, which looks in java.library.path . However, when libclient.so tries to load libhttp.so, it does not know anything about Java and simply uses the usual Linux shared library download (dynamic linker ld.so ), which looks in LD_LIBRARY_PATH , and some common directories like /usr/lib64 .

I would probably go with the LD_LIBRARY_PATH installed from the beginning of the script of your Java application. If you do not want to use start script, you could theoretically set LD_LIBRARY_PATH from the process itself. However, Java does not allow this (there is only System.getenv() , not System.setenv() ), so you will need to write a small C library that is called from Java and calls putenv() the LD_LIBRARY_PATH setting.

If you create libclient.so yourself, you can use the -rpath linker flag to specify the path in which the dynamic linker should look for additional required libraries. Be careful if you specify a relative path here, it will be interpreted as relative to the current working directory of the running application, and not relative to the location of libclient.so . To do this, you need to use $ORIGIN as an argument to -rpath and be careful that your shell does not extend this.

So, if you want to have libclient.so and libhttp.so in the same directory, you need to use

 -rpath '$ORIGIN' 

as a linker argument when building libclient.so . If you do not call the linker directly, but let your compiler call it, you need to add the following to your compiler command line:

 -Wl,-rpath,'$ORIGIN' 

More information on this can be found on the page for ld.so

+10
source

I do not have a good answer to this question.

But I found some good ways.

  • Put libhttp.so in the shared folder for libraries, for example / usr / lib 64.
  • Put the path in libhttp.so in LD_LIBRARY_PATH.
  • Create libclient.so using libhttp.so inside.
  • Use -rpath during build of libclient.so.
+1
source

For the correct library search (from java.library.path) for different operating systems there must be different names:

  • Linux: libhttp.so
  • Windows: http.dll

How can you call with Java:

 System.loadLibrary( "http" ); 
0
source

Source: https://habr.com/ru/post/943623/


All Articles