如何在没有 System32 的情况下解决“java.lang.UnsatisfiedLinkError:找不到依赖库”?

Posted

技术标签:

【中文标题】如何在没有 System32 的情况下解决“java.lang.UnsatisfiedLinkError:找不到依赖库”?【英文标题】:How to solve "java.lang.UnsatisfiedLinkError: Can't find dependent libraries" without System32? 【发布时间】:2017-03-01 15:58:25 【问题描述】:

我正在 Eclipse 上开发一个 Java 项目,该项目通过 JNI 使用 C++ OpenCV 库。一些图像处理算法是在本机端使用 OpenCV 实现的,我希望使用 JNI 从 java 中使用它们。

我已经构建了一个 C++ DLL 项目来链接到 Java,这导致了一个 MyLibrary.dll 文件。我使用 GCC 6.3 编译器编译 OpenCV,并在 Eclipse CDT 上使用相同的 GCC 6.3 编译器(以及 MinGW Linker)编译了 C++ 代码。我还使用Dependency Walker 检查了是否存在任何依赖问题。到目前为止,我没有任何错误。

之后,我尝试从 Java 代码中加载库,如下所示:System.loadLibrary("MyLibrary")

我已经用-Djava.library.path=path\to\MyLibrary 设置了路径,并确保JVM 知道本机库的地址。我还在 MyLibrary.dll 旁边添加了所需的 OpenCV 库。

但是我得到以下错误:

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)
...

然后,当我将依赖的 OpenCV 库移动到 System32 文件夹中时,问题就消失了。

我的问题是;如何在不移动所需的 DLL 文件到 System32 文件夹的情况下解决此问题?

【问题讨论】:

这能回答你的问题吗? How to fix an UnsatisfiedLinkError (Can't find dependent libraries) in a JNI project 【参考方案1】:

解决这个问题的最佳做法是通过调用库加载方法自行加载依赖库:

System.loadLibrary("opencv_1");
System.loadLibrary("opencv_2");
...

现在加载依赖库后,您可以使用相同的方式安全地加载自己的 dll 文件:

System.loadLibrary("MyFile");

这应该可以解决can't file dependent libraries 错误。

另一种解决方法(不是最佳做法)是将依赖的 dll 文件(在您的情况下为 opencv dll)复制到 System32 文件夹。

为什么会这样?

我认为,当您设置java.library.path 参数时,您负责加载库的依赖库,而不是操作系统本身。我不确定是否诚实。

如How to fix an UnsatisfiedLinkError (Can't find dependent libraries) in a JNI project 中所述 ,您可以通过将-XshowSettings:properties -version 参数添加到虚拟机来检查您的路径。

【讨论】:

@isacikgoz 现在看起来很明显,但是当错误消息一直说:“找不到依赖库”时,我不知道真的有其他库需要加载。我使用 DLL 依赖walker 来查找依赖库并按照您的建议加载它们,现在它可以工作了!谢谢。【参考方案2】:

对于那些正在抱怨的人:Can't find dependent libraries 并访问此帖子以寻求解决方案:

这个抱怨意味着加载失败的 dll 依赖于其他一些 dll。通过使用 depedency walker:http://www.dependencywalker.com/,我们可以知道需要哪些 dll。通过在加载失败的dll之前加载它们(System.loadLibrary("dependedDll");),我们可以解决这个问题。

【讨论】:

【参考方案3】:

我在看到这个错误报告后解决了这个问题:

https://www.mail-archive.com/openjfx-dev@openjdk.java.net/msg22016.html

“如前所述,在安装了 Visual C++ 2019 可再发行组件的机器上不会引发上述异常。”

我下载了 2015-2019 年的 MS Visual C++ Redistributable,并将其安装在两台不同的计算机上,并使用了 offAdoptJDK、jre_8u_202 和 jre_8u_265 的不同组合,这解决了我的问题。

我从以下链接下载了可再发行组件: https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0

对于 Windows 10,我在上面安装了“x64: vc_redist.x64.exe”来解决我的问题。

【讨论】:

以上是关于如何在没有 System32 的情况下解决“java.lang.UnsatisfiedLinkError:找不到依赖库”?的主要内容,如果未能解决你的问题,请参考以下文章

我得到了StaleElementReferenceException.在以下情况下,我如何解决这个问题。

在 `System.Windows.Forms` 控件中没有 `ref` 关键字的情况下,如何通过引用传递

如何在没有硬编码 NetworkCredentials 的情况下使用 System.Net.Mail?

如何在没有 arch 的情况下获取内核版本

发生类型为 System.OutOfMemoryException 的异常。 如何解决

system权限怎么获得win10