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. :)
Related
The Java application has the JNI module to use.
Where should a user (or an installation script of this application) put the JNI module on Linux (Ubuntu) or on MacOS X so that this JNI module could be loaded without specifying the path to the module in code?
This is a link to a detailed explanation of shared objects and how they are searched for by the OS.
I wish Java people would stop using LD_LIBRARY_PATH and start using the existing directory structures and the ld.so.conf mechanism. Even the OpenJDK libraries are dumped in a place that's not on a standard path and they don't add an ld.so.conf file either ( just how hard is that ? ).
This approach avoids the need to set up your own LD_LIBRARY_PATH and launch via a shell script.
If a required shared object is to be installed, first test for somewhere like /usr/local/lib as an installation choice system wide, and if it exists and an existing file does not already use your file's name, then put your library there. A more systematic approach would be to check all the ld.so.conf files and see if any of the directories match something you know can be used. A shell script can do that at install time.
Put the compiled libraries (.so files on Linux or .dylib on MacOS) into a directory of your choice and include this directory in the library search path LD_LIBRARY_PATH used to start your JVM.
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)
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.
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?