I have NetBeans project from tutorial which causes exception:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'simpleDLL': The specified module could not be found.
Tried to put simpleDLL.dll in project libraries, copied file in system32 folder with no success.
I had exactly the same problem with loading a DLL, I solved it in this way:
As Christian Kuetbach said, check if the simpleDLL you are using is compatible with your processor's architecture, a 32-bit DLL won't work on a 64-bit machine, and also a 64-bit DLL won't work on a 32-bit machine.
If the DLL is compatible, then the problem may be in your java library path. I put my DLL into the user.dir directory and then I used this code:
Set Java library path to user.dir or maybe another path you want:
String myLibraryPath = System.getProperty("user.dir");//or another absolute or relative path
System.setProperty("java.library.path", myLibraryPath);
Load the library:
System.loadLibrary("libraryWithoutDLLExtension");
It worked for me, try it and tell me if it works for you.
Please check if the simpleDLL is 32 or 64 bit. Then check, if the JVM is also 32 or 64 bit. They have to be for the same platform.
You may also specify an absolute path, if you change loadLibrary() to load():
http://www.chilkatsoft.com/p/p_499.asp
I could only run in 32bit (Xp).
Place the DLL in the folder "c:\Windows\System32"
helloWorldDLL lib = (helloWorldDLL)
Native.loadLibrary("helloworldDLL", helloWorldDLL.class);
If the error java.lang.UnsatisfiedLinkError: Unable to load library" persists, use Dependency Walker to view the dependent DLLs.
Dependency Walker
Three possible reasons for this issue, if the dll file is not broken:
32 bit 64 bit Compatibility. 32bit dll can only be running on a 32bit jdk or jre.
By using Cygwin command file <filename> we can tell if a dll is 32bit or 64bit.
the dll is not lacated in the right path, so java cannot locate it. Generally speaking we can use some absolut path other than System32 to ensure that the path is right.
the dll that we are loading is requires other dlls.
How can we handle the 3rd possibility:
using JNI's System.loadLibrary() mthod can give me more hint, compared with JNA. It may says something like: Exception in thread "main" java.lang.UnsatisfiedLinkError: MyLibrary.dll: Can't find dependent libraries.
It means some libraries MyLibrary.dll depends is missing. By using dependency walker we can tell what dlls are needed.
By loading these dlls before the dll that we want to load, we can solve this issue.
Had the same problem and for some reason even if the dll filename has uppercase letters, you have to load it using all lowercase letters like this:
Native.loadLibrary("dlls/library.dll", YourInterface.class)
NOT this: Native.loadLibrary("dlls/Library.dll", YourInterface.class)
Related
I am experiencing a problem in Java (Eclipse) regarding the usage of dlls. Until now, I am experiencing the following problem:
Uncaught Exception for agent SomeAgent
java.lang.UnsatisfiedLinkError: SomePackage.SomeClass.SomeNativeMethod(II)Z
[...]
at jade.core.behaviours.Behaviour.actionWrapper(Behaviour.java:344)
at jade.core.Agent$ActiveLifeCycle.execute(Agent.java:1532)
at jade.core.Agent.run(Agent.java:1471)
at java.lang.Thread.run(Thread.java:745)
I don't know if this will help to figure out the problem, but I am also using JADE in this project...
EDIT (28/04/2014):
The dll which I am trying to use is a custom one (was created by an ex-employee from the company where I work).
The curious thing about this problem is that I have 2 java projects which perform similar tasks. One of this projects runs perfectly, while the other one is experiencing the UnsatisfiedLinkError.
About the paths: I've created a specific folder for the dlls which is contained in the workspace folder, but not inside the project folder (in other words, the same folder where bin, src, bibs, settings, etc. are). This folder's configuration is equal for the both projects I have. Also, I've already tested the System.out.println(System.getProperty("java.library.path") method and the right path is returned on both cases.
EDIT (29/04/2014):
Just added some additional information regarding the error messages. I am starting to think that the problem may be related to the JADE usage...
Here is a PD procedure that might help you identify the problem.
Add the following to your program to identify the differences in the arch and load paths between the two runtime environments. Investigate any differences in path/arch.
System.out.println(System.getProperty("java.library.path"));
System.out.println(System.getProperty("sun.arch.data.model"));
You can use the dumpbin.exe utility to identify the dependencies needed by the DLL that is being loaded.
Make sure the dependencies exist.
Example usage:
C:> dumpbin /imports your.dll
Dump of file your.dll
File Type: DLL
Section contains the following imports:
**KERNEL32.dll**
You can use the where.exe command to find the location of the dependencies.
Example usage:
C:>where KERNEL32.dll
C:\Windows\System32\kernel32.dll
If you see:
C:>where KERNEL32.dll
INFO: Could not find files for the given pattern(s)
Investigate why the dependent DLL is not on the path.
You can use the dumpbin.exe command to check 64bit vs 32bit.
Example:
C:>dumpbin /headers yourd.dll
Dump of file yourd.dll
PE signature found
File Type: DLL
FILE HEADER VALUES
14C machine (x86) <-- 32bit DLL
C:>dumpbin /headers yourd.dll
Dump of file yourd.dll
PE signature found
File Type: DLL
FILE HEADER VALUES
8664 machine (x64) <-- 64bit DLL
Investigate any 32bit vs 64bit mismatches between main/dependent. If your JVM is 32bit, you need to use 32bit DLLs. If your JVM is 64bit, you need to use 64bit DLLs. ( It is okay to run a 32bit JVM on a 64bit OS but the JNI DLLs must be 32bit ( DLLs match the JVM not the OS ).
Contrary to several answers here, this is not a library loading problem. See the stack trace. It's a problem locating the method named in the exception. This is caused by a mismatch between the actual and expected names. Popular causes:
not using javah to generate the .h file
method signature in .h and .c/.cpp file do not agree
not including the .h file in the .c or .cpp file
changing the package or name of the Java class after running javah
changing the method name or signature after running javah
If you do either of the last two you must re-run javah and adjust the .c/.cpp file to agree with the new signature in the new .h file.
This might be due to version mismatch or bit mismatch of your library. You may be working on 64 bit OS, use 64 bit compatible versions of your JAR files. Also check for version mismatch between JARS.
When you use some native library your system will check it in both environment variable and java.library.path. system property if it does not found there then it will throw java.lang.UnsatisfiedLinkError. Windows pick dll form system32 because system32 folder already exists in the path so there is very less change of error form this side. Native libraries make java code platform dependent. Check your java path for the required dll. Check your java.library.path and try to load your library(without dll extension) by using System.loadLibrary("library name"). Hope this help. :)
After doing some research, some people say I can add the following VM Argument in my project Run Configuration. In run time, JVM will search these directories to find DDLs.
-Djava.library.path="${workspace_loc}/GunCalibration/myLib/DLLs;${env_var:PATH}"
GunCalibration is my Java project folder in my workspace.
DLLs folder contains all my DLLs which are defined with my JNI specification.
As a result, I get this error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: D:\Software
x64\eclipse3.7\Kai\workspace_RealW\GunCalibration\myLib\DLLs\sixense.dll:
Can't find dependent libraries
However, if I copy some specific dll files to JAVA_HOME\jre6\bin, my code works correctly. (I do add this path into my system environment PATH.)
Could anyone explain why the first approach by using java.library.path doesn't work? How can I know which ddl is required to place in JAVA_HOME\jre6\bin?
Thank you a lot~
JAVA_HOME\jre6\bin is effectively in the system PATH (since it's the same directory as the java.exe program which is being run), which makes any DLLs there loadable by the system. java.library.path is mostly derived from the value of PATH, but it only affects where the VM looks for native libraries, not the system itself.
The VM can load any file explicitly based on the paths in java.library.path, but it cannot affect how the system looks up any dependent DLLs (other than telling the system to include the path to the initial DLL in its search -- see MSDN for LoadLibrary[Ex])
One alternative to copying the DLLs is to add the path to the DLLs to the PATH environment variable.
To import DLL into Eclipse Java project, I checked the "java.library.path"
String path = System.getProperty("java.library.path");
System.out.println(path);
One of the path values was equal to C:/Windows/System32. Therefore I saved myAPI.dll in C:/Windows/System32. Then I called System.loadLibrary:
System.loadLibrary("myAPI.dll");
And got the error message:
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library: myAPI.dll
at java.lang.Runtime.load0(Unknown Source)
at java.lang.System.load(Unknown Source)
BTW, I tried to put my DLL file in different other directories that was mentioned in path. But each time I got the same error message. How to solve this problem?
Don't put ".dll" at the end of your library. That is a Windows-specific extension, and your call will work on other systems with other extensions, so putting the extension on is incorrect. Just load "myAPI" and, if that's the right names and other things are as advertised, it will work.
One option is to try keeping that dll in your /jre/bin used in eclipse system library and was able to configure dll files at runtime , by placing dll in /jre/bin
It is the simplest way i could find out. This work for me.Hopefully will help you.:)
If the dll is in your project folder (e.g. part of your project), i.e.:
./prod/bin/myAPI.dll
and you want to execute the program/unit test within eclipse you can configure the runtime environment which runs your program. Go to "Preferences/Java/Installed JREs", choose the desired JRE or JDK (note: for loading a 32bit dll you must use a 32bit JRE, although your host system is a 64bit system), click on "Edit". In the box "Default VM arguments" you enter
-Djava.library.path="./prod/bin;${env_var:PATH}"
This adds your dll folder "prod/bin" in front of the system path (don't bother, it's not permanently, only for the environment of the chosen JRE).
By running following code you can verify that the system path was updated and the dll can be loaded:
String path = System.getProperty("java.library.path");
System.out.println(path);
System.loadLibrary("myAPI");
I'm getting the following error when trying to interface with a Magtek 32-bit DLL.
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: Unable to load library 'MCPAPI': The specified module could not be found.
I have no problem interfacing with user32.dll in the same code (just tweaking the DLL name and interface). Seems to indicate that the DLL can't be found, but it's most definitely in my jna.library.path. I've even gone as far as dumping it into the Windows system directory, next to user32, without success.
What am I missing here?
jna.library.path will only influence loading of libraries directly referenced. Dependent libraries must be found either in the same directory as the explicitly loaded one, or in PATH.
For your example to work, MCPAPI must be in either jna.library.path or PATH, and its dependent libraries must be either in the same directory or in PATH.
If you run a 64bit jvm you cannot load 32bit dll's. If thats the case, install 32bit jvm
try using System.load(path\to\library) instead System.loadLibrary().
I've been integrating simple java modules into the MATLAB environment on Windows with some success. Recently I encountered a problem with a third-party library which attempts to load a dll.
The java ClassLoader throws the UnsatisfiedLinkError when the load is attempted:
java.lang.UnsatisfiedLinkError: no <libname> in java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
The exception is reporting that my 'libname' is not in the java.library.path property. I have verified that the property does indeed have the correct path in it, and that the libname.dll file exists on that path.
I verified java.library.path in two ways. First, I simply checked that value returned on the MATLAB command line:
>> java.lang.System.getProperty('java.library.path')
Then, I modified the java method in question to print that value just before the call into the failing third-party function:
System.out.println(System.getProperty('java.library.path'));
Both confirmed that my path value was set as expected.
I've also tried manually loading the library from the command line, and it fails with the same results.
Is this something that is not possible in MATLAB, or am I missing something here? Unfortunately I'm not administrator on this machine so I can't try the old trick of moving the dll into a directory with dlls that do work.
I welcome any suggestions for things to try if there is no absolute answer.
Platform:
Windows XP
MATLAB R2009a
Java 1.6
Are you familiar with Process Monitor? (If not you will easily get how it works).
Download it. Run it. Just enable "Show File System Activity" (little icons on right under menu-bar), disable the others.
Then fire up whatever causes the library to try to load the dll. After the UnsatisfiedLinkError occured, stop the event capturing in Process Monitor.
Now do a CTRL+F and search for the name of the dll it should load. Check the (probably multiple) entry which say "Not Found" or "Name not found" in the result column and with the dll-name in the path column.
Now check where it really looks for the dll. Maybe it appends some additional path or similar and thus can't find it.
Just found this in the MATLAB docs:
Specifying the Search Path for Sun Java Native Method DLLs
The mechanism that MATLAB uses to locate native method libraries that are required by Java has changed. MATLAB no longer uses system environment variables to define the paths to these libraries.
Compatibility Considerations
If you presently rely on the PATH (for Windows) or LD_LIBRARY_PATH (for UNIX) environment variables for this purpose, you will need to use the file librarypath.txt, as described below, in its place.
Specifying the Java Library Path
Java classes can dynamically load native methods using the Java method java.lang.System.loadLibrary("LibFile"). In order for the JVM software to locate the specified library file, the directory containing it must be on the Java Library Path. This path is established when MATLAB launches the JVM software at startup, and is based on the contents of the file
$matlab/toolbox/local/librarypath.txt
(where $matlab is the MATLAB root directory represented by the MATLAB keyword matlabroot).
You can augment the search path for native method libraries by editing the librarypath.txt file. Follow these guidelines when editing this file:
Specify each new directory on a line by itself.
Specify only the directory names, not the names of the DLL files. The LoadLibrary call does this for you.
To simplify the specification of directories in cross-platform environments, you can use any of these macros: $matlabroot, $arch, and $jre_home.
Put the DLL that you try to load using java.lang.System.loadLibrary into the following directory:
$matlabroot\sys\java\jre\win??\jre\bin\
Does your library depend on other dlls? It could be that the dll java is loading as a result of its loadLibrary() call requires other dlls. On Windows, I believe it will look on %PATH% to try to find these dlls.
This isn't strictly a java thing; it's more to do with the native library you are loading.
Java is told where to find the dll via java.library.path (or whatever other mechanism Matlab uses), and the libname.dll will use %PATH% to find any dlls it depends on.
As you say that the missing dll is in your java.library.path, perhaps you could try appending the java.library.path value to %PATH% and trying again?