Setting LD_LIBRARY_PATH for MatlabEngine java call

I am developing a maven mojo plugin to compile my MATLAB code used in a Tomcat servlet. It just grabs a few paths from maven, assembles a call to mcc, and passes that to an instance of MatlabEngine. The problem is that unless I define LD_LIBRARY_PATH (either in .bashrc, or by sourcing my own script), LD_LIBRARY_PATH is empty and the program dies in the call:
Future<MatlabEngine> eng = MatlabEngine.startMatlabAsync();
I assumed .matlab7rc.sh would be invoked, but watching the file access:
$ sudo auditctl -l
-w /usr/local/MATLAB/R2020a/bin/.matlab7rc.sh -p rx -k matlab7rc
shows the program isn't accessing that file. Even strace:
strace -o strace.out -f -t -e trace=file mvn install
grep matlab7rc strace.out
shows no access. I understand I can define LD_LIBRARY_PATH in a shell script, but this seems inelegant. I haven't found a clean way to define an environment variable within the pom.xml, and while I could use java.util ProcessBuilder to define the environment, this is a long run for a short slide. Suggestions?

3 Comments

I poked around with strace a bit more. MatlabEngine.startMatlab attempts to load libnativemvm. If LD_LIBRARY_PATH contains /usr/local/MATLAB/[version]/bin/glnxa64/, this succeeds. If LD_LIBRARY_PATH is empty, the System.loadLibrary("libnativemvm") call fails:
java.lang.UnsatisfiedLinkError: no nativemvm in java.library.path
It is quite easy to add /usr/local/MATLAB/[version]/bin/glnxa64/ to java.library.path, but this only works for libnativemvm.so; any libraries it references can't be found. Examining the output of strace, we see that jvm looks for:
28814 16:36:43 stat("/usr/lib/jvm/java-8-oracle/jre/lib/amd64/libnativemvm.so", 0x7ff2dadaf340) = -1 ENOENT (No such file or directory)
28814 16:36:43 stat("./libnativemvm.so", 0x7ff2dadaf340) = -1 ENOENT (No such file or directory)
28814 16:36:43 stat("/usr/java/packages/lib/amd64/libnativemvm.so", 0x7ff2dadaf340) = -1 ENOENT (No such file or directory)
28814 16:36:43 stat("/usr/lib64/libnativemvm.so", 0x7ff2dadaf340) = -1 ENOENT (No such file or directory)
28814 16:36:43 stat("/lib64/libnativemvm.so", 0x7ff2dadaf340) = -1 ENOENT (No such file or directory)
28814 16:36:43 stat("/lib/libnativemvm.so", 0x7ff2dadaf340) = -1 ENOENT (No such file or directory)
28814 16:36:43 stat("/usr/lib/libnativemvm.so", 0x7ff2dadaf340) = -1 ENOENT (No such file or directory)
So a simple solution is:
ln -s /usr/local/MATLAB/R2020a/bin/glnxa64/libnativemvm.so libnativemvm.so
Now we find:
java.lang.UnsatisfiedLinkError: no nativecapabilities in java.library.path
Adding:
ln -s /usr/local/MATLAB/R2020a/bin/glnxa64/libnativecapabilities.so libnativecapabilities.so
allows the call to startMatlab to complete. Of course, this isn't a really portable solution.
What would be nice would be if startMatlab looked in ./javalibrarypath.txt or ~/.matlab/[version]/javaclasspath.txt, but it doesn't. As best I can tell, it doesn't touch any file that has .txt or .sh.
Why not just define LD_LIBRARY_PATH in .bashrc? Because too many other things hate the Matlab libraries:
export LD_LIBRARY_PATH=/usr/local/MATLAB/R2020a/bin/glnxa64
$ curl localhost:9000
curl: /usr/local/MATLAB/R2020a/bin/glnxa64/libcurl.so.4: no version information available (required by curl)
curl: (48) An unknown option was passed in to libcurl
Suggestions?
I had the same annoying errors. Try to add the /usr/local/MATLAB/R2020a/sys/os/glnxa64 to your LD_LIBRARY_PATH.
export LD_LIBRARY_PATH=/usr/local/MATLAB/R2020a/bin/glnxa64:/usr/local/MATLAB/R2020a/sys/os/glnxa64:$LD_LIBRARY_PATH
The gcc compiler libraries used by Matlab is located there and it uses those libraries instead of the ones installed in your system, which probably is not the same versions.
As I noted, that is easy enough to do globally in .bashrc; I want to do it on a per-process basis. The reason I can execute "matlab -nodisplay" on my Linux box is that the matlab command first executes .matlab7rc.sh, which sets the LD_LIBRARY_PATH for that process. The problem is that the matlab engine doesn't do this. I can work around this by simply setting the LD_LIBRARY_PATH on the command line:
LD_LIBRARY_PATH=/usr/local/MATLAB/R2020a/bin/glnxa64 java -classpath ...
This works fine, but is inelegant. Also note that the only reason I need to mess around with LD_LIBRARY_PATH is that I'm loading a library that loads another private MATLAB library, which means that setting the java.library.path doesn't suffice, as the java classloader isn't doing the path resolution, the native OS is.

Sign in to comment.

Answers (0)

Categories

Products

Release

R2020a

Asked:

on 17 Dec 2020

Commented:

on 30 Dec 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!