Java - JNA and shared Libraries, UnsatisfiedLinkError when starting from a .jar on Linux
[Final Solution can be found in the comments to the accepted answer. Thanks to bmargulies]
Hey Folks,
I've got a quite weird error and I can't figure out the reason. So here's the setup: I'm building a platform-independent music player in Java. As native sound library I'm using the irrKlang engine ( http://www.ambiera.com/irrklang/ ), which comes as a set of shared libraries for Windows, Linux and MacOS, respectively. Since these libraries are written in C++, I've built a shared library as wrapper (also in C++, but using extern "C" and so on), also compiled for each operating system needed. I now use that wrapper out of JNA. I'm using eclipse, all needed library resist in the Project's main folder (the current working directory). Now here comes the problem: Everything works fine if I run my Java application out of eclipse and even building a .jar on Windows into the Project's main folder and executing it there brings no problems. But specifically on Linux, when I pack the (usually working!) application into a .jar, I get the following error:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.UnsatisfiedLinkError: Unable to load library 'IrrklangWrapper': libIrrKlang.so: cannot open shared object file: No such file or directory
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:163)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:236)
at com.sun.jna.Library$Handler.<init>(Library.java:140)
at com.sun.jna.Native.loadLibrary(Native.java:379)
at com.sun.jna.Native.loadLibrary(Native.java:364)
at Demo.<init>(Demo.java:29)
at Demo.main(Demo.java:55)
... 5 more
"IrrKlangWrapper" is my own shared library, "libIrrKlang.so" is the library wrapped by it. So JNA is able to find开发者_Python百科 my library, but my library isn't able to find the wrapped one. Weird! Especially because this doesn't happen if I start the Project directly (without building a .jar).
Because some of you might ask for it, here also the code written in C++ - although I don't think the source of the problem is located there, as the error is raised before the contained method is called:
#include <iostream>
#include <stdio.h>
#include <irrKlang.h>
#include <sys/stat.h>
#include <string>
#include <unistd.h>
using namespace std;
extern "C" {
int func(char *path) {
cout << path << endl;
irrklang::ISoundEngine* engine = irrklang::createIrrKlangDevice();
engine->loadPlugins("./");
cout << engine->getDriverName() << endl;
engine->play2D(path);
//Endless loop for testing. TODO: Remove
while (true) {
}
engine->drop();
return 0;
}
}
Anyone got an idea how to solve this? As my application intends to be platform independent, I'm not able to copy any shared libraries to specific folders - they have to reside in a (sub-)folder of my application.
Thanks in advance,
André
On Linux you'll need to set LD_LIBRARY_PATH to include the directory containing that second shared library.
This requirement is very hard to get around. LD_LIBRARY_PATH is only read by ld.so at the inception of the java process. You can't add to it later.
You have to make one big shared lib, which means finding .a versions of your dependencies to incorporate into it.
精彩评论