Как использовать фрагменты 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. В этом случае только один фрагмент с собственным кодом может быть разрешен и установлен в любое время, что позволяет избежать конфликта пространств имен.