É possível criar um único arquivo JAR com todas as dependências, incluindo as bibliotecas JNI nativas para uma ou mais plataformas. O mecanismo básico é usar System.load (File) para carregar a biblioteca em vez do System.loadLibrary (String) típico, que pesquisa a propriedade de sistema java.library.path. Este método torna a instalação muito mais simples, pois o usuário não precisa instalar a biblioteca JNI em seu sistema, mas às custas de todas as plataformas podem não ser suportadas, pois a biblioteca específica para uma plataforma pode não estar incluída no arquivo JAR único .
O processo é como se segue:
- inclua as bibliotecas JNI nativas no arquivo JAR em um local específico para a plataforma, por exemplo em NATIVE / $ {os.arch} / $ {os.name} /libname.lib
- criar código em um inicializador estático da classe principal para
- calcule o os.arch e os.name atuais
- procure a biblioteca no arquivo JAR no local predefinido usando Class.getResource (String)
- se existir, extraia-o para um arquivo temporário e carregue-o com System.load (File).
Eu adicionei funcionalidade para fazer isso para jzmq, as ligações Java de ZeroMQ (plug sem vergonha). O código pode ser encontrado aqui . O código jzmq usa uma solução híbrida para que, se uma biblioteca incorporada não puder ser carregada, o código reverterá para procurar a biblioteca JNI junto com java.library.path.
UnsatisfiedLinkError
as carregando o dll anterior implicitamente deseja carregar o último, mas não consigo encontrá-lo porque está oculto no jar. Também carregar o último dll primeiro não ajuda.DLL
devem ser conhecidos previamente e suas localizações devem ser adicionadas naPATH
variável de ambiente.https://www.adamheinrich.com/blog/2012/12/how-to-load-native-jni-library-from-jar/
é um ótimo artigo, que resolve meu problema.
No meu caso, tenho o seguinte código para inicializar a biblioteca:
fonte
Dê uma olhada no One-JAR . Ele embrulhará seu aplicativo em um único arquivo jar com um carregador de classes especializado que manipula "jars dentro de jars", entre outras coisas.
Ele lida com bibliotecas nativas (JNI) descompactando-as em uma pasta de trabalho temporária conforme necessário.
(Isenção de responsabilidade: eu nunca usei One-JAR, não precisei ainda, apenas o marquei para um dia chuvoso.)
fonte
1) Inclua a biblioteca nativa em seu JAR como um recurso. Por exemplo. com Maven ou Gradle, e o layout de projeto padrão, coloque a biblioteca nativa no
main/resources
diretório.2) Em algum lugar em inicializadores estáticos de classes Java, relacionados a esta biblioteca, coloque o código da seguinte forma:
fonte
JarClassLoader é um carregador de classes para carregar classes, bibliotecas nativas e recursos de um único monstro JAR e de JARs dentro do monstro JAR.
fonte
Você provavelmente terá que unjar a biblioteca nativa para o sistema de arquivos local. Pelo que eu sei, o trecho de código que faz o carregamento nativo examina o sistema de arquivos.
Este código deve ajudar você a começar (não o vejo há algum tempo e é para um propósito diferente, mas deve servir, e estou muito ocupado no momento, mas se você tiver dúvidas, deixe um comentário e responderei assim que puder).
fonte