首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java -通过相对路径加载dll并将它们隐藏在jar中

Java -通过相对路径加载dll并将它们隐藏在jar中
EN

Stack Overflow用户
提问于 2011-01-14 20:35:26
回答 4查看 45.6K关注 0票数 23

第1部分

我正在开发一个Java应用程序,它应该作为jar发布。这个程序依赖于JNI调用的C++外部库。要加载它们,我使用带有绝对路径的System.load方法,这很好用。

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

这会抛出预期的异常:

线程"main“java.lang.UnsatisfiedLinkError中的

异常:需要库的绝对路径

我怎么才能让它正常工作呢?

第2部分

将DLL复制到文件夹的方法(下面解释)仅当我在eclipse环境下运行它时才有效。运行一个导出的JAR,DLL二进制文件被很好地创建,但是加载JNI二进制文件会抛出下一个异常:

线程"main“java.lang.reflect.InvocationTargetException中的

异常

java.lang.ClassLoader$NativeLibrary.load(Native方法导致的java.lang.UnsatisfiedLinkError: C:\Users\Supertreta\Desktop\nm files\temp\jniBin.dll:找不到依赖库)

我运行这个加载方法:

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());
        }
    }

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-01-14 22:07:42

我不相信你可以直接从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());
}
票数 26
EN

Stack Overflow用户

发布于 2012-04-04 09:16:55

这个JarClassLoader旨在解决同样的问题:

http://www.jdotsoft.com/JarClassLoader.php

票数 2
EN

Stack Overflow用户

发布于 2011-01-14 20:50:50

基本上,这应该是可行的。由于JNA就是这样做的,所以只需下载并研究代码即可。YOu甚至有一些让这个平台独立的提示...

编辑

JNA将其本机代码带到jar中,在运行时解压正确的二进制文件并加载它。这可能是一个很好的模式来遵循(如果我对你的问题正确的话)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4691095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档