6

我正在使用JNotify项目来监听文件系统事件。这取决于每个 OS:processor 体系结构的一个本机库。例如,有一个用于 Windows x86 的库,一个用于 x86-64 的库等。

单片捆绑

最初,我有一个包含 JNotify Java 类和本机代码的包。本机代码在 Bundle-NativeCode 中声明如下:

(为了更好的可读性,我已将它们格式化为 bnd 样式......显然,实际的 MANIFEST.MF 文件格式正确)。

Bundle-NativeCode: jnotify_64bit.dll;osname=Win32;osname="Windows NT (unknown)";osname = WindowsXP;osname = Windows2000;osname = Windows2003;osname = WindowsVista;osname = Windows7;osname = WindowsServer2008;osname= Windows8;osname = WindowsServer2012;processor = x86-64,\
 jnotify.dll;osname=Win32;osname="Windows NT (unknown)";osname = WindowsXP;osname = Windows2000;osname = Windows2003;osname = WindowsVista;osname = Windows7;osname = WindowsServer2008;osname = Windows8;osname = WindowsServer2012;processor = x86,\
 libjnotify.so;osname = Linux;processor = x86,\
 libjnotify64.so;osname = Linux;processor = x86-64,\
 libjnotify.dylib;osname = Mac OSX;processor = x86;processor = x86-64,\
 *

这运作良好。

移动到片段

我认为如果我将库移动到单独的片段包中会“很好”,这样我就可以为我感兴趣的架构贡献片段。以 Linux 为例,我将它们分成两个包:

Linux 32 位

Include-Resource: lib/libjnotify.so
Bundle-NativeCode: libjnotify.so;osname = Linux;processor = x86,\
    *
Fragment-Host: net.contentobjects.jnotify
Bundle-Version: 0.94.0

Linux 64 位

Include-Resource: lib/libjnotify.so
Bundle-NativeCode: libjnotify.so;osname = Linux;processor = x86-64,\
    *
Fragment-Host: net.contentobjects.jnotify
Bundle-Version: 0.94.0

请注意,这些捆绑包是从不同的来源构建的。尽管 libjnotify.so 文件名相同,但它们是不同 Eclipse 项目中的不同文件。它们必须相同才能与 JNotify 一起使用。

请注意,相同的文件名被贡献给主机包。在这种情况下,文件名为 libjnotify.so。

如果我在我的 64 位机器上运行这些,并且在 32 位之前加载 64 位包,它就可以工作。

但是,如果首先加载 32 位包,我会得到:

Couldn't initialise JNotify: java.lang.UnsatisfiedLinkError: /blah/generated/fw/bundle46/version0.0/net.contentobjects.jnotify.linux.x86-0.94.0.jar-lib/0/libjnotify.so: /blah/generated/fw/bundle46/version0.0/net.contentobjects.jnotify.linux.x86-0.94.0.jar-lib/0/libjnotify.so: wrong ELF class: ELFCLASS32 (Possible cause: architecture word width mismatch) (JnotifyFileSystemObserver.java:53, thread platformExecutor)

显然正在加载 32 位库。但为什么?我的 Bundle-NativeCode 定义主机必须是 32 位 Linux 机器才能使用 32 位包的版本。我想如果那个子句不匹配,图书馆会被忽略吗?

我试过的东西

  • 删除可选通配符...这仅意味着捆绑包无法解析
4

3 回答 3

3

由于您的片段占用相同的资源命名空间,因此只能访问一个 .so 文件。您可以只部署一个片段,或者您可以尝试将它们放在不同的目录中:

 Fragment 32-bit:
 Include-Resource: x32/libjnotify.so=lib/libjnotify.so

 Fragment 64-bit:
 Include-Resource: x64/libjnotify.so=lib/libjnotify.so

我还认为您需要将 Bundle-NativeCode 标头放在主机包中并引用正确的目录,因为我认为此标头未合并到主机中。

于 2012-10-17T06:09:18.047 回答
0

检查您正在运行的 Eclipse/OSGi 容器的版本。我怀疑您发现您正在启动的容器已将操作系统设置为 32 位系统。

于 2012-10-16T21:06:48.117 回答
0

If you don't mind being restricted to Equinox you can use one-fragment-per-platform solution with Eclipse-PlatformFilter. In this case, only one fragment with native code can be resolved and installed at any time thus avoiding namespace conflict.

于 2014-09-08T14:10:27.960 回答