Как использовать фрагменты OSGi для добавления зависимого от платформы нативного кода с тем же именем файла?
Я используюJNotify проект для прослушивания событий файловой системы. Это зависит от одной собственной библиотеки на ОС: архитектура процессора. Например, есть одна библиотека для 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-битной машине с загруженным 64-битным комплектомдо 32 бит один, это работает.
Однако, если 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-битную версию пакета. Я думал, что если это предложение не совпадает, библиотека игнорируется?
Материал, который я пробовалУдаление необязательного подстановочного знака ... это просто означает, что пакеты не разрешаются