I’ve compiled OpenCV 4.4.0 from source on Windows 64 bit along with java bindings and I’m trying to compile a basic test, however I’m running into unexpected errors.
Here’s how I’ve setup an eclipse project:
and this how the jar references the native libraries:
And this is the basic test snippet:
import org.opencv.core.*; public class CVTest { public static void main(String[] args) { System.load(Core.NATIVE_LIBRARY_NAME); } }
which throws this exception:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library: opencv_java440 at java.lang.Runtime.load0(Runtime.java:806) at java.lang.System.load(System.java:1086) at CVTest.main(CVTest.java:8)
I’ve tried hardcoding the absolute path as a test:
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_java440.dll");
However I run into this exception:
Exception in thread “main” java.lang.UnsatisfiedLinkError:
C:Usersgeorge.profenzaDocumentseclipseCVTestlibopencv_java440.dll: Can't find dependent libraries at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1934) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1817) at java.lang.Runtime.load0(Runtime.java:809) at java.lang.System.load(System.java:1086) at CVTest.main(CVTest.java:9)
I didn’t expect this as I’ve compiled OpenCV 4 64-bit and I’m running this on JVM 1.8 64-bit.
I’ve tried manually loading one library at a time and using Dependency Walker and finally managed to instantiate a Mat
like so:
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_core440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_imgproc440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_imgcodecs440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_img_hash440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_videoio_ffmpeg440_64.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_videoio440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_photo440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_xphoto440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_flann440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_features2d440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_calib3d440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_phase_unwrapping440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_structured_light440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_xfeatures2d440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_video440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_ximgproc440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_aruco440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_bgsegm440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_bioinspired440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_objdetect440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_face440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_dnn440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_tracking440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_plot440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_ml440.dll"); System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_text440.dll"); // f.finally load the JNI wrapper native lib System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_java440.dll");
This works but hardcoding every single DLL in that order feels like a messy hack. Has anyone else ran into this scenario ?
What is the elegant way of loading the OpenCV 4 library in Java on Windows ?
To facilitate testing I’ve uploaded the following:
- opencv_440_windows32.zip: 32 bit headers/dynamic libraries (as well as java wrapper)
- opencv_440_windows64.zip: 64 bit headers/dynamic libraries (as well as java wrapper)
Update
Here are the static libs, including java bindings based on José’s excellent anwer:
Advertisement
Answer
Please, try to set the java.library.path
property to indicate the JVM where to find native libraries (I suppose you need to configure C:/Users/george.profenza/Documents/eclipse/CVTest/lib
in your case).
From the command line (or Eclipse Run/Debug configurations), you can include the required libraries as follows:
java -Djava.library.path=<path_to_dlls> <main class>
In the Java code, you can set the property like this:
System.setProperty(“java.library.path”, “/path/to/dlls”);
In addition to modifying the Run/Debug configurations to include the -Djava.library.path
in Eclipse, to set the java.library.path
property in this IDE you can follow several guides (look at this, for instance). Basically:
- Right click into your project in the
Package Explorer
. - Select the
Build Path → Configure Build Path...
option. - In the window that appears, select the
Libraries
tab. - Expand the
JRE System library
option, and select theNative library location
. - Click on the
Edit...
button at the right panel. - Locate the required libraries and then click
OK
.
It could be necessary to build the library without shared libs to avoid problems with dll dependencies. You can see an in depth explanation here. Note where the author says:
When OpenCV is built as a set of static libraries (
-DBUILD_SHARED_LIBS=OFF
option) the Java bindings dynamic library is all-sufficient, i.e. doesn’t depend on other OpenCV libs, but includes all the OpenCV code inside.