Loading DLL in Java - Eclipse - JNI - java

I am trying to load a dll in java using the following code
System.loadLibrary("mydll");
The project is placed in D:\development\project\ and i have placed the dll on D:. I then gave following VM argument in eclipse configuration
-Djava.library.path=D:/
But when i run i get UnsatisifiedLinkerError. After googling a bit, I used
System.load("D:\mydll.dll");
but again getting the same problem, could someone can help?

Where you specify the DLL filename in the library path, omit that. Additionally, your System.loadLibrary call should just be 'mydll'. I can tell you (from experience) that if you put the DLL in the root of your project in Eclipse (i.e., D:\Eclipse Workspace\Proj), it should work. Any further linker errors could be from dependency problems with finding other DLLs. The exception is the same. Use something like Dependency Walker (http://www.dependencywalker.com/) to see if your DLL relies on anything else not on the system library path.
Edit: UnsatisfiedLinkError: Thrown if the Java Virtual Machine cannot find an appropriate native-language definition of a method declared native -- it seems like you are using a JNI function which does not exist.

One problem you have is:
System.load("D:\mydll.dll");
should be
System.load("D:\\mydll.dll");
or
System.load("D:/mydll.dll");
I have had more success with System.load, but loadlibrary is better designed for multiplatform.
It figures out the extension for you.

Check out how to properly set up the native dependencies here. Additionally, make sure you use the correct JVM: in my case, the DLL was not found because it was a 32 bit DLL, but I used the x64 JVM!

Using System.loadLibrary("mydll") works fine, you can also use that one. If you used javah and you think with your DLL everything is fine, there are two possibilies:
The JVM does not find your DLL: In this case, your java library path is not correct (which I doubt) and you should probably set it to . and place your DLL in the current working dir.
The JVM does not find a DLL your DLL depends on: If you have any dependent libraries in your DLL, they are NOT searched by the JVM, but by Windows itself. And Windows does not know the java.library.path, so it will look in the system PATH variable for those. If you have the possibility, you can set the system PATH variable to the location of your DLLs before starting the JVM and everything will be fine. Or you can load all your DLLs using the JVM like this
System.loadLibrary("dll_1");
System.loadLibrary("dll_2");
System.loadLibrary("dll_3");
where dll_3.dll depends on dll_2.dll, which depends on dll_1.dll.
Hope that helps.

System.loadLibrary loads the DLL from the JVM path (JDK bin path).
If you want to load an explicit file with a path, use System.load()
See also: Difference between System.load() and System.loadLibrary in Java
public class MyClass
{
static
{
System.load("MyJNI.dll");
}
}

Put your Almafa.dll into the C:/Java/jre7/lib or /bin sorry, I can`t remember exactly. After you have done no more configuration needed, just say
static{
System.LoadLibrary("Almafa");
}
in the class, where you want to load it. It is works only in Java project, in Android like project you need to use JNI. I had posted now the result of 3 days no sleeping :)

I got my error resolved by using the following:
static {
try {
System.loadLibrary("myDLL");
} catch (Exception e) {
e.printStackTrace();
}
}
Instead of using System.load("myDLL.dll")

#alee- You can just copy and the paste the dll files in system32 folder of your windows and try to call the library through the System.loadLibrary("mydll")... i guess it may work...

Give the library path in your project as native library location,seems to be solved.

Related

java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()L

I can't run methods of a library.
My library is in my PATH and also getting loaded without errors by following code:
System.loadLibrary("FTDIInterface");
But the functions are not working.
I get the following exception:
Caused by: java.lang.UnsatisfiedLinkError: Messgeraet.src.net.sf.yad2xx.FTDIInterface.getDevices()[LMessgeraet/src/net/sf/yad2xx/Device;
at Messgeraet.src.net.sf.yad2xx.FTDIInterface.getDevices(Native Method)
at Messgeraet.src.Emu.EmuConnection.<init>(EmuConnection.java:22)
at Messgeraet.src.Emu.EmuModel.connect(EmuModel.java:27)
at Messgeraet.src.JavaFX.FXController.connect(FXController.java:112)
... 62 more
I am using eclipse. In IntelliJ it is working fine and I also got another eclipse project that includes the library without any problems.
Why it can't run my method FTDIInterface.getDevices?
Your package seems off; Messgereat.src sounds like you have a project dir named Messgereat, within you have a folder named 'src' with your java sources, and you've misconfigured your build tooling; the right package name sounds like it should be: package net.sf.yad2xx;, but due to a misconfigured build it wasn't working and you decided to fix the problem by updating your package statements, but that broke your JNI bindings.
The solution would then be to undo all the changes you've made to your package statements, and fix your build script instead.
Alternatively, if you really do intend to use that bizarre package, then make sure you have executed javah with the exact same build setup and use that as a basis for your JNI code. If you've done that, include the exported symbols in the library as the comment by #user2543253 suggested.
NB: It's a bit odd that your loadLibrary call works at all; PATH has nothing to do with it, but presuambly then your library so happens to be located in a place that is listed on your librarypath, which is the system property (of the VM, not of your OS) named 'java.library.path'; you set it with e.g.:
java -Djava.library.path=/path1:/path2 -cp /path/to/dep1.jar:/path/to/dep2.jar com.foo.Main
because of this confusion it is also possible that some different native lib file also named FTDIInterface is being loaded instead of the one you think is being loaded. If you want to be certain of what is being loaded, run System.load("/absolute/path/to/the/dll-jnilib-or-so-libraryfile.so"); - then you know for sure.

JNI - Specify the own executable as source for native methods

I have started a Java VM with JNI_CreateJavaVM. I want my java classes to be able to use native methods exported from the executable that started JNI_CreateJavaVM.
All around google results, people tell you to use System.loadLibrary to specify what library to import native methods from. However, doing
public class someclass
{
static { System.loadLibrary("myExeName.exe"); }
}
will fail FindClass with
java.lang.UnsatisfiedLinkError: no myExeName. in java.library.path
(I added -Djava.library.path=. as a JavaVMOption)
It seems Java cuts off the extension, which is a bummer as win32 LoadLibrary("myExeName.exe"); works when having the extension. (But it might bite me when I try to port to another OS)
Anyway, my question is if there are other/better ways specify which module to import the natives from.
P.S I am aware there is RegisterNatives, but I'm hoping there to be a more automatic way.
You can give the full path of your executable (not hard to guess on any OS) into System.load() function, but RegisterNatives is not too much code to write.

UnsatisfiedLinkError for JNI library

I have the following Java class that invokes a native library on Linux (/usr/local/lib/libCAPJni.so):
public class MyClass {
private native float runCAP(String name, int[] data);
private static final String LD_LIBRARY_PATH = "/usr/local/lib";
static {
System.setProperty("java.library.path", LD_LIBRARY_PATH);
System.loadLibrary("CAPJni");
}
...
}
The native library libCAPJni.so is located in /usr/local/lib. I also set this lib path in my Eclipse's Build Path -> Native library location. However when I launched my application in Eclipse, I got the following error:
java.lang.UnsatisfiedLinkError: no CAPJni in java.library.path
This seems to be caused by that the native lib is not found in /usr/local/lib directory. But if I directly run the following in command line:
java -Djava.library.path=/usr/local/lib MyClass
It runs fine without any problem. Why can't my Tomcat web application find the native library?
Specifying the native library path in Eclipse should definitely work.
However, it does NOT work to specify the library path at runtime with setting the system property. The library path must be known and set when booting the jvm.
I haven't worked with tomcat yet but as you mentioned it, make sure that tomcat starts with this parameter as well which might be your problem here.
EDIT:
As stated here it might actually be possible to change the library path later on. But as this is a hack and messes with the classloader it is most likely not a good idea to use that in the tomcat environment.

"Unable to load library: JNA native support not found in resource path" on trying to load JNA library on Mac OS X

I have a JNA library stub like this:
public interface FREngine extends Library {
NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance("FREngine");
FREngine INSTANCE = (FREngine) Native.loadLibrary("FREngine", FREngine.class);
}
If I try to use this library in any way, I get a really confusing error:
java.lang.UnsatisfiedLinkError: Unable to load library 'FREngine':
JNA native support (darwin/libFREngine.jnilib) not found in resource path
(...entire classpath here...)
Why this is confusing to me:
.jnilib is the file extension for JNI libraries. Since I'm using JNA, I wouldn't expect JNA to be using any JNI library other than its own one, "jnidispatch".
JNA is looking on the classpath for this file, but there is no way in hell it will be there because it's just some random library I'm trying to import. Shouldn't it be looking on DYLD_FRAMEWORK_PATH?
Other native libraries which are initialised in exactly the same way work fine. For instance, CoreFoundation can be resolved. Its code for loading the library is the same aside from the name of the library being different.
I tried looking at the frameworks themselves and can only see minor differences:
FREngine.framework is in /Library, CoreFoundation.framework is in /System/Library
FREngine.framework/Versions contains a directory with a longer and more complex name than CoreFoundation.framework, which only has one version called A.
FREngine.framework/Versions/[ver] contains Headers and Libraries
The version of JNA in use is 3.5.2. We can't upgrade to 4.x because there is some other bug which causes an exception as soon as we try to load our native library.
The reason why FREngine library does not work in this case in a wrong Engine load method. FREngine is expected to be loaded via com.abbyy.FREngine only.

How can I tell javac how to find the imageio-classes?

I'm new to java development, I just want to use javac for my build system. I'm using java to add a feature to a program someone else wrote, specifically involving GeoTiff images.
I found a class online that I would like to use, however I'm having trouble building the class, no matter what I do I get this message:
javac GeoTiffIIOMetadataAdapter.java
GeoTiffIIOMetadataAdapter.java:11: package com.sun.media.imageio.plugins.tiff does not exist
import com.sun.media.imageio.plugins.tiff.GeoTIFFTagSet;
I'm on RHEL5, so I installed the package I thought I needed, jai-imageio-core.x86_64. But the problem persists. I think that I'm not setting some variable corrently (like -sourcepath or something). I would appreciate any help.
You need to include the jar with -cp or -classpath.
So your compile would be like java -cp "<location to jai_imageio-1.1.jar>" <your java class> .
I think you need this jar file.
You can read more about javac here.
Find out where the package installed the jar file with the class you want to import, and add it to the javac commandline in the -classpath. (You then also need to include it in the classpath when your plugin runs; how to do that may depend on the program it plugs into).
I think that I'm not setting some variable correctly (like -sourcepath or something)
This tutorial briefly introduces the usage of environment variables in Java: PATH and CLASSPATH
This one seems to be the most popular answer to various classpath related questions I've seen at online forums: Setting the class path.
To avoid "blind recommendation" I quickly skimmed through it before adding to this answer and, well... it really covers most of what one needs to know to deal with classpath. Pretty good; the reason why I didn't look into it before is that there always has been some guru nearby who explained stuff to me.

Categories