java - para - generar jar desde linea de comando
JNA: dependencias de la Biblioteca Nativa y extracción de JAR (1)
Accederé al MSP430.dll (ver aquí) a través de JNA. Pero esta biblioteca tiene una dependencia a otra biblioteca nativa, que viene incluida con el MSP430.dll. Esta biblioteca nativa dependendiente se llama HIL.dll. Con el uso de jna.library.path todo funciona perfecto. Ahora incluiría las bibliotecas nativas en mi propio paquete .jar. Luego utilizaría la carga automática de la biblioteca nativa desde el jar del marco JNA. Pero esto crea problemas con las bibliotecas nativas que tienen dependencias. Si empaqueté el MSP430.dll y el HIL.dll en mi paquete .jar, entonces recibo el siguiente error: "JNA java.lang.UnsatisfiedLinkError y no se pudo encontrar el módulo especificado". Esto significa que no fue posible resolver las dependencias de MSP430.dll con HIL.dll. En los resultados de depuración de JNA puedo ver, solo el MSP430.dll extraerá del paquete .jar. En este contexto, el error es comprensible. En el siguiente camino, cargué el HIL.dll explícito y puedo ver la extracción de HIL.dll y luego de la MSP430.dll. Pero me detengo del error del módulo de JNA.
He buscado el código JNA del método de extracción. Veo que JNA extrae las bibliotecas nativas al directorio temporal del sistema y crea un propio directorio temporal en su. Pero ahora creo que el problema es que JNA crea archivos temporales para las bibliotecas nativas con el prefijo "jna" y un valor numérico único generado. Aquí la salida de JNA:
Found library ''HIL.dll'' at C:/Users/RD3/AppData/Local/Temp/jna-80961/jna1305152974718331988.dll
Creo que el MSP430.dll necesita HIL.dll sin asignar para encontrarlo. Tengo testet con carga directa de HIL.dll con siguiente como primera llamada en la aplicación
System.loadLibrary(C://absolutepath//HIL.dll);
Luego solo carga MSP430.dll a través de JNA desde el paquete .jar, esto funciona sin problemas. Después de eso cambio el nombre de HIL.dll a lol.dll y uso esta llamada:
System.loadLibrary(C://absolutepath//lol.dll);
luego recibo el error del módulo nuevamente de JNA. El MSP430.dll no pudo resolver el HIL.dll renombrado.
¿Es de todos modos posible empaquetar una biblioteca nativa con dependencias al paquete .jar y cargar con JNA?
Aquí el resultado de depuración JNA con la carga explícita de HIL.dll a través de JNA:
C:/Users/RD3/Desktop>call "C:/Program Files (x86)/Java/jre1.8.0_25/bin/java.exe"
-Djna.debug_load=true -jar C:/Data/Workspace/NetBeans/MspApiTest/target/MspApiTest-1.0.0-SNAPSHOT-jar-with-dependencies.jar
Looking in classpath from sun.misc.Launcher$AppClassLoader@1f96302 for /com/sun/jna/win32-x86/jnidispatch.dll
Found library resource at jar:file:/C:/Data/mstandfuss/Workspace/NetBeans/MspApiTest/target/MspApiTest-1.0.0-SNAPSHOT-jar-with-dependencies.jar!/com/sun/jna/win32-x86/jnidispatch.dll
Looking for library ''HIL.dll''
Adding paths from jna.library.path: null
Trying HIL.dll
Adding system paths: []
Trying HIL.dll
Looking for lib- prefix
Trying libHIL.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader@1f96302 for HIL.dll
Found library resource at jar:file:/C:/Data/mstandfuss/Workspace/NetBeans/MspApiTest/target/MspApiTest-1.0.0-SNAPSHOT-jar-with-dependencies.jar!/win32-x86/HIL.dll
Found library ''HIL.dll'' at C:/Users/RD3/AppData/Local/Temp/jna-80961/jna1305152974718331988.dll
Looking for library ''MSP430.dll''
Adding paths from jna.library.path: null
Trying MSP430.dll
Adding system paths: []
Trying MSP430.dll
Looking for lib- prefix
Trying libMSP430.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader@1f96302 for MSP430.dll
Found library resource at jar:file:/C:/Data/mstandfuss/Workspace/NetBeans/MspApi
Test/target/MspApiTest-1.0.0-SNAPSHOT-jar-with-dependencies.jar!/win32-x86/MSP430.dll
Exception in thread "main" java.lang.UnsatisfiedLinkError: Das angegebene Modul wurde nicht gefunden.
at com.sun.jna.Native.open(Native Method)
at com.sun.jna.Native.open(Native.java:1759)
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:260)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
at com.sun.jna.Library$Handler.<init>(Library.java:147)
at com.sun.jna.Native.loadLibrary(Native.java:412)
at com.sun.jna.Native.loadLibrary(Native.java:391)
at de.sitec.jmspflash.Msp430Native.<clinit>(Msp430Native.java:22)
at de.sitec.jmspflash.Msp430Impl.init(Msp430Impl.java:50)
at de.sitec.jmspflash.Msp430Impl.createMsp430Impl(Msp430Impl.java:36)
at de.sitec.mspapitest.App.main(App.java:34)
C:/Users/RD3/Desktop>
Atentamente
Suponiendo que el único problema que tiene es el nombre de la biblioteca dependiente, vea Native.extractFromResourcePath()
. Puede usarlo para extraer sus dependencias no explícitas y usar File.rename()
para asegurarse de que la biblioteca tenga el nombre que desea.