zoukankan      html  css  js  c++  java
  • Java导出成可运行Jar包 dll或者so加载失败的解决方案

    正常情况下, xxx.class.getResourceAsStream(lib) 这样就可以获取到了。但是我的是在JFrame的初始化中的, 所以需要Thread.currentThread().getContextClassLoader().getResourceAsStream(lib); 这样来获取。   这个坑  找了蛮久才找到解决方案记录下。

    嗯   看了一些解决方案,1、把库跟jar包一起拷贝打包 2、放入指定路径 添加环境变量 通过环境变量来获取库路径等等 终究还是比较麻烦的。  

    经过测试发现  本文的方案 还是没有最终解决这个问题   手里还有别的事  先放下了后面再研究

    private synchronized static void copyLib(String libFullName, String arch_libfile_suffix) throws IOException {
        InputStream in = null;   
        BufferedInputStream reader = null;   
        FileOutputStream writer = null;   
        File f = new File(".");
        
        String libs[] = { libFullName, libFullName.replace(arch_libfile_suffix, ".c"), libFullName.replace(arch_libfile_suffix, ".h") }; 
        for(int i = 0;i<libs.length;++i){
            File extractedLibFile = new File(f + File.separator + libs[i]);   
            if(!extractedLibFile.exists()){   
                //打包进jar中后, 可以用zip软件打开jar文件 看看你需要调用的dll或者so 在jar中的路径就是这个lib的值       
                String lib = libs[i].replace("lib" + File.separatorChar, "");
    //          String lib = libs[i];
                System.out.println("lib = " + lib);
                try {
                    // “/”代表Jar包的根目录
                    in = Thread.currentThread().getContextClassLoader().getResourceAsStream(lib);
                    //   踩过的坑  这些方式都没能够成功获取到。   这是因为我的获取是在UI线程中的。
                    //   MD5.class.getResourceAsStream("/" + libs[i]);
                    //   MD5.class.getClassLoader().getResourceAsStream("/" + libs[i]);
                    //   MD5.class.getResource(libFullName);
                    System.out.println(" getResourceAsStream == " +  lib);
                   
                    reader = new BufferedInputStream(in);
                    writer = new FileOutputStream(extractedLibFile);
     
                    byte[] buffer = new byte[1024];         
                    while (reader.read(buffer) > 0){
                        writer.write(buffer);
                        buffer = new byte[1024];
                    }
                } catch (IOException e){
                    e.printStackTrace();
                } finally {
                    if(in!=null)
                        in.close();
                    if(writer!=null)
                        writer.close();
                }
            }   
        }   
    }

    这种方案  经过测试在mac上面是可行的   但是在windows上面 总是拷贝lib失败  报 IOException 异常. 先记录 后面再解决

     还有下面这种解决方案,来自https://www.cnblogs.com/FlyingPuPu/p/7598098.html

     就是把Jar 当作zip文件遍历,找出需要加载的lib 然后拷贝到指定路径再进行加载

    /**
     * 加载项目下的native文件,DLL或SO
     *
     * @param dirPath 需要扫描的文件路径,项目下的相对路径
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public synchronized static void loader(String dirPath) throws IOException, ClassNotFoundException {
        Enumeration<URL> dir = Thread.currentThread().getContextClassLoader().getResources(dirPath);
        // 获取操作系统类型
        String systemType = System.getProperty("os.name");
        String systemArch = System.getProperty("os.arch");
        // 获取动态链接库后缀名
        String ext = (systemType.toLowerCase().indexOf("win") != -1) ? ".dll" : ".so";
        while (dir.hasMoreElements()) {
            URL url = dir.nextElement();
            String protocol = url.getProtocol();
            if ("jar".equals(protocol)) {
                JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
                JarFile jarFile = jarURLConnection.getJarFile();
                // 遍历Jar包
                Enumeration<JarEntry> entries = jarFile.entries();
                while (entries.hasMoreElements()) {
                    JarEntry jarEntry = entries.nextElement();
                    String entityName = jarEntry.getName();
                    if (jarEntry.isDirectory() || !entityName.startsWith(dirPath)) {
                        continue;
                    }
                    if (entityName.endsWith(ext)) {
                        loadJarNative(jarEntry);
                    }
                }
            } else if ("file".equals(protocol)) {
                File file = new File(url.getPath());
                loadFileNative(file, ext);
            }
        }
    }
  • 相关阅读:
    Python 爬虫js加密破解(一) 爬取今日头条as cp 算法 解密
    Python 爬虫实例(2)—— 爬取今日头条
    Python 爬虫实例(1)—— 爬取百度图片
    python 操作redis之——HyperLogLog (八)
    python 操作redis之——有序集合(sorted set) (七)
    Python操作redis系列之 列表(list) (五)
    Python操作redis系列以 哈希(Hash)命令详解(四)
    Python操作redis字符串(String)详解 (三)
    How to Install MySQL on CentOS 7
    Linux SSH远程文件/目录 传输
  • 原文地址:https://www.cnblogs.com/lesten/p/10629756.html
Copyright © 2011-2022 走看看