JNA: native library dependencies and JAR extraction
I will be accessing MSP430.dll (see here) via JNA. But this library has a dependency on another native library that cames comes with MSP430.dll. This dependent native library is named HIL.dll. Using jna.library.path everything works fine. Now I would link the native libraries with my own .jar package. Then I will use the automatic loading of the loadable library from the JNA jar structure. But this creates problems with native libraries that have dependencies. If I package MSP430.dll and HIL.dll in my .jar package then I get the following error: "JNA java.lang.UnsatisfiedLinkError and the specified module could not be found." This means that the dependencies of MSP430.dll cannot be resolved with the HIL.dll file. In the JNA debug output I can see only MSP430.dll will be extracted from the .jar package.In this context, the error is understandable. In the next trail, I load the kernel HIL.dll and I can see the HIL.dll extract from the MSP430.dll file. But I am getting a module error from JNA.
I looked at the JNA code of the extract method. I see that JNA is pulling native libraries into the system temp directory and creating its own temp directory in them. But now I think the problem is that JNA creates temporary files for embedded libraries with "jna" prefix and unique generated numeric value. Here's the JNA output:
Found library 'HIL.dll' at C:\Users\RD3\AppData\Local\Temp\jna-80961\jna1305152974718331988.dll
I think MSP430.dll needs HIL.dll unmatched to find it. I have a testet with direct download of HIL.dll with the following as the first call in the application
System.loadLibrary(C:\\absolutepath\\HIL.dll);
Then only loads MSP430.dll via JNA from the .jar package, this works without issue. After that I rename HIL.dll to lol.dll and use this call:
System.loadLibrary(C:\\absolutepath\\lol.dll);
then I get the module error from JNA again. MSP430.dll was unable to resolve the renamed HIL.dll.
Is there anyway to package my own library with dependencies into a .jar package and load using JNA?
Here's the JNA debug output with explicit loading of HIL.dll via 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>
Regards
source to share
Assuming the only problem you are running into is the name of the dependent library, see Native.extractFromResourcePath()
. You can use this to fetch implicit dependencies and use File.rename()
it to make sure the library has the name you want.
source to share