我想在运行时将一个外部库(例如:\Lic4bit)加载到JVM,其中包含一些DLL文件。也不能使用反射和FFM(Java外部函数内存API)。
我尝试了一些方法,但仍然无法正确加载库。
最后我发现有一个名为 JAVA_LIBRARY_PATH
的
private static Final变量。所以我无法修改它,因为它是最终变量。
已经尝试过以下实现。
private static void loadAllDLLs(String libraryPathToAdd) {
final String[] userPath = initializePath("java.library.path");
String ps = System.getProperty("path.separator");
//check if the path to add is already present
for (String path : userPath) {
if (path.equals(libraryPathToAdd)) {
return;
}
}
StringBuilder pathBuilder = new StringBuilder();
for (String pathToAdd : userPath) {
pathBuilder.append(pathToAdd).append(ps);
}
pathBuilder.append(libraryPathToAdd);
// Update java.library.path once with all paths
String finalPath = pathBuilder.toString();
System.setProperty("java.library.path", finalPath);
String[] newUserPath = initializePath("java.library.path");
for (String up : newUserPath) {
System.out.println("New User Path ----> " + up);
}
}
但是后来我尝试使用
验证库是否已成功加载private static void loadLibraries() {
String libraryPath = System.getProperty("java.library.path");
System.out.println("java.library.path: " + libraryPath);
try {
System.loadLibrary("webcam-capture-driver-native-64");
System.out.println("Library loaded successfully.");
} catch (UnsatisfiedLinkError e) {
System.err.println("Failed to load library: " + e.getMessage());
}
}
System.out.println("java.library.path: " + libraryPath);
显示包含“webcam-capture-driver-native-64”的库已添加到 java.library.path
属性中。但是当使用 System.loadLibrary("webcam-capture-driver-native-64");
加载库时,会显示找不到库的异常。
有人已经遇到过这个问题或者有任何想法来处理这个问题吗?
问题的第二个答案java.lang.UnsatisfiedLinkError no *****.dll in java.library.path指出JVM仅读取库路径一次,这意味着即使您在运行时修改它, JVM 不会更新它,并且仍然会使用启动时加载的那个。
同样的答案也指向博客文章http://fahdshariff.blogspot.com/2011/08/changing-java-library-path-at-runtime.html,它解释了此问题的解决方案(以编程方式重置存储库路径的字段,以“强制”JVM 重新读取它)。
这可能不再适用于较新的 JDK 版本,因为 ClassLoader.class.getDeclaredFields()
将返回一个空列表。根据您的 JDK 版本,上述解决方案可能有效也可能无效。
.dll
文件的路径(包括其名称):
System.load(String filename);
...或者只是坚持运行命令:
java -Djava.library.path=/path/to/dir