【问题标题】:jna.loadLibrary cannot find native library filejna.loadLibrary 找不到本机库文件
【发布时间】:2020-03-26 11:56:50
【问题描述】:

我用原生库包装器创建了自己的 jar。结果jar的结构是:

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

我加载原生库如下:

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

现在我想在其他项目中添加这个库并使用它。但是当我创建 MyLibClass 的一个实例时,我收到一个错误:

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

我应该如何解决这个问题?

【问题讨论】:

    标签: java native jna unsatisfiedlinkerror


    【解决方案1】:

    JNA Getting Started 页面上所述,

    使您的目标库可用于您的 Java 程序。有几种方法可以做到这一点:

    • 首选方法是将jna.library.path 系统属性设置为目标库的路径。此属性类似于java.library.path,但仅适用于 JNA 加载的库。
    • 在启动 VM 之前更改适当的库访问环境变量。在 Windows 上是 PATH,在 Linux 上是 LD_LIBRARY_PATH,在 OSX 上是 DYLD_LIBRARY_PATH
    • 使您的本机库在您的类路径中可用,在路径 {OS}-{ARCH}/{LIBRARY} 下,其中 {OS}-{ARCH} 是 JNA 的本机库的规范前缀(例如 win32-x86linux-amd64darwin)。如果资源在 jar 文件中,加载时会自动提取。

    【讨论】:

      【解决方案2】:

      我使用静态 Loader 类完成了如下操作:

      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");
              }
          }
      }
      

      我从资源中加载库文件并将其内容复制到临时目录。正如您在执行此操作之前所看到的,我将 jna.library.path 设置为 temp 文件夹,因此 JNA 将在那里搜索库。

      此外,我正在加载库:

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

      【讨论】:

        猜你喜欢
        • 2018-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多