Reputation: 350
I'm working on a Java project on Eclipse, which uses C++ OpenCV libraries via JNI. Some image processing algorithms are implemented with OpenCV on the native side, and I wish to use them from java using JNI.
I have built a C++ DLL project to link to Java, which resulted in a MyLibrary.dll
file. I compiled OpenCV with GCC 6.3 compiler and I compiled the C++ code with the same GCC 6.3 compiler on Eclipse CDT (along with MinGW Linker). I also checked if there are any dependency issues using Dependency Walker. I had no errors thus far.
Afterwards, I tried to load the library from Java code as follows:
System.loadLibrary("MyLibrary")
I have set the path with -Djava.library.path=path\to\MyLibrary
, and and made sure that JVM knows the address of the native libraries. I also added the required OpenCV libraries next to MyLibrary.dll
.
However I get the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: MyLibrary.dll: Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
...
Then the problem goes away, when I move the dependent OpenCV libraries into the System32
folder.
My question is; how can I solve this issue without moving the required DLL files into the System32
folder?
Upvotes: 3
Views: 25302
Reputation: 491
Sorry, I'll leave a note for myself.
Java JNI compiling with g++ (MinGW) including dependency dll:
g++ -c -I"C:\Program Files\Eclipse Adoptium\jdk-17.0.2.8-hotspot\include" -I"C:\Program Files\Eclipse Adoptium\jdk-17.0.2.8-hotspot\include\win32" UtilLib.cpp -o UtilLib.o
g++ -shared -o UtilLib.dll UtilLib.o -static-libgcc -static-libstdc++ -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive
Upvotes: 0
Reputation: 590
I just want to add because I experience this also. I use dependency walker and found that I needed to load opencv_world455.dll
first before loading my dll.
Upvotes: 0
Reputation: 21
I resolved this after coming across this bug report:
https://www.mail-archive.com/[email protected]/msg22016.html
"As previously mentioned, the above exception is not thrown on machines where the Visual C++ 2019 redistributable is installed."
I downloaded the MS Visual C++ redistributable for 2015-2019 and installed it on two different computers with diff combinations of offAdoptJDK, jre_8u_202, and jre_8u_265, and this resolved my issue.
I downloaded the redistributable from the link below: https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0
For Windows 10, I installed "x64: vc_redist.x64.exe" above to resolve my issue.
Upvotes: 2
Reputation: 4915
For ones who are hitting the complain: Can't find dependent libraries
and visiting this post for a solution:
this complain means that the dll which failed to load is depending on some other dlls. By using a depedency walker: http://www.dependencywalker.com/, we can tell what dlls are required. By loading them ( System.loadLibrary("dependedDll");
) before the failed loading dll, we can solve this issue.
Upvotes: 3
Reputation: 106
The best practice for this issue is to load dependent libraries by yourself with calling the library load method:
System.loadLibrary("opencv_1");
System.loadLibrary("opencv_2");
...
After you load dependent libararies now you can safely load your own dll file with the same way:
System.loadLibrary("MyFile");
This should resolve the can't file dependent libraries
error.
Another workaround (no the best practice) is to copy dependent dll files (in your case opencv dlls) to System32 folder.
Why this is happening?
I think, when you set java.library.path
argument, you are responsible to load dependent libraries of the library, not the OS itself. I'm not sure to be honest.
As mentioned in the How to fix an UnsatisfiedLinkError (Can't find dependent libraries) in a JNI project
, you can check your path by adding -XshowSettings:properties -version
argument to the virtual machine.
Upvotes: 6