【发布时间】:2010-11-25 10:08:33
【问题描述】:
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 界面中执行 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
我通过另一个包(导出 com.sun.jna 和上面导入的其他包)提供了 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 时)。看来我应该能够根据清单中的 Bundle-NativeCode 指令避免此调用。显然,一旦库被加载,Native.loadLibrary 就会抓取它的现有实例,但我不想依赖这种非常特定于订单的策略。
static{
System.loadLibrary("foo");
}
【问题讨论】:
-
您使用的是哪个 OSGi 实现?
-
我正在使用 Equinox(规格 R4)
-
您可能想说明您使用的是哪个版本的 Java,因为我以前从未遇到过 JNA,而且它不是 Java 的一部分,包括 6。
-
System.loadLibrary() 调用有效,因为它将调用类加载器的 findLibrary() 方法,如果它是 ClassLoader 的 Eclipse 实现,将通过查看包内部找到“本地”库。
-
当你遇到这些讨厌的问题时,不要害怕调试这些类加载器和系统调用,这可能很有教育意义。