In a Java project, I am using a third-party library that loads some native library via
System.loadLibrary("libName");
I'd like to be able to influence the search path of this method from within my application, so that the user doesn't need to specify a correct java.library.path value on the command line (this value depends on the current OS and architecture). E.g on Windows I want to set it to "lib/native/windows", on Linux 32bit to "lib/native/linux32" etc.
I tried
System.setProperty("java.library.path", ...)
but this is ignored, apparently because the JVM reads this property only once before my code is run.
I also tried to load the native libray before using the Java library that depends on it with
System.load("fullPath/lib")
This call succeeds, but there will still be an UnsatisfiedLinkError when the native library is loaded again with System.loadLibrary().
The only way I found is the following:
- Add interfaces that abstract the whole API of the external library.
- Use only these interfaces in the rest of the code.
- Add classes that implement the interfaces and delegate to the library.
- Write an own ClassLoader, that
- overwrites findLibary() so that the native library is found in the correct path
- overwrites loadClass() and loads all classes of the external library and the wrapper layer by itself instead of trying to delegate to its parent like the default ClassLoader would do
- Ensure that the interfaces are loaded with the normal ClassLoader and the wrapping classes and the external library are loaded with my own ClassLoader.
This works, but I find it very complicated and it is much effort because I need to add all those interfaces. Is there a simpler way?