如何使用OSGi片段来提供具有相同文件名的依赖于平台的本机代码?

Dan*_*ell 6 java osgi native-code osgi-fragment

我正在使用JNotify项目来监听文件系统事件.这取决于每个OS的一个本机库:处理器架构.例如,有一个用于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,\
 *
Run Code Online (Sandbox Code Playgroud)

这很好用.

转移到片段

我认为如果我将库移动到单独的片段包中会很"好",这样我就可以为我感兴趣的体系结构贡献片段.以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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

请注意,这些捆绑包是根据不同的来源构建的.虽然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)
Run Code Online (Sandbox Code Playgroud)

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

我试过的东西

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

Pet*_*ens 3

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

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

 Fragment 64-bit:
 Include-Resource: x64/libjnotify.so=lib/libjnotify.so
Run Code Online (Sandbox Code Playgroud)

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