Es posible crear un solo archivo JAR con todas las dependencias, incluidas las bibliotecas JNI nativas para una o más plataformas. El mecanismo básico es usar System.load (Archivo) para cargar la biblioteca en lugar del típico System.loadLibrary (String) que busca la propiedad del sistema java.library.path. Este método hace que la instalación sea mucho más sencilla, ya que el usuario no tiene que instalar la biblioteca JNI en su sistema, a expensas, sin embargo, de que es posible que no todas las plataformas sean compatibles, ya que la biblioteca específica para una plataforma podría no estar incluida en el archivo JAR único. .
El proceso es el siguiente:
- incluir las bibliotecas JNI nativas en el archivo JAR en una ubicación específica de la plataforma, por ejemplo en NATIVE / $ {os.arch} / $ {os.name} /libname.lib
- crear código en un inicializador estático de la clase principal para
- calcula el os.arch y os.name actuales
- busque la biblioteca en el archivo JAR en la ubicación predefinida usando Class.getResource (String)
- si existe, extráigalo a un archivo temporal y cárguelo con System.load (Archivo).
Agregué funcionalidad para hacer esto para jzmq, los enlaces Java de ZeroMQ (enchufe desvergonzado). El código se puede encontrar aquí . El código jzmq utiliza una solución híbrida de modo que si no se puede cargar una biblioteca incrustada, el código volverá a buscar la biblioteca JNI a lo largo de java.library.path.
UnsatisfiedLinkError
mensaje al cargar el dll anterior que implícitamente quiere cargar el último, pero no puedo encontrarlo porque está oculto en el frasco. Además, cargar la última dll primero no ayuda.DLL
deben conocerse de antemano y sus ubicaciones deben agregarse en laPATH
variable de entorno.https://www.adamheinrich.com/blog/2012/12/how-to-load-native-jni-library-from-jar/
es un gran artículo, que resuelve mi problema ..
En mi caso, tengo el siguiente código para inicializar la biblioteca:
fuente
Eche un vistazo a One-JAR . Envolverá su aplicación en un solo archivo jar con un cargador de clases especializado que maneja "jarras dentro de jarras", entre otras cosas.
Se encarga de bibliotecas nativas (JNI) por desempaquetarlos a una carpeta de trabajo temporal según sea necesario.
(Descargo de responsabilidad: nunca he usado One-JAR, aún no lo he necesitado, solo lo he marcado como favorito para un día lluvioso).
fuente
1) Incluya la biblioteca nativa en su JAR como recurso. P.ej. con Maven o Gradle, y el diseño de proyecto estándar, coloque la biblioteca nativa en el
main/resources
directorio.2) En algún lugar de los inicializadores estáticos de las clases de Java, relacionados con esta biblioteca, coloque el código como el siguiente:
fuente
JarClassLoader es un cargador de clases para cargar clases, bibliotecas nativas y recursos desde un solo JAR monstruo y desde JARs dentro del JAR monstruo.
fuente
Probablemente tendrá que descomprimir la biblioteca nativa en el sistema de archivos local. Hasta donde yo sé, el fragmento de código que realiza la carga nativa examina el sistema de archivos.
Este código debería ayudarlo a comenzar (no lo he visto en un tiempo, y es para un propósito diferente, pero debería funcionar, y estoy bastante ocupado en este momento, pero si tiene preguntas, simplemente deje un comentario y responderé tan pronto como pueda).
fuente