Search code examples
javanativejnaunsatisfiedlinkerror

jna.loadLibrary cannot find native library file


I have created own jar with native library wrapper. The structure of resulting jar is:

library.jar
 |- com (there are my .java classes)
 |- libs (there is the native - libmylib.so)
 |- META-INF

I load native lib as follows:

MyLibClass instance = (MyLibClass) Native.loadLibrary("mylib", MyLibClass.class);

Now I want to add this library in other project and use it. But when I create an instance of MyLibClass I receive an error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'mylib':
libmylib.so: cannot open shared object file: No such file or directory

How should i fix this problem?


Solution

  • I've done that using static Loader class as follows:

    static class Loader {
    
        private Loader() {
        }
    
        static String getNative() {
            InputStream in = null;
            FileOutputStream fos = null;
            File fileOut = null;
            System.setProperty("jna.library.path",
                    System.getProperty("java.io.tmpdir"));
    
            in = Loader.class.getResourceAsStream(
                            "/libs/libmylib.so");
    
            if (in != null) {
                try {
                    fileOut = File.createTempFile("mylib", ".so");
                    fileOut.deleteOnExit();
    
                    fos = new FileOutputStream(fileOut);
    
                    int count;
                    byte[] buf = new byte[1024];
    
                    while ((count = in.read(buf, 0, buf.length)) > 0) {
                        fos.write(buf, 0, count);
                    }
    
                } catch (IOException ex) {
                    throw new Error("Failed to create temporary file: " + ex);
                } finally {
                    try {
                        in.close();
                    } catch (IOException ex) {
                    }
    
                    if (fos != null) {
                        try {
                            fos.close();
                        } catch (IOException ex) {
                        }
                    }
    
                    return fileOut.getAbsolutePath();
                }
            } else {
                throw new Error("Couldn't open native library file");
            }
        }
    }
    

    There I load library file from resources and copy its contents to the temporary dir. As you can see before doing that I set jna.library.path to temp folder, so JNA will search libraries there.

    Futher I'm loading library as this:

    MyLibClass instance = (MyLibClass) Native.loadLibrary(Loader.getNative(), MyLibClass.class);