Running JNI program in ubuntu - java-native-interface

I am running my first program in ubuntu.
But there was an error when I tried to run it:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1681)
at java.lang.Runtime.loadLibrary0(Runtime.java:840)
at java.lang.System.loadLibrary(System.java:1047)
at JNIFoo.<clinit>(JNIFoo.java:6)
Could not find the main class: JNIFoo. Program will exit.

These lines taken from Getting Stated JNI from SUN site
Make sure that the native library resides in one of the directories in
the native library path. If you are running on a Solaris system, the
LD_LIBRARY_PATH environment variable is used to define the native
library path. Make sure that it includes the name of the directory
that contains the libHelloWorld.so file. If the libHelloWorld.so file
is in the current directory, you can issue the following two commands
in the standard shell (sh) or KornShell (ksh) to set up the
LD_LIBRARY_PATH environment variable properly:
LD_LIBRARY_PATH=.
export LD_LIBRARY_PATH

Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
Fix your library path and try again.

Related

QLibrary::load fails, but LD_LIBRARY_PATH just updated correctly before that, why?

I have a library (let's call it mydll.so) that is dependent to an external application, i.e. Matlab. To dynamically load mydll.so, I have written a code like this (Ubuntu, g++ 4.8.5, qt 5.12.6):
// update LD_LIBRARY_PATH with ALL required paths (Matlab, boost, etc.)
bool res = qputenv("LD_LIBRARY_PATH", required_path.toStdString().c_str());
assert(res);
// loading the dll
QLibrary my_dll;
my_dll.setFileName(dll_path);
if (!my_dll.load())
{
std::cout << my_dll.errorString().toStdString() << std::endl;
}
The above code fails with this message:
Cannot load library /home/user/code/test/lnx_x64/debug/mydll.so: (libMatlabDataArray.so: cannot open shared object file: No such file or directory)
It is strange because the load() function is complaining about a library from Matlab, i.e. libMatlabDataArray.so that its path is already included in LD_LIBRARY_PATH. But, if I run ldd on the same environment, I have:
user#everest:~/code$ ldd /home/user/code/test/lnx_x64/debug/mydll.so
linux-vdso.so.1 (0x00007ffcb4da2000)
libMatlabDataArray.so => /usr/local/MATLAB/extern/bin/glnxa64/libMatlabDataArray.so (0x00007f6af95f2000)
libMatlabEngine.so => /usr/local/MATLAB/extern/bin/glnxa64/libMatlabEngine.so (0x00007f6af93e7000)
That means the libMatlabDataArray.so can be found by ldd command and the contents of LD_LIBRARY_PATH is correct. Then what can be the reason behind this issue in my case?
Update 1: If I set the LD_LIBRARY_PATH before the application is started, everything works fine. What is the difference between setting the the LD_LIBRAARY_PATH before launching the application and inside it?
The problem is that you change the environment variable LD_LIBRARY_PATH from within the process. However the process still uses the "old" environment variables block with old values. As a result it cannot properly find the dependent libraries and eventually fails.
Therefore your approach will not work. I would propose the following solutions:
Set the LD_LIBRARY_PATH variable before starting the process, so that the process can take the updated block into account,
Try to use QCoreApplication::setLibraryPaths() function to set the library search paths.

Executable error : Can't start program

After finishing my C++ program (on windows os using codeblocks)(using libcurl) when i try to launch the program from the executable it displays an error saying that i can't start the program because libcurldll is missing,reinstall program then retry. I don't think any line of code is needed here,it's just a configuration and logics problem,any ideas,would be great !
Please note that,running it from the codeblocks's console works fine.
Common issue with DLLs or SOs is that the executable needs to know where they are.
A common solution is to place the DLL library in the same folder as the executable:
Find the libcurldll file.
Find the folder containing your executable.
Copy the libcurldll file into the folder containing your executable.

How to get it REALLY right with LD_LIBRARY_PATH and linking?

I'm repeatedly experiencing problems with libraries which are not found.
In my bashrc I have:
LD_LIBRARY_PATH=
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib1
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib2
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib3
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH
These paths contain ALL folders from where I link libraries into my program with -L/lib1 -l1a -L/lib2 -l2a -L/lib3 -l3a.
Now I start my program standalone:
./program
Fine!
Then I start it with mpiexec from mpich:
/mpich/intel/bin/mpiexec -np 2 ./solvertest1
Fine!
BUT THEN I start it with gdb enabled:
/mpich/intel/bin/mpiexec -np 2 gdb ./solvertest1
Problem, libraries are not found:
Starting program: /my/program
/my/program: error while loading shared libraries: libirng.so: cannot open shared object file: No such file or directory
I suspect that there's something wrong when the LD_LIBRARY_PATH should be propagated through all the subprocesses and shells those scripts and programs produce... What do I have to do to let every subprocess (and whatever else will be started) know where those libraries are?
Store the library path in the DT_RPATH tag of your executable when linking
-Wl,rpath=/lib1 -Wl,rpath=/lib2 -Wl,rpath=/lib3
that way you don't need to mess with LD_LIBRARY_PATH and shell initialization.
Since the program is dependent on having the right environment variables set to run, and mpiexec isn't giving it the env it needs, try something like these from the mpiexec docs:
-x , --envall
Export all environment variables to all processes.
-E , --env name value
Export the variable name with the content value.

GDB "cannot open shared object file" Issue

I've already read gdb says "cannot open shared object file" and gdb can not open shared object file and followed the instructions.
I have a binary which is linked to a shared library file (/zzz/yyy/xxx.so). After I set LD_LIBRARY_PATH to /zzz/yyy/ and run the binary without GDB, it executes very well.
However, when I was trying to use GDB to debug this binary, GDB says:
error while loading shared libraries: xxx.so: cannot open shared object file: No such file or directory
I already have (set in .gdbinit):
(gdb)show env LD_LIBRARY_PATH
LD_LIBRARY_PATH = "/zzz/yyy/"
and
(gdb) show solib-search-path
The search path for loading non-absolute shared library symbol files is "/zzz/yyy/".
and in my system:
% printenv LD_LIBRARY_PATH
/zzz/yyy
What's the other possible reasons why GDB still can't find this shared library?
However, when I was trying to use GDB to debug this binary, GDB says: error while loading shared libraries: xxx.so: cannot open shared object file: No such file or directory
You are mistaken: it's not GDB that says that, it's the dynamic loader. GDB itself doesn't care what LD_LIBRARY_PATH is set to, it simply runs your program. But your program can not run.
The most common cause: you are re-setting your LD_LIBRARY_PATH in your ~/.cshrc, and GDB runs your program in a separate shell, and that shell reads your .cshrc, so your program executes with incorrect environment.
The fix is to make .cshrc not set LD_LIBRARY_PATH for non-interactive shells. See e.g. this answer.

boost thread link fails in Netbeans 7.1 debugging/testing session

I am developing an app on Netbeans, while I can run it. I can not debug or reun the test files. When I try to do so, I get:
./build/Debug/GNU-Linux-x86/tests/TestFiles/f1: error while loading shared libraries: libboost_thread.so.1.49.0: cannot open shared object file: No such file or directory
It tried including the library or the specific file with the debugging or testing session, but I continue to get that. Could there be an inconsistency with Netbeans?
Any ideas would be greatly appreciated!
I assume your OS is Linux. It follows from your email that you have access to the copy of the libboost_thread.so.1.49.0 file. Let DIR be directory where this library exists.
If you do not have superuser on this computer, use method A. If you have superuser, use method A or method B.
Method A. Good for non-superuser or for superuser.
Let DIR be directory in which library libboost_thread.so.1.49.0 exists.
I assume you can start NetBeans from shell command line, not from GUI icon.
Quit NetBeans. Execute following command in bash:
export LD_LIBRARY_PATH=DIR:$LD_LIBRARY_PATH
start netbeans from command line
Eventually, you will want to put the export command into your ~/.bashrc file.
Method B. Good only for superuser.
If you have superuser, use one the following methods to place the missing library into /usr/lib or /lib:
(1) install boost from rpm or apt or whatever packaging your linux system has, or
(2) install boost from sources with --prefix=/usr, or
(3) copy the mentioned library to /usr/lib. If you have to use #3, be careful about symlinks. Copy using "cp -a" and copy all files beginning libboost_thread.so*, like
cp -a DIR/libboost_thread.so* /usr/lib