【问题标题】:Load .so file from a jar从 jar 加载 .so 文件
【发布时间】:2014-12-26 10:27:59
【问题描述】:

我用 C 语言创建了一个库,并使用 JNI 从 Java 调用它,所以我有我的包和一个包含 libMYLIB.so 文件的 lib 文件夹。我从 Java 写作中回忆起来:

static{
    System.loadLibrary("MYLIB");
}

如果我使用选项 -Djava.library.path=../lib 执行它,它运行良好。

但是我需要用我的包和 lib 文件夹创建一个 jar 文件;所以我做了它并导入到一个更复杂的项目中。

在大型项目中,可以看到并使用我的包的类,但在运行时 Java 无法加载 MYLIB。

是否可以告诉 Java 从 jar 文件中加载它?怎么样?

【问题讨论】:

  • 有四种加载库的方法:chilkatsoft.com/java-loadLibrary-Linux.asp
  • 好的,但是如果我想将它包含在 jar 文件中,有没有办法以编程方式将该路径添加到 library.path?
  • 不是直接的,我们需要解压库。顺便说一句,JavaCPP 具有完全适合这种情况的功能。如果您愿意,我可以详细说明。
  • 我很感兴趣...如果可以的话:)

标签: java c java-native-interface loadlibrary library-path


【解决方案1】:

首先,我们需要确保 JAR 文件位于类路径中。然后,这里有一个加载库的简单方法,假设它在 JAR 中的/com/example/libMYLIB.so 下找到:

    InputStream is = ClassLoader.class.getResourceAsStream("/com/example/libMYLIB.so");
    File file = File.createTempFile("lib", ".so");
    OutputStream os = new FileOutputStream(file);
    byte[] buffer = new byte[1024];
    int length;
    while ((length = is.read(buffer)) != -1) {
        os.write(buffer, 0, length);
    }
    is.close();
    os.close();

    System.load(file.getAbsolutePath());
    file.deleteOnExit();

但这掩盖了Loader 类中的 JavaCPP 涵盖的许多极端情况和可移植性问题。

【讨论】:

  • 对硬盘来说压力很大,但我认为这是将 .so 文件保存在 jar 中的唯一方法!
  • @DavideTheSgrash 好吧,这确实是一个操作系统问题:他们需要一个实际的库文件。大多数支持在 RAM 中挂载临时目录。
  • 我们有同样的要求,但这种方法对我们不起作用。 Linux操作系统和Java8。我们这里有什么遗漏吗?
  • 没有。不。在我们的例子中,我们已经将 .so 文件打包在 jar 中。我们试图在 jar 本身中编写/添加一个类以在运行时加载 so 文件。我们使用上面的代码这样做。结果是,lib 被提取到 temp 目录并且System.load() 也被执行,但是当尝试访问该 lib 时它失败了。我们错过了什么吗?
  • 谢谢,非常有用,我最近两天一直在处理这个问题,终于找到了解决方案。
猜你喜欢
  • 2012-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-02
相关资源
最近更新 更多