动态库文件加载(Sys)

为什么记录?

Java 可以通过System.load()与System.loadLibrary()加载动态库。

  • 问题一 :loadLibrary()加载有libname参数指定的系统库。将库映射到实际系统库的方法取决于系统。load() 以指定的文件名加载代码文件。文件名必须是绝对路径。使用opencv时,需要系统能够work every where,所以需要使用load()方法。将dll或者so文件打包到jar下,并不能直接使用,需要将文件写到临时文件中。

  • 问题二 :动态文件加载一遍之后,bundle卸载重装,但karaf并没有重新启动,到日志bundle再次运行后出现文件已经加载,再次加载出错的问题。解决办法是在bundle停止运行或者卸载的时候,将动态文件释放。

1. 将jar包中的文件写到临时文件夹
//BIN_LIB为JAR包中存放DLL的路径
    //getResourceAsStream以JAR中根路径为开始点
    public static String getLib(String libName, String type) throws IOException {
       
        BufferedInputStream reader = null;
        FileOutputStream writer = null;
        String systemType = System.getProperty("os.name");
        String libExtension = (systemType.toLowerCase().indexOf("win") != -1) ? ".dll" : ".so";
        String libFullName = libName + libExtension;
        String nativeTempDir = System.getProperty("java.io.tmpdir");
        File extractedLibFile = new File(nativeTempDir + File.separator + libFullName);
        InputStream in = LibUtil.class.getResourceAsStream("/libs/" + libFullName);
        if (!extractedLibFile.exists()) {
            try {
                if (in == null)
                    in = LibUtil.class.getResourceAsStream(libFullName);
                LibUtil.class.getResource(libFullName);
                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();
            }
        }

        return extractedLibFile.toString();
    }
2. 卸载或释放动态链文件
// libName:动态文件全路径
public static synchronized void unloadNativeLibs(String libName) {
        try {
            ClassLoader classLoader = LibUtil.class.getClassLoader();
            Field field = ClassLoader.class.getDeclaredField("nativeLibraries");
            field.setAccessible(true);
            Vector libs = (Vector) field.get(classLoader);
            Iterator it = libs.iterator();
            while (it.hasNext()) {
                Object object = it.next();
                Field[] fs = object.getClass().getDeclaredFields();
                for (int k = 0; k < fs.length; k++) {
                    if (fs[k].getName().equals("name")) {
                        fs[k].setAccessible(true);
                        String dllPath = fs[k].get(object).toString();
                        if (dllPath.endsWith(libName)) {
                            Method finalize = object.getClass().getDeclaredMethod("finalize");
                            finalize.setAccessible(true);
                            finalize.invoke(object);
                            list.add(libName);
                        }
                    }
                }
            }
        } catch (Throwable th) {
            th.printStackTrace();
        }

    }






你可能感兴趣的:(动态库文件加载(Sys))