Wie verwende ich OSGi-Fragmente, um plattformabhängigen nativen Code mit demselben Dateinamen beizutragen?
Ich benutze dieJBenachrichtigen Projekt zum Abhören von Dateisystemereignissen. Dies hängt von einer nativen Bibliothek pro Betriebssystem ab: Prozessorarchitektur. Zum Beispiel gibt es eine Bibliothek für Windows x86, eine Bibliothek für x86-64 usw.
Monolithisches BündelUrsprünglich hatte ich ein Bundle, das sowohl die JNotify-Java-Klassen als auch den nativen Code enthielt. Der native Code wurde in Bundle-NativeCode wie folgt deklariert:
(Ich habe diese zur besseren Lesbarkeit im bnd-Stil formatiert ... offensichtlich sind die tatsächlichen MANIFEST.MF-Dateien richtig formatiert).
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,\
*
Das hat gut funktioniert.
Bewegen Sie sich zu FragmentenIch dachte, es wäre 'schön', wenn ich die Bibliotheken in separate Fragmentbündel verschieben würde, um nur die Fragmente für die Architektur beizutragen, die mich interessiert. Am Beispiel von Linux teile ich sie in zwei Bündel auf:
Linux 32 Bit
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
Beachten Sie, dass diese Bundles aus unterschiedlichen Quellen erstellt wurden. Der Dateiname libjnotify.so ist zwar derselbe, es handelt sich jedoch um unterschiedliche Dateien in verschiedenen Eclipse-Projekten. Sie müssen identisch sein, um mit JNotify arbeiten zu können.
Beachten Sie, dass derselbe Dateiname zum Host-Bundle hinzugefügt wird. In diesem Fall lautet der Dateiname libjnotify.so.
Wenn ich diese auf meinem 64-Bit-Computer mit dem geladenen 64-Bit-Bundle ausführeVor Die 32-Bit-Version funktioniert.
Wenn jedoch das 32-Bit-Bundle zuerst geladen wird, erhalte ich:
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)
Offensichtlich wird die 32-Bit-Bibliothek geladen.Aber warum? Mein Bundle-NativeCode definiert, dass der Host ein 32-Bit-Linux-Computer sein muss, um die 32-Bit-Bundle-Version zu verwenden. Ich dachte, wenn diese Klausel nicht übereinstimmt, wird die Bibliothek ignoriert?
Sachen die ich ausprobiert habeEntfernen des optionalen Platzhalters ... dies bedeutet nur, dass die Bundles nicht aufgelöst werden