Anders Anders - 18 days ago 8
Java Question

How to get JNA to extract several DLL files from a jar file?

I am working on a Java project in NetBeans using JNA. According to the JNA documentation, I can make my DLL:s available to Java by putting it in the jar:


Make your native library available on your classpath, under the path
{OS}-{ARCH}/{LIBRARY}
, where
{OS}-{ARCH}
is JNA's canonical prefix for native libraries (e.g.
win32-x86
,
linux-amd64
, or
darwin
). If the resource is within a jar file it will be automatically extracted when loaded.


This is what I want to do, so I have included the DLL:s in the project under
src/win32-x86-64
. If I build a jar-file with netbeans, and then include the jar file in another project everything works fine and JNA finds my library without a problem. This is what I get with
jna.debug_load
on:

Looking in classpath from sun.misc.Launcher$AppClassLoader@15db9742 for /com/sun/jna/win32-x86-64/jnidispatch.dll
Found library resource at jar:file:/C:/MyNetBeansProject/dist/lib/jna-4.2.2.jar!/com/sun/jna/win32-x86-64/jnidispatch.dll
Looking for library 'MyLibrary'
Adding paths from jna.library.path: null
Trying MyLibrary.dll
Adding system paths: []
Trying MyLibrary.dll
Looking for lib- prefix
Trying libMyLibrary.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader@15db9742 for MyLibrary
Found library resource at file:/C:/MyNetBeansProject/build/classes/win32-x86-64/MyLibrary.dll
Looking in C:/MyNetBeansProject/build\classes\win32-x86-64\MyLibrary.dll
Found library 'MyLibrary' at C:/MyNetBeansProject/build\classes\win32-x86-64\MyLibrary.dll


Apparently the DLL from the jar is not used. Instead the DLL from the build folder is used.

Now, if I move the jar-file to another folder and include it in my project, I get a
UnsatisfiedLinkError
. JNA gives the following output:

Looking in classpath from sun.misc.Launcher$AppClassLoader@70dea4e for /com/sun/jna/win32-x86-64/jnidispatch.dll
Found library resource at jar:file:/C:/SomeFolder/lib/jna-4.2.2.jar!/com/sun/jna/win32-x86-64/jnidispatch.dll
Looking for library 'MyLibrary'
Adding paths from jna.library.path: null
Trying MyLibrary.dll
Adding system paths: []
Trying MyLibrary.dll
Looking for lib- prefix
Trying libMyLibrary.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader@70dea4e for MyLibrary
Found library resource at jar:file:/C:/SomeFolder/MyNetBeansProject.jar!/win32-x86-64/MyLibrary.dll


It looks like JNA finds the DLL in the jar, but it does not try to extract it. I can not find it in my temp folder (where JNA extracts it's own internal DLL).

What is the problem here? Why doesn't JNA extract the file? How can I fix this?

(I don't know if this is relevant, but I should mention that my DLL depends on multiple other DLL files that are in the same folder in the jar. Not sure if JNA will extract them automatically for me, but so far it seems JNA isn't even extracting the DLL I am actually using.)

EDIT: There seems to be no problem locating
jnidispatch.dll
. According to the output when
jna.debug_load.jna
is set to
true
the file is found in the JAR and extracted to the temp folder.

Answer

JNA show error "UnsatisfiedLinkError" when dll couldn't be loaded. If your DLL needs another custom DLLs not present in the system path it will fail, as JNA doesn't extract this dll automatically.

JNA as a Java library doesn't know the dependencies of the system library, so it can extract from the jar. The solution is to specify all the dependencies in the JNA Java interfaces.

You can see an example here Load multiple libraries with JNA


What is happening behind the scenes of the Operating System

At the end, the libraries are loaded by the operating system as requested by the main executable. In this case the main executable is java.exe or (jvm.dll). If the system can't find a library in the path it fails and java generates an exception.

Another related and solved question is Registering multiple .dll libraries into a single java class using JNA

Comments