JNI java load so and got undefined symbol Excetion - java-native-interface

when I load so which compiled locally, I got the exception:
Caused by: java.lang.UnsatisfiedLinkError: /home/admin/libLprProcessor.so: /home/admin/libLprProcessor.so: undefined symbol: _ZNKSt8__detail20_Prime_rehash_policy11_M_next_bktEm
at java.lang.ClassLoader$NativeLibrary.load(Native Method) ~[?:1.8.0_91]
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941) ~[?:1.8.0_91]
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824) ~[?:1.8.0_91]
at java.lang.Runtime.load0(Runtime.java:809) ~[?:1.8.0_91]
at java.lang.System.load(System.java:1086) ~[?:1.8.0_91]

Most likely your library /home/admin/libLprProcessor.so is linked with another library - one that contains _ZNKSt8__detail20_Prime_rehash_policy11_M_next_bktEm.
You have few options here:
link libLprProcessor.so with this library such way you pass -rpath. This way, this additional library will be correctly pointed to from libLprProcessor.so
Add this library to location pointed by java.library.path
Before starting your Java code, make sure to export LD_LIBRARY_PATH such way it points to the library that is used by libLprProcessor.so

(.so) files are shared object similar to .dll files in windows for loading them by JNI you need place them in /lib or /usr/lib for linux in under system32 folder in windows.
programs read these files from specific location so you need install or put them at right place.

Related

Missing DLLs cross-compile wxWidgets shared library on ubuntu

I try to cross-compile under Linux to Windows using the shared library.
I followed the instructions on wxWidgets wiki but while executing main out.exe I got a lot of missing DLL Errors.
Here's how I builded the library :
../configure --disable-debug_flag --host=x86_64-w64-mingw32 --build=x86_64-linux-gnu -with-msw
Here's how I compile and Link :
First : x86_64-w64-mingw32-g++ -c *.cpp *.h $(/wxWidgets/build_win/wx-config --cxxflags)
Second : x86_64-w64-mingw32-g++ -o out.exe *.o $(/wxWidgets/build_win/wx-config --libs) -static-libgcc -static-libstdc++
When I use wine out.exe I got these errors :
002a:err:module:import_dll Library wxbase313u_gcc_custom.dll (which is needed by L"Z:\\home\\ubuntu\\test.exe") not found
002a:err:module:import_dll Library wxmsw313u_core_gcc_custom.dll (which is needed by L"Z:\\home\\ubuntu\\test.exe") not found
002a:err:module:attach_dlls Importing dlls for L"Z:\\home\\ubuntu\\test.exe" failed, status c0000135
I've added the missing DLLs in the same folder as out.exe (They were located in /wxWidgets/build_win/lib/ ) and doing this added lot of more errors :
wine out.exe
0028:err:module:import_dll Library libgcc_s_seh-1.dll (which is needed by L"Z:\\home\\ubuntu\\Bureau\\test\\wxbase313u_gcc_custom.dll") not found
0028:err:module:import_dll Library libstdc++-6.dll (which is needed by L"Z:\\home\\ubuntu\\Bureau\\test\\wxbase313u_gcc_custom.dll") not found
0028:err:module:import_dll Library wxbase313u_gcc_custom.dll (which is needed by L"Z:\\home\\ubuntu\\Bureau\\test\\out.exe") not found
0028:err:module:import_dll Library libgcc_s_seh-1.dll (which is needed by L"Z:\\home\\ubuntu\\Bureau\\test\\wxbase313u_gcc_custom.dll") not found
0028:err:module:import_dll Library libstdc++-6.dll (which is needed by L"Z:\\home\\ubuntu\\Bureau\\test\\wxbase313u_gcc_custom.dll") not found
0028:err:module:import_dll Library wxbase313u_gcc_custom.dll (which is needed by L"Z:\\home\\ubuntu\\Bureau\\test\\wxmsw313u_core_gcc_custom.dll") not found
0028:err:module:import_dll Library libgcc_s_seh-1.dll (which is needed by L"Z:\\home\\ubuntu\\Bureau\\test\\wxmsw313u_core_gcc_custom.dll") not found
0028:err:module:import_dll Library libstdc++-6.dll (which is needed by L"Z:\\home\\ubuntu\\Bureau\\test\\wxmsw313u_core_gcc_custom.dll") not found
0028:err:module:import_dll Library wxmsw313u_core_gcc_custom.dll (which is needed by L"Z:\\home\\ubuntu\\Bureau\\test\\out.exe") not found
0028:err:module:attach_dlls Importing dlls for L"Z:\\home\\ubuntu\\Bureau\\test\\out.exe" failed, status c0000135
Here's my folder content :
ChildPanels.o wxmsw313u_gl_gcc_custom.dll
main.o wxmsw313u_html_gcc_custom.dll
MainPanel.o wxmsw313u_media_gcc_custom.dll
out.exe wxmsw313u_propgrid_gcc_custom.dll
wxbase313u_gcc_custom.dll wxmsw313u_qa_gcc_custom.dll
wxbase313u_net_gcc_custom.dll wxmsw313u_ribbon_gcc_custom.dll
wxbase313u_xml_gcc_custom.dll wxmsw313u_richtext_gcc_custom.dll
wxmsw313u_adv_gcc_custom.dll wxmsw313u_stc_gcc_custom.dll
wxmsw313u_aui_gcc_custom.dll wxmsw313u_webview_gcc_custom.dll
wxmsw313u_core_gcc_custom.dll wxmsw313u_xrc_gcc_custom.dll
Can anyone help me with this ?
EDIT :
It work copying all of these DLLs to my folder :
libgcc_s_seh-1.dll libstdc++-6.dll libwinpthread-1.dll wxmsw313u_core_gcc_custom.dll wxbase313u_gcc_custom.dll
I don't understand why I need to copy the libgcc and libstdc++ to my folder because I linked them staticly. Is it not possible to link static libgcc and libstdc++ and shared wxWidgets ?
Also, how can I tell the compiler I want my DLLs to be loaded from a folder named /lib for example inside my app folder ?
This is not really wxWidgets-specific, but just the way that DLLs work: they need to be found during the program execution and this means either being in the same directory as the program itself, or in one of the directories in the PATH environment variable.
You can't "tell the compiler" anything about the path where the DLLs are found because this path must be used at run time, not compile time.
The simplest workaround if you really, really want to have the DLLs in another directory is to use a wrapper (it could be a script or another compiled program) that would add this directory to the PATH before launching the real application. Alternatively, just link statically and don't bother with the DLLs at all.

ldconfig Does not Include Dynamic Library With non Standard Naming?

I have /foo/lib64/bar.so
I could link it correctly but when I start my application, it complains:
myapps: error while loading shared libraries: bar.so: cannot open shared object file: No such file or directory
I created /etc/ld.so.conf.d/bar.conf to have
/foo/lib64
And I did try to delete the cache /etc/ld.so.cache and rebuild.
"ldconfig -v" shows that /foo/lib64 has no dynamic library:
/foo/lib64:
/lib:
/lib64:
libnl.so.1 -> libnl.so.1.1.4
So certainly ldconfig picks up bar.conf. If I append /foo/lib64 to LD_LIBRARY_PATH, it works.
How can I fix it without renaming bar.so (or symlinking) and without appending /foo/lib64 to LD_LIBRARY_PATH?
Thanks in advance!
Related unresolved post

C++ - shared library liblog4cpp.so.4 not found

I tried to run a program that requires log4cpp,
I got following error when I try to run the program
error while loading shared libraries: liblog4cpp.so.4: cannot open shared object file: No such file or directory
I have set the library path in $LD_LIBRARY_PATH and these are the files in my /usr/local/lib directory:
liblog4cpp.a
liblog4cpp.so
liblog4cpp.so.5.0.6
liblog4cpp.la
liblog4cpp.so.5
pkgconfig
What could be the problem here ?
Thanks!
Use
ldd [program name]
so see what's actually loaded (assuming you are on a Unix system since you use LD_LIBRARY_PATH).

C++ linux executable keeps trying to use library that does not exist

I am trying to write a simple application with GLFW on Linux. Right now the main file (the only file) is basically just a few lines of code to make sure the dynamic library linked correctly. Here it is:
#include <GLFW/glfw3.h>
#include <iostream>
int main()
{
glfwInit();
std::cout << "It works this far!" << std::endl;
glfwTerminate();
}
The include files are stored in a directory labelled "include" and the library files are stored in a directory labelled "lib". As of right now, I am compiling the program with the following line:
g++ -Wl,-Rlib -Iinclude -Llib test.cpp -o test -lglfw.3.2
It compiles and links just fine, but when I try to execute it, I get the following error:
./test: error while loading shared libraries: libglfw.so.3: cannot open shared object file: No such file or directory
Now, before you rush to downvote this question into oblivion and mark it as a duplicate, at least allow me to explain why I believe my question is different enough to not be a duplicate. I already attempted the solutions that the other questions presented, but it was unsuccessful. As you can see, I tried setting the path to the library during linking with the -Wl,-Rlib tag. I also tried setting LD_LIBRARY_PATH to point to the location of my libraries (the 'lib' folder), but it still threw the same error. (It didn't matter if the path was relative or absolute.)
So, the next thing I tried was running the ldd command on the executable. I got some other dependencies that were working just fine, but importantly, I got this:
libglfw.so.3 => not found
For some reason, it insists on looking for libglfw.so.3. It will not have it any other way. Upon renaming the library from libglfw.3.2.so to libglfw.so.3, the program executed just fine and printed It works this far! as if there were no problems at all.
Why would this happen?
For some reason, it insists on looking for libglfw.so.3. ... Upon renaming the library from libglfw.3.2.so to libglfw.so.3 ...
The ELF executables contain the exact name of the dynamic libraries used.
If the executable contains the library name "libglfw.so.3" the file must be named exactly like this.
The file naming scheme is intentionally done in a way that not the "full" version is coded into the file name: This way a later version ("libglfw.so.3.15") will work with the executable.
Normally there should be a symbolic link to the latest version of the library installed:
libglfw.so.3 -> libglfw.so.3.2
This symbolic link seems to be missing on your computer. I would say that this is an installation problem!
EDIT
The question could be: Why is the file name stored in the executable file not libglfw.3.2.so but libglfw.so.3?
The answer has to do with the backward compatibility when a new version of a library is installed:
Normally you would use the switch -lglfw and a symbolic link named libglfw.so is looked up.
If you stored the file name libglfw.so in the executable file and a new, incompatible version if this library (libglfw.so.4) is installed you would have no chance to get the program running by having both versions of the library installed.
To enable backward compatibility by having both versions of the library installed the "real" symbolic link name of the library (libglfw.so.3) must be stored in the executable file.
Therefore the "expected" file name of a library is stored in the library itself: Inside the file libglfw.so.3.2 you'll find some information that the file expects itself to be stored as libglfw.so.3.
The linker will use this information about the file name because it assumes that the library name given in the linker switch (-lglfw) is less "precise" than the name stored in the library itself.
For some reason, it insists on looking for libglfw.so.3. It will not have it any other way.
This is the Linux convention for shared libraries which is described here among other places. For Linux libfoo.so.x.y.z is considered to have the same ABI as libfoo.so.x. Usually when shared libraries are installed (e.g. via rpm, dpkg, etc.) there's an invocation of ldconfig that happens so that the just installed libraries have a symlink following the convention installed that references the library. Also these libs (if installed to a "trusted location"), are added to a linker cache for performance reasons.
It compiles and links just fine, but when I try to execute it, I get the following error:
./test: error while loading shared libraries: libglfw.so.3: cannot open shared object file: No such file or directory
libglfw.so.3 isn't on ld-linux.so's path.
As you can see, I tried setting the path to the library during linking with the -Wl,-Rlib
Still won't find it -- libglfw.so.3 isn't on ld-linux.so's path. You can add it by doing something like:
ldconfig -n /path/to/lib
Which should output the requisite libglfw.so.3 symlink for your lib.
IIRC setting the rpath might require a full path.
I also tried setting LD_LIBRARY_PATH to point to the location of my libraries
Again, libglfw.so.3 isn't on ld-linux.so's path.

How to avoid 'cannot open shared object file' when using CMake?

Situation
My project uses CMake and compiles without problems on Ubuntu 16.04.
When starting the compiled application I get the message cannot
open shared object file.
All the shared object libs are available in the same non-standard
folder (and I need them there).
For some reason some can be found, but others cannot.
What I need
The reason why some shared objects can be found and others cannot be found. The project is pretty big with many CMake files. I tried to find the differences between the libs that can be loaded and the ones that can't, but without success. Any help that point me to the right place is welcome.
A solution within CMake to make it find all the shared objects.
ldd
The ldd output shows me that most shared objects can be found. Here are some examples:
libboost_filesystem.so.1.55.0 => /path/to/libs/boost/lib/libboost_filesystem.so.1.55.0 (0x00007f2ed1fa0000)
libboost_filesystem.so.1.55.0 => /path/to/libs/boost/lib/libboost_filesystem.so.1.55.0 (0x00007f96af1f5000)
libboost_program_options.so.1.55.0 => /path/to/libs/boost/lib/libboost_program_options.so.1.55.0 (0x00007f96aef85000)
libboost_system.so.1.55.0 => /path/to/libs/boost/lib/libboost_system.so.1.55.0 (0x00007f96aed80000)
For some reason a few others cannot be found. For example:
libboost_iostreams.so.1.55.0 => not found
libboost_chrono.so.1.55.0 => not found
There are other non-boost libs that showing the same behavior, but for simplicity I am just showing the boost examples.
Workarounds already tried
Below are the workarounds that already work successfully. But I am really interested in the two points in the What I need section.
Copying to standard folders like /usr/lib and running ldconfig
Adding the path to LD_LIBRARY_PATH
tldr; Check that the imported library is imported as SHARED or UNKNOWN and not STATIC, and has an IMPORTED_SONAME property.
You should check how the library is being imported that you're linking.
I've analyzed a few of the config mode exported targets for static and dynamic libraries, and they are a little different in the properties they set for the target.
For example for zlib, here's the version for static libraries:
add_library(ZLIB::zlibstatic STATIC IMPORTED)
set_target_properties(ZLIB::zlibstatic PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_NOCONFIG "C"
IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/lib/libz.a"
)
However, for dynamic libraries it's:
add_library(ZLIB::zlib SHARED IMPORTED)
set_target_properties(ZLIB::zlib PROPERTIES
IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/lib/libz.so.1.2.11"
IMPORTED_SONAME_NOCONFIG "libz.so.1"
)
In a find_package module mode script, you might think you're importing a static library, when in fact the found library is a .so, so it may use the incorrect target properties. In config mode this is not likely because it's much more explicit when defining the target. Though, module mode (cmake/findXXX.cmake), you're often defining these properties as a result of FIND_PACKAGE_HANDLE_STANDARD_ARGS _LIBRARIES variable, and it's hard to tell what you're going to get. You can use libFoo.a in the search to be more explicit or playing with CMAKE_FIND_LIBRARY_SUFFIXES.