java - 在 JNA 中加载 DLL 时找不到指定的模块
问题描述
我有这个类初始化程序:
System.setProperty("java.library.path", "C:\\Users\\lucas\\Desktop\\libraries");
System.loadLibrary("libTTARCHHelper");
TTARCH_LIBRARY=(TtarchLibrary)Native.loadLibrary(TtarchLibrary.class);
DLL 位于C:\\Users\\lucas\\Desktop\\libraries\\libTTARCHHelper.dll
如果我在 Eclipse 中运行它,我会得到“找不到指定的模块”,如果我将它作为 JAR 运行,我会得到“java.library.path 中没有 libTTARCHHelper”。
我该如何解决这些问题?我什至尝试将 DLL 放在 PATH 环境变量的文件夹中。
使用文件直接加载进行完整调试:
Aug 26, 2020 12:28:51 AM com.sun.jna.Native extractFromResourcePath
INFO: Looking in classpath from jdk.internal.loader.ClassLoaders$AppClassLoader@c387f44 for /com/sun/jna/win32-x86-64/jnidispatch.dll
Aug 26, 2020 12:28:51 AM com.sun.jna.Native extractFromResourcePath
INFO: Found library resource at jar:file:/C:/Users/lucas/Desktop/My%20Stuff/Eclipse%20Workspaces/Build%20Paths/jna-5.6.0.jar!/com/sun/jna/win32-x86-64/jnidispatch.dll
Aug 26, 2020 12:28:51 AM com.sun.jna.Native extractFromResourcePath
INFO: Extracting library to C:\Users\lucas\AppData\Local\Temp\jna-103324076\jna5931694657592960137.dll
Aug 26, 2020 12:28:51 AM com.sun.jna.NativeLibrary loadLibrary
INFO: Looking for library 'C:\Users\lucas\Desktop\libraries\libTTARCHHelper.dll'
Aug 26, 2020 12:28:51 AM com.sun.jna.NativeLibrary loadLibrary
INFO: Adding paths from jna.library.path: null
Aug 26, 2020 12:28:51 AM com.sun.jna.NativeLibrary loadLibrary
INFO: Trying C:\Users\lucas\Desktop\libraries\libTTARCHHelper.dll
Aug 26, 2020 12:28:51 AM com.sun.jna.NativeLibrary loadLibrary
INFO: Loading failed with message: The specified module could not be found.
Aug 26, 2020 12:28:51 AM com.sun.jna.NativeLibrary loadLibrary
INFO: Adding system paths: []
Aug 26, 2020 12:28:51 AM com.sun.jna.NativeLibrary loadLibrary
INFO: Trying C:\Users\lucas\Desktop\libraries\libTTARCHHelper.dll
Aug 26, 2020 12:28:51 AM com.sun.jna.NativeLibrary loadLibrary
INFO: Loading failed with message: The specified module could not be found.
Aug 26, 2020 12:28:51 AM com.sun.jna.Native extractFromResourcePath
INFO: Looking in classpath from jdk.internal.loader.ClassLoaders$AppClassLoader@c387f44 for C:\Users\lucas\Desktop\libraries\libTTARCHHelper.dll
Aug 26, 2020 12:28:51 AM com.sun.jna.NativeLibrary loadLibrary
INFO: Loading failed with message: Native library (win32-x86-64/C:\Users\lucas\Desktop\libraries\libTTARCHHelper.dll) not found in resource path (C:\Users\lucas\eclipse-workspace\TEST\bin;C:\Users\lucas\Desktop\My Stuff\Eclipse Workspaces\Build Paths\jna-5.6.0.jar)
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'C:\Users\lucas\Desktop\libraries\libTTARCHHelper.dll':
The specified module could not be found.
The specified module could not be found.
其余的跟踪:
Native library (win32-x86-64/C:\Users\lucas\Desktop\libraries\libTTARCHHelper.dll) not found in resource path (C:\Users\lucas\eclipse-workspace\TEST\bin;C:\Users\lucas\Desktop\My Stuff\Eclipse Workspaces\Build Paths\jna-5.6.0.jar)
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:301)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:461)
at com.sun.jna.Library$Handler.<init>(Library.java:192)
at com.sun.jna.Native.loadLibrary(Native.java:646)
at com.sun.jna.Native.loadLibrary(Native.java:630)
at com.test.TTARCHHelper.<clinit>(TTARCHHelper.java:17)
at com.test.main.main(main.java:6)
Suppressed: java.lang.UnsatisfiedLinkError: The specified module could not be found.
at com.sun.jna.Native.open(Native Method)
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:191)
... 6 more
Suppressed: java.lang.UnsatisfiedLinkError: The specified module could not be found.
at com.sun.jna.Native.open(Native Method)
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:204)
... 6 more
Suppressed: java.io.IOException: Native library (win32-x86-64/C:\Users\lucas\Desktop\libraries\libTTARCHHelper.dll) not found in resource path (C:\Users\lucas\eclipse-workspace\TEST\bin;C:\Users\lucas\Desktop\My Stuff\Eclipse Workspaces\Build Paths\jna-5.6.0.jar)
at com.sun.jna.Native.extractFromResourcePath(Native.java:1095)
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:275)
... 6 more
所以看起来它没有找到它,它抛出了一个
java.lang.UnsatisfiedLinkError: The specified module could not be found.
我发现了问题,DLL 用于错误的位。Eclipse 在 64 上运行,JAR 使用 32 位 JVM。我也下载了 32 位 dll,现在运行 JAR 时它可以工作了。但是 Eclipse 中的 64 位 dll 不断抛出上面的模块异常
解决方案
jna.library.path
JNA 将在环境变量中的位置查找库。
一种选择是在 Eclipse 的运行配置中将其指定为命令行选项。在运行菜单中,选择运行配置。转到 (x)=Arguments 选项卡。在 VM 参数字段中添加:
-Djna.library.path=C:\Users\lucas\Desktop\libraries
您还可以在尝试加载 DLL 之前以编程方式在代码中设置它:
System.setProperty("jna.library.path", "C:\\Users\\lucas\\Desktop\\libraries");
正如您稍后在调试日志中指出的那样,它可能正在找到 DLL 但无法打开它。可能的原因可能是:
- DLL 运行时依赖于系统上不在适当路径中的另一个 DLL。一个常见的是 Visual C++ Distributable。您可能需要查阅 DLL 文档以获取更多信息。您有时可以使用SysInternals 库中的Process Monitor来尝试查看它正在打开什么。
- 具有上述依赖 DLL 的重复/不兼容版本
- 运行 64 位 JVM 并尝试打开不兼容 64 位的 DLL,反之亦然
- 您的 Java 程序可能无权读取您的库所在的目录
为了帮助诊断问题,请查看完整的堆栈跟踪。虽然最近的错误消息可能不相关(在“备份”搜索中找不到文件),但如果您查看跟踪,您可能会看到早期尝试打开 DLL 的多个抑制异常,这可能会为您提供更多信息性调试信息。
推荐阅读
- python - 使用 XGboost 作为分类器而不是神经网络的二值图像分类
- php - 为什么当我在 mysql 数据库中合并表时,值会重复?
- unit-testing - 如何在 AutoFixture 中更新夹具的自定义
- c - 我将错误长度的数组传递给函数。为什么我没有收到错误消息?
- c++ - 使用 C++ 模板匹配类型列表中的类型
- parallel-processing - 为什么 Pthread 虚拟内存使用与 OpenMP 不同?
- angular5 - 如何在角度 6 中动态创建元素上绑定事件?
- facebook-graph-api - Facebook Graph API 在异常时总是返回错误的请求错误
- python - python tkinter按钮不调用函数
- spring-integration - 使用建议处理 MessageHandlingException 并继续流程 spring 集成 dsl