负载DLL(使用JNA)一个OSGi包内(Load DLL (using JNA) inside a

2019-07-04 16:54发布

OSGi的找不到我的DLL文件,我似乎无法找出原因。

目前,我有DLL文件( foo.dll在我的包的根),我也试着让它在libs目录。

有问题的捆绑的清单看起来是这样的:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: foobundle
Bundle-SymbolicName: com.foo.bar
Bundle-Version: 1.0.0
Bundle-Vendor: me
Import-Package: com.sun.jna,
 com.sun.jna.ptr,
 com.sun.jna.win32
Export-Package: com.foo.bar
Bundle-NativeCode: foo.dll;
 osname=WindowsXP;
 processor=x86

然后在我的JNA接口I进行调用LoadLibrary(按照文档):

public interface MyFooInterface extends com.sun.jna.Library{
    static final MyFooInterface INSTANCE = (MyFooInterface)com.sun.jna.Native.loadLibrary("foo", MyFooInterface .class);

    // specific interface defs here...
}

然后在另一个类我试图使用JNA接口

// ...code
int var = MyFooInterface.INSTANCE.bar();
// ...more code

我有JNA经由另一束(其中出口com.sun.jna和其他包上述进口)供给,也试图与这里定义的捆绑包装它(在这种情况下将其添加到类路径,等等)。

我也试着指定Bundle-NativeCode: /foo.dll

同样的兴趣,这是相关的OSGi属性(我拉起使用getprop

org.osgi.framework.os.name=WindowsXP
org.osgi.framework.processor=x86

即使毕竟这(与我尽了一切试行)我总是以下面的错误(和堆栈跟踪未显示)结束:

java.lang.UnsatisfiedLinkError: Unable to load library 'foo': The specified module could not be found.

...所以我缺少什么?

编辑 :我还应该注意到,我测试过,并取得了成功的JNA接口代码,它会谈的JUnit测试计划的一部分的DLL。

编辑2:将此代码添加到调用了库中的类似乎让JNA找到库(当Native.loadLibrary被后来称为)。 看来我应该能够避免基于清单捆NativeCode指令这一呼吁。 显然,一旦库被加载Native.loadLibrary抓住它的现有实例,但我不希望依靠这种非常具体的订单策略。

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

Answer 1:

问题是专业JNA LoadLibrary调用,这是不知道的OSGi。 当您从一个OSGi包调用调用LoadLibrary,它将使用OSGi的类加载器(这是束知道)找到该DLL是,在这种情况下,从包中提取出来,并使其通过的System.loadLibrary可装载()调用针对特定位置。

由于这JNA似乎是(一)不OSGi的认识,和(b)superflous,为什么不使用的System.loadLibrary()呢?

如果你需要写两个,然后在包的开始执行的System.loadLibrary()()方法在BundleActivator的,这将在(你可能想确保,如果它不能被加载,捆把机库不能在任何情况下启动)。



Answer 2:

综观JNA的文档,它指出:

  • 让你的目标库提供给您的Java程序。 有两种方法可以做到这一点:
    • 首选的方法是将设置jna.library.path系统属性的路径,你的目标库。 此属性类似于java.library.path ,但仅适用于JNA加载库。
    • 启动VM之前更改相应的库访问环境变量。 这是PATH在Windows上, LD_LIBRARY_PATH在Linux和DYLD_LIBRARY_PATH在OSX。

因此,要解决这个缺点,你可以解决库的绝对路径和加载。

假设其Eclipse的标准类加载器,你可以做ClassLoader.findLibrary()应该找到被捆绑的本地库。



Answer 3:

我建议你尝试打包DLL作为一个jar:

jar cvf foo.dll.jar foo.dll

和负载罐子作为常规库。



文章来源: Load DLL (using JNA) inside an OSGi bundle
标签: java osgi jna