Como usar fragmentos OSGi para contribuir com código nativo dependente de plataforma com o mesmo nome de arquivo?
Estou usando oJNotify projeto para ouvir eventos do sistema de arquivos. Isso depende de uma biblioteca nativa por SO: arquitetura do processador. Por exemplo, há uma biblioteca para o Windows x86, uma biblioteca para x86-64 etc.
Pacote monolíticoOriginalmente, eu tinha um pacote que continha as classes JNotify Java e o código nativo. O código nativo foi declarado no Bundle-NativeCode da seguinte maneira:
(Eu formatado estes no estilo bnd para melhor legibilidade ... obviamente, os arquivos MANIFEST.MF reais são formados corretamente).
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,\
*
Isso funcionou bem.
Mover para fragmentosEu imaginei que seria "legal" se eu movesse as bibliotecas para fragmentos de fragmentos separados para que eu pudesse contribuir com os fragmentos para a arquitetura em que estou interessado. Tomando o exemplo do Linux, eu os divido em dois pacotes:
Linux 32 bits
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 bits
Include-Resource: lib/libjnotify.so
Bundle-NativeCode: libjnotify.so;osname = Linux;processor = x86-64,\
*
Fragment-Host: net.contentobjects.jnotify
Bundle-Version: 0.94.0
Observe que esses pacotes são criados a partir de uma fonte diferente. Embora o nome do arquivo libjnotify.so seja o mesmo, eles são arquivos diferentes em diferentes projetos Eclipse. Eles têm que ser o mesmo para trabalhar com o JNotify.
Observe que o mesmo nome de arquivo é contribuído para o pacote do host. Neste caso, o nome do arquivo é libjnotify.so.
Se eu executar estes na minha máquina de 64 bits com o pacote de 64 bits sendo carregadoantes o 32 bit um, funciona.
No entanto, se o pacote de 32 bits for carregado primeiro, recebo:
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)
Claramente a biblioteca de 32 bits está sendo carregada.Mas por que? Meu Bundle-NativeCode define que o host deve ser uma máquina Linux de 32 bits para usar a versão do pacote de 32 bits. Eu pensei que se essa cláusula não coincide, a biblioteca é ignorada?
Coisas que eu tenteiRemovendo o caractere curinga opcional ... isso significa que os pacotes não resolvem