12

可能重复:
如何在 JAR 中捆绑原生库和 JNI 库?

我需要在我的 jar 中包含本机 lib(jnotify 但我认为没关系)。我想用 NetBeans 来做。

我添加Bundle-NativeCode: /lib/jnotify.dll; osname=win32到我的manifest.mf文件并添加jnotify.dllprojektHome\src\lib\文件夹中。但不幸的是,NetBeans 覆盖了 manifest.mf文件。

我该如何解决?我可以只使用 NetBeans 做到这一点吗?行'Bundle-NativeCode: /lib/jnotify.dll; osname=win32正确吗?我还听说我应该将 dll 散列放入manifest.mf并签署我的 jar。真的吗?

4

3 回答 3

6

我认为 Java 可执行文件不支持Bundle-NativeCode. 我很确定这是一个OSGi属性。支持的属性列表在JAR 文件规范中定义。

在提供它的外部框架中,没有对在 JAR 文件中捆绑本机库的内置支持。如果我没记错的话,可以将文件提取到临时位置并手动加载。

于 2009-12-04T10:50:30.073 回答
6

有时我发现问题不是加载本机库的 Java 方式,而是需要该本机代码的 3rd 方库。

问题是第 3 方库会在某个时候执行(通常在初始化的早期)

System.loadLibrary("native.dll"); 

如果 native.dll 不在适当的位置,则会引发错误。

如果您有权访问 3rd 方库的 java 源代码,则可能很容易修补该代码,并且您可以轻松地从 JAR 中提取 dll 并在使用 3rd 方库之前运行 System.load。

更新 我查看了 JNotify 来源。这正是我所说的:

public class JNotify_win32
{
    static
    {
        System.loadLibrary("jnotify"); /* *** */
        int res = nativeInit();
        if (res != 0)
        {
            throw new RuntimeException("Error initialiing native library. (#" + res + ")");
        }
    }

取出线 *** 或用 try-catch 包围,用 System.load() 加载,你就完成了。

于 2009-12-04T14:24:40.287 回答
3

当程序在该操作系统上运行时尝试挂钩 Windows 关闭事件时,我遇到了这个问题。我最终使用的解决方案本质上是 McDowell 的 - 将 DLL 添加到 jar 文件中,并在程序启动时将其提取到临时位置。如果它适合您的程序,您可以将 DLL 保留在更永久的位置,然后在后续程序启动时引用它。我的应用程序在用户可能故意删除他们不应该删除的文件的环境中使用,因此我必须在每次运行时提取 DLL。但是,它并没有导致任何重大的性能损失。

于 2009-12-04T14:03:01.363 回答