How to use OpenCV 4.4.0 (with contrib modules) in Java on Windows?

Tags: , ,



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:

Eclipse project displaying OpenCV java and native library files

and this how the jar references the native libraries:

Java project build properties of the OpenCV java library pointing to native DLLs

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:

Update

Here are the static libs, including java bindings based on José’s excellent anwer:

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:

  1. Right click into your project in the Package Explorer.
  2. Select the Build Path → Configure Build Path... option.
  3. In the window that appears, select the Libraries tab.
  4. Expand the JRE System library option, and select the Native library location.
  5. Click on the Edit... button at the right panel.
  6. 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.



Source: stackoverflow