Как использовать фрагменты OSGi для создания зависящего от платформы собственного кода с тем же именем файла?
Я использую JNotify проект для прослушивания событий файловой системы. Это зависит от одной собственной библиотеки per OS:архитектуры процессора. Например, есть одна библиотека для Windows x86,одна библиотека для x86-64 и т. д.
монолитная связка
первоначально у меня был один пакет, который содержал как классы Jnotify Java, так и собственный код. Собственный код был объявлен в Bundle-NativeCode следующим образом:
(я отформатировал их в bnd стиль для лучшей читаемости... очевидно, фактический манифест.Файлы 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.так Имя же это разные файлы в различные проекты Eclipse. Они должны быть одинаковыми для работы с JNotify.
обратите внимание, что одно и то же имя файла внесено в пакет хоста. в этом случае имя файла libjnotify.Итак.
если я запускаю их на моем 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-разрядная библиотека загружается. но почему? My Bundle-NativeCode определяет, что хост должен быть 32-битной машиной Linux для использования версии 32-битного пакета. Я думал, если это предложение не соответствует, библиотека игнорируется?
вещи, которые у меня есть пробовал
- удаления лишних подстановки... это просто означает, что пакеты не разрешают
3 ответов
Так как ваш фрагмент занимает одно и то же пространство имен ресурсов только один .таким образом, файл может быть доступен. Вы можете развернуть только один фрагмент, или вы можете попробовать поместить их в разные каталоги:
Fragment 32-bit:
Include-Resource: x32/libjnotify.so=lib/libjnotify.so
Fragment 64-bit:
Include-Resource: x64/libjnotify.so=lib/libjnotify.so
Я также думаю, что вам нужно поместить заголовок Bundle-NativeCode в пакет хоста и обратиться к соответствующим каталогам, так как я думаю, что этот заголовок не объединен в Хосте.
проверьте, какую версию контейнера Eclipse/OSGi вы используете. Я подозреваю, что вы обнаружите, что контейнер, который вы запускаете, имеет ОС, установленную на 32-битную систему.
Если вы не возражаете, ограничен Эквинокс вы можете использовать решение с одним фрагментом на платформу с Eclipse-PlatformFilter
. В этом случае только один фрагмент с собственным кодом может быть разрешен и установлен в любое время, что позволяет избежать конфликта пространств имен.