当前位置: 首页 > 面试题库 >

Java-通过相对路径加载dll,并将其隐藏在jar中

史绍晖
2023-03-14
问题内容

我正在开发应该以jar形式发布的Java应用程序。该程序取决于JNI调用的C
++外部库。要加载它们,我使用System.load带有绝对路径的方法,并且可以正常工作。

但是,我真的很想在JAR中“隐藏”它们,因此我创建了一个收集它们的包。这迫使我加载相对路径-
打包路径。通过这种方法,我让用户可以在任何目录中运行JAR,而不必担心链接DLL或对以前的安装过程感到厌烦。

这将引发预期的异常:

线程“主”中的异常java.lang.UnsatisfiedLinkError:期望库的绝对路径

我该如何工作?

第2部分

仅当我在eclipse环境下运行DLL时,将DLL复制到文件夹的方法才起作用。运行导出的JAR,可以很好地创建DLL二进制文件,但加载JNI则会引发下一个异常:

线程“主”中的异常java.lang.reflect.InvocationTargetException

        at
 org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56)
      Caused by: java.lang.UnsatisfiedLinkError:
 C:\Users\Supertreta\Desktop\nm files\temp\jniBin.dll: Can't find dependent
 libraries at java.lang.ClassLoader$NativeLibrary.load(Native Method)

我运行此加载方法:

public static void loadBinaries(){
        String os = System.getProperty("os.name").toLowerCase();

        if(os.indexOf("win") >= 0){
            ArrayList<String> bins = new ArrayList<String>(){{
                add("/nm/metadata/bin/dependence1.dll");
                add("/nm/metadata/bin/dependence2.dll");
                add("/nm/metadata/bin/dependence3.dll");
                add("/nm/metadata/bin/dependence4.dll");
                add("/nm/metadata/bin/jniBin.dll");
            }};

            File f = null;
            for(String bin : bins){
                InputStream in = FileManager.class.getResourceAsStream(bin);
                byte[] buffer = new byte[1024];
                int read = -1;
                try {
                    String[] temp = bin.split("/");
                    f = new File(TEMP_FOLDER, temp[temp.length-1]);     
                    FileOutputStream fos = new FileOutputStream(f);

                    while((read = in.read(buffer)) != -1) {
                        fos.write(buffer, 0, read);
                    }
                    fos.close();
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            System.load(f.getAbsolutePath());
        }
    }

我认为这可能是访问权限问题,但不知道如何解决。你怎么看?


问题答案:

我不相信您可以直接从JAR加载DLL。您必须采取将DLL从JAR中复制出来的中间步骤。下面的代码应该这样做:

public static void loadJarDll(String name) throws IOException {
    InputStream in = MyClass.class.getResourceAsStream(name);
    byte[] buffer = new byte[1024];
    int read = -1;
    File temp = File.createTempFile(name, "");
    FileOutputStream fos = new FileOutputStream(temp);

    while((read = in.read(buffer)) != -1) {
        fos.write(buffer, 0, read);
    }
    fos.close();
    in.close();

    System.load(temp.getAbsolutePath());
}


 类似资料:
  • 问题内容: 我的Java应用程序使用DL​​L库。我如何从JAR文件中使用它? DLL位于项目的源文件夹中。我必须将其包含在我的JAR中,在运行时将其提取(在jar的同一目录中)并加载它。 问题答案: 尝试加载dll之前,需要将dll放入库路径(推荐)。因此你将不得不从jar中提取它并将其复制到lib path中。 注意: ACWrapper是持有静态方法的类

  • 问题内容: 我有一个专有的jar,要作为依赖项添加到pom中。 但是我不想将其添加到存储库中。原因是我希望我通常的Maven命令(例如)可以mvn compile直接使用。(无需开发人员自己将其添加到某个存储库中)。 我希望该jar位于源代码管理的3rdparty库中,并通过pom.xml文件中的相对路径链接到它。 能做到吗?怎么样? 问题答案: 我希望该jar位于源代码管理的3rdparty库中

  • 我只是在尝试IntelliJ IDE,我想在java项目中添加一个外部jar。 我已经在

  • 问题内容: 说,我有两条绝对路径。我需要检查其中一条路径所指的位置是否为另一条路径的后代。如果为true,则需要从祖先找出后代的相对路径。用Python实现此功能的好方法是什么?我可以受益于任何图书馆? 问题答案: os.path.commonprefix()和os.path.relpath()是您的朋友: 因此,您可以测试公共前缀是否是路径之一,即,其中一个路径是否是公共祖先: 然后,您可以找到

  • 解决方案目录包含ExtraDlls和项目目录。在Project.csproj文件中,我们在ExtraDlls中有相对路径的dlls引用。ExtraDlls目录中的Dlls总是可用的。 使用下面的批处理文件发布web项目。但由于以下提到的细节,它失败了。 已尝试更改批处理文件中的根目录。i、 e.当根目录设置为包含MSBuild的根目录时。exe,还是同样的问题。 设置用$(SolutionDir)

  • 问题内容: 我想在固定位置引用一个jar文件,以供多个可执行jar使用,而不是在每个可执行文件中都包含该jar。我有以下设置可以正常工作 commons- math3-3.6.1.jar存在于目录testgradle中。TestGradle.jar包含main方法,并存在于目录testgradle / build / libs中 从testgradle / build / libs我运行: 一切正