β

调用JNI的程序 生成JAR包后的部署问题

齐码代码 710 阅读

编写调用JNI的Java程序,都会先将C/C++的代码编译成DLL或者SO格式。随之而来的就是部署的问题。
1.如果是制作bat文件启动程序,当然就简便了,在bat文件中,把DLL文件(以DLL为例)所在的路径加入到java lib path中即可。
2.如果只是生成一个jar包,两种方法可以考虑:
1)让用户自己把DLL文件手动拷贝到java lib path中,或者添加一个path到DLL文件所在路径。此法对于开发人员来说相对简单,但是用户需要做很多额外操作。
2)Java中自己写一些代码,程序首次启动时候将所需要的DLL文件拷贝到java lib path中。
有人可能会想到,在Java代码中利用System.setProPerty设置lib path,指向DLL所在路径。不过此法不可行,因为一旦Java虚拟机启动以后,lib path就是只读的,就不能再设置进去值了。所以,想改lib path,只能是在程序启动前,手动修改或者利用bat文件修改。
对于2),给出简单的示例代码如下:

static {
        try { 
            String libpath = System.getProperty("java.library.path"); 
            String path = null; 
            StringTokenizer st = new StringTokenizer(libpath, System.getProperty("path.separator")); 
            if ( st.hasMoreElements() ) { 
                path = st.nextToken(); 
            }
 
            // copy all dll files to java lib path
            File dllFile = null;
            InputStream inputStream = null;
            FileOutputStream outputStream = null;
            byte[] array = null;
 
            dllFile = new File(new File(path), "JniCall.dll"); 
            if (!dllFile.exists()) { 
                inputStream = DOMTree.class.getResource("/jni/JniCall.dll").openStream(); 
                outputStream = new FileOutputStream(dllFile); 
                array = new byte[1024]; 
                for (int i = inputStream.read(array); i != -1; i = inputStream.read(array)) { 
                    outputStream.write(array, 0, i); 
                } 
                outputStream.close(); 
            }
 
            dllFile = new File(new File(path), "libxml2.dll"); 
            if (!dllFile.exists()) { 
                inputStream = DOMTree.class.getResource("/jni/libxml2.dll").openStream(); 
                outputStream = new FileOutputStream(dllFile);
                array = new byte[1024]; 
                for (int i = inputStream.read(array); i != -1; i = inputStream.read(array)) { 
                    outputStream.write(array, 0, i); 
                } 
                outputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } 
 
        try {
            // load JniCall.dll
            System.loadLibrary("JniCall");
        } catch (Error e) {
            e.printStackTrace();
        }
    }
作者:齐码代码
记录我的程序员之路
原文地址:调用JNI的程序 生成JAR包后的部署问题, 感谢原作者分享。