4

I have a native library that I call using JNI. Call to the native library works fine in Linux.

My questions is if I create a .so and .dll file for Linux and Windows and add them to the project, is there a way to load the right library based on the operating system my application is running on when calling System.LoadLibrary("myLib")?

In other words, what would be the right implementation of the pseudo-code below ?

if(Windows){
   System.LoadLibrary("myLib.dll");
}else if(Linux){
   System.LoadLibrary("myLib.so");
}

Thanks

user624558
  • 559
  • 2
  • 8
  • 20

2 Answers2

4

Quite contrary, on Windows

System.loadLibrary("myLib");

will load myLib.dll, but on *x it is equivalent to

System.load(path + "/libmyLib.so");

Deployment and path management will be platform-dependent, but loadLibrary() is "code once, run everywhere".

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • System.mapLibraryName() should be used in conjunction with System.loadLibrary() to address the above mentioned platform naming discrepancy. – Alex Barker Jun 12 '14 at 07:36
  • 1
    `System.mapLibraryName()` may be useful to handle relative paths, see *[example](http://stackoverflow.com/a/10693468/192373)*. But in simple cases, `System.loadLibrary()` is just enough. – Alex Cohn Jun 12 '14 at 07:42
  • Thanks for pointing `System.mapLibraryName()`. I think it will solve my problem by combining it with `System.load()` if `System.loadLibrary()` fails to load the library. I will have to go with @AlexBarker's answer as it shows a more complete solution. – user624558 Jun 12 '14 at 16:29
1

Its a little complicated, there is a full example in this loadNativeLibrary() method.

A few notes:

Try System.loadLibrary(libName) first so your library can be externalized. Most Linux packages will want to do this.

You will need to setup some method of arch and operating system native file storage in your jar. The example covers this with a few helper classes to normalize arch names. See NativeSystem.

Previous versions of Java on OS X decided that dynamic libraries used for JNI should use the jnilib extension instead of dylib like every other dynamic library on the system. You may need to work around that.

Make sure you unpack the native library to a unique file path. Its always fun when you have concurrent applications extracting different versions of your naive library to the same location and filename.

Use System.load() instead of System.loadLibrary() to load the extracted binaries. That way you don't need to worry about the java.library.path.

Alex Barker
  • 4,316
  • 4
  • 28
  • 47
  • Thank you. The example shown gives a more complete picture on how to address this problem. It is a good reference for anyone who is trying to solve this problem. – user624558 Jun 12 '14 at 16:31