在 Java 21 中运行时将外部本机库加载到 JVM

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

我想在运行时将一个外部库(例如:\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 jvm runtime dynamic-library java-21
1个回答
0
投票

问题的第二个答案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

	
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.