Jak korzystać z fragmentów OSGi, aby dodać zależny od platformy kod macierzysty o tej samej nazwie?
UżywamJNotwierdź projekt do słuchania zdarzeń systemu plików. Zależy to od jednej rodzimej biblioteki na OS: architektura procesora. Na przykład jest jedna biblioteka dla Windows x86, jedna biblioteka dla x86-64 itp.
Pakiet monolitycznyPierwotnie miałem jeden pakiet zawierający zarówno klasy JNotify Java, jak i kod natywny. Kod natywny został zadeklarowany w Bundle-NativeCode w następujący sposób:
(Sformatowałem je w stylu bnd dla lepszej czytelności ... oczywiście rzeczywiste pliki MANIFEST.MF są poprawnie utworzone).
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,\
*
To działało dobrze.
Przejdź do fragmentówDoszedłem do wniosku, że byłoby miło, gdybym przeniósł biblioteki do oddzielnych pakietów fragmentów, dzięki czemu mógłbym po prostu dodać fragmenty do interesującej mnie architektury. Biorąc przykład z Linuksa, podzieliłem je na dwa pakiety:
Linux 32-bitowy
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-bit
Include-Resource: lib/libjnotify.so
Bundle-NativeCode: libjnotify.so;osname = Linux;processor = x86-64,\
*
Fragment-Host: net.contentobjects.jnotify
Bundle-Version: 0.94.0
Zauważ, że te pakiety są zbudowane z innego źródła. Chociaż nazwa pliku libjnotify.so jest taka sama, są to różne pliki w różnych projektach Eclipse. Muszą być takie same w przypadku JNotify.
Zauważ, że ta sama nazwa pliku jest dołączana do pakietu hosta. W tym przypadku nazwa pliku to libjnotify.so.
Jeśli uruchomię je na moim 64-bitowym komputerze z ładowanym pakietem 64-bitowymprzed 32-bitowy, działa.
Jeśli jednak pakiet 32-bitowy zostanie załadowany jako pierwszy, otrzymuję:
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)
Oczywiście ładowana jest biblioteka 32-bitowa.Ale dlaczego? My Bundle-NativeCode definiuje hosta, który musi być 32-bitowym komputerem z Linuksem, aby korzystać z 32-bitowej wersji pakietu. Myślałem, że jeśli ta klauzula nie pasuje, biblioteka jest ignorowana?
Rzeczy, które próbowałemUsunięcie opcjonalnego symbolu wieloznacznego ... oznacza, że pakiety nie rozwiązują się