9

I'm using the following code to load a dll in JNA (irrelevant code is left out):

    public class JNAMain {
       public interface PointShapeBuffer extends Library { ... }

       public static void main(String[] args){
          System.setProperty("jna.library.path", "c:\\jnadll");
          System.setProperty("java.library.path", "c:\\jnadll");

          PointShapeBuffer jna = (PointShapeBuffer) Native.loadLibrary("FileGDBAPI", PointShapeBuffer.class);
       }
    }

And I get the following error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'FileGDBAPI': The specified module could not be found.

I've also tried setting the VM args. Any suggestions would be great.

Edit: For reference, I am using a publicly available library found here (registration is required).

Dave86
  • 91
  • 1
  • 1
  • 3
  • WIndows? Linus? PATH set to include shared lib on Windows? LD_LIBRARY_PATH on Linux? – bmargulies Jul 26 '11 at 01:14
  • This is Windows 7. The PATH environment variable has been changed to include "C:\jnadll", but I'm still getting the error. – Dave86 Jul 26 '11 at 17:58
  • Same problem here. I can load user32.dll just fine, but it pukes on trying to load any non-Windows 32-bit DLLs, no matter where I put them/how I point the path to them. – Brian Knoblauch Jul 28 '11 at 18:24
  • You shouldn't be setting java.library.path (and it'll only properly take effect if set prior to launching the VM anyway). Make sure your DLL and all its non-system dependencies are in the same directory, and that any system dependencies are in PATH. – technomage Jan 16 '12 at 12:35
  • "Make sure your DLL and all its non-system dependencies are" helped me. – Park JongBum May 07 '16 at 22:30

6 Answers6

8

In my experience you usally see this error when calling 32bit native dlls from a 64bit jvm on 64bit Win7. Win7 works differently for 64bit and 32bit applications.

On 64bit Win7 you can call functions in native 32bit dll's, but you need to use a 32bit JVM.

  1. Download and install 32bit Java Runtime Environment (JRE). You can install a 32bit and 64bit jvm on the same machine, just make sure they are installed in seperate directories.
  2. Ensure you run the 32bit JRE instead of the default 64bit JVM when you execute your program. Either A) change your CLASSPATH and JAVA_HOME environment variables to point to the 32bit jvm, or write a script to set the CLASSPATH and JAVA_HOME and launch you application.

The reason for this is 32bit dll's are incompatible with 64bit applications, and 64bit Win7 uses a 32bit emulator to run 32bit applications. Although Windows Libraries might be called named xxxx32.dll (e.g. user32.dll) the libraries in the System32 folder on a 64bit Win7 are 64bit libraries, not 32bit, and the libraries in SysWOW64 are 32bit libraries, confusing right?!?

You can also place the library in the 32bit system folder (SysWOW64) and make the JNI call from within a 32bit JVM.

Check out the following link for a full explanantion as how 64bit Win7 handles libraries;

http://www.samlogic.net/articles/32-64-bit-windows-folder-x86-syswow64.htm

And if you really want to help yourself get to sleep, trying starting on this ;)

http://msdn.microsoft.com/en-us/windows/hardware/gg463051.aspx

John O'Hara
  • 146
  • 1
  • 4
6

Change your:

Native.loadLibrary("FileGDBAPI", PointShapeBuffer.class);

to:

Native.loadLibrary("C:\\jnadll\\FileGDBAPI.dll", PointShapeBuffer.class);

If you dive into the jna source code enough you will find a nice little hook in the NativeLibrary class:

    /** Use standard library search paths to find the library. */
    private static String findLibraryPath(String libName, List searchPath) {
        //
        // If a full path to the library was specified, don't search for it
        //
        if (new File(libName).isAbsolute()) {
            return libName;
        }
        ...

So it will catch if you just passed an absolute path and not even use the searchPath. This was why you dont have to worry about jna.library.lib.

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
JHowIX
  • 1,683
  • 1
  • 20
  • 38
  • Don't know what to tell you.. maybe you have a different version of jna. This has worked for me and others and source code (copied from my version of jna) doesn't lie. – JHowIX Sep 25 '15 at 21:51
  • 2
    Turns out that the JNA doesn't distinguish between *not being able to find the dll* and *not being able to find dll dependencies*. So the DLL was all right, but was missing dependency as I found out using dependency walker. – Tomáš Zato Sep 26 '15 at 14:58
  • 2
    Actually it's WINDOWS that doesn't distinguish between the two.. the error box "Could not find the dll or one of its dependencies" has cost me many debugging hours – JHowIX Sep 26 '15 at 15:28
2

You need to specify the folder containing your DLL, not the DLL's actual path.

e.g. for baz.dll at c:\foo\bar\baz.dll, the path should be set to c:\\foo\\bar. (note in Java if you're using backspaces you'll have to escape them with backslashes)

Mark Elliot
  • 75,278
  • 22
  • 140
  • 160
  • Sorry for abstracting away the file path--I didn't want to give away anything sensitive on my work machine. The dll is now at C:\jnadll\FileGDBAPI.dll, but setting the paths to "c:\\jnadll" is still a no go. – Dave86 Jul 26 '11 at 17:55
  • 1
    @Dave: have you tried setting the system properties during the program call instead of in main? (`-Djna.library.path=c:\jnadll`) – Mark Elliot Jul 26 '11 at 23:37
  • Unfortunately that also didn't work. I used Dependency Walker to see if there were any missing references, and it threw this error at me: "Modules with different CPU types were found." This was for gpsvc.dll and sysntfy.dll, both 64-bit. I'm not able to find 32-bit versions, so I'm again stuck. – Dave86 Aug 01 '11 at 21:10
2

You might want to download the latest version with jna.jar and platform.jar and just include those. No need to set the path then.

RobotRock
  • 4,211
  • 6
  • 46
  • 86
  • I was having the same problem, but with a third-party application where I don't have access to the code. This answer solved the problem for me without changing the code. Thank you. – Paschoal May 26 '20 at 12:36
0

Like it was already mentioned in some comments: checks your Dependencies of your DLL/Library. Best Tool for this is Dependency Walker (http://www.dependencywalker.com/). Only if all your Dependencies are fulfilled, jna finds your DLL.... took me quite long to figure this out

conryyy
  • 127
  • 1
  • 9
-1

it is may be because there is the conflation into the lebweb kit. I am not sure but that has to be that only now u can do one thing try this.

$ dpkg -l | grep -i jna

try this command and if u getting this output

ii  libjna-java  3.2.7-4 Dynamic access of native libraries from Java without JNI

or any other output then this u need to remove then that jna from the system because if program itself have jna jar with that then there is no need of system jna for the same. so do something like this.

sudo apt-get autoremove libjna-java

and try for restart that application again. it will run and it is not running then try to install new version of libwebkit-gtk.

hope this will help. this helped me.

Kishan Bheemajiyani
  • 3,429
  • 5
  • 34
  • 68