多次执行 JAR 时无法加载 Java 中的 OpenCV 库 (Windows)

问题描述 投票:0回答:2

当我同时多次执行构建的 JAR 时,在 Java 中加载 OpenCV DLL 库时遇到问题。我得到的错误如下:

Caused by: java.lang.UnsatisfiedLinkError: Can't load library: C:\Users\xxx\AppData\Local\Temp\opencv_openpnp15738695246714582909
u\pattern\opencv\windows\x86_64\opencv_java320.dll

该异常发生在除一个 JAR 执行之外的所有 JAR 执行中。一个总是工作得很好。如果我一个接一个地执行 JAR,一切都会正常,但我需要同时执行它们(由于其他原因)。

我使用 Java 17 和 Maven org.openpnp.opencv 4.9.0,但在 OpenCV 3.2.0 上遇到相同的错误。 JAR 在 Windows 主机上执行。在代码中,我按如下方式加载库:

static {
    nu.pattern.OpenCV.loadLocally();
}

我尝试阅读一些源代码,我认为问题在于,如果操作系统是 Windows,OpenCV loadLocally() 方法会在启动时删除所有其他临时 DLL,因此在加载其他 JAR 执行之前删除了其他 JAR 执行的 DLL ,但错误发生后文件夹仍在 tmp 目录中(但其中没有 DLL 文件)。
OpenCV 代码:

if (OS.WINDOWS.equals(os)) {
      destination = new TemporaryDirectory().deleteOldInstancesOnStart().getPath().resolve("./" + location).normalize();
    } else {
      destination = new TemporaryDirectory().markDeleteOnExit().getPath().resolve("./" + location).normalize();
    }

执行后的DLL tmp文件夹:Temp Folder after Errors
Empty library tmp folder

有什么建议可以解决这个问题吗?或者还有其他方法可以正确执行此操作吗?

更新: 我通过将 DLL 文件从类路径复制到 tmp 目录并通过 System.load() 手动加载它来使其工作,但这样 DLL 文件将永远不会被删除并最终炸毁文件系统。有没有办法在 JVM 关闭后干净地删除这些文件?在 Linux 上,您可以使用关闭挂钩来执行此操作,但在 Windows 上,这不起作用,因为 DLL 文件以某种方式被锁定。

java windows opencv jar
2个回答
0
投票

您可以尝试使用 opencv-platform 而不是直接使用 opencv,因为它带有本机库。您可以轻松地在线获取其 jar 文件,或者如果您正在使用 Maven,则其依赖项存在于 Maven 中央存储库中。对于 Maven,您可以在 pom.xml 中添加此依赖项

    <dependency>
        <groupId>org.bytedeco</groupId>
        <artifactId>opencv-platform</artifactId>
        <version>4.9.0-1.5.10</version>
    </dependency>

0
投票

我刚刚想出了一个简单的方法。您可以将每个执行传递给自定义 tmp 目录。然后,OpenCV 仅删除当前执行的 tmp 目录中的 DLL 文件。我不知道我怎么没有早点得到这个,但这应该是这个问题的一个简单的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.