前言
在一些比较不同的公司中 没有提供java的sdk 需要调用dll so库等 需要用java-jni来调用
需要手动加载对应的lib到 内存中
示例
例如linux下加载 xxx.so 库
os中so、dll直接加载
直接在os目录中的 直接加载就是的
1 2 3 4
| System.loadLibrary("xxx");
System.load("/home/ming/xxx.so");
|
jar中的so、dll加载
既然是在java中 肯定是想打包进jar中 方便分发
这里以 maven管理项目的方式来演示
将 xxx.so 放进resources目录下 也就是 classLoader.getResource(“”)
然后在启动加载的时候 直接从jar中将库文件复制到os目录中 然后加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package com.ming.test;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import java.io.File; import java.io.InputStream; import java.io.OutputStream;
public class TestLoad { private static final Logger LOGGER = LoggerFactory.getLogger(TestLoad.class); private static final String SDK_NAME = "xxx";
static { LOGGER.info("load xxx.so...."); try { System.loadLibrary(SDK_NAME); } catch (Throwable e) { loadFromJar(); } }
private static void loadFromJar() { String name = SDK_NAME + ".so"; String path = "lib_" + System.currentTimeMillis() + "/"; try { InputStream in = TestLoad.class.getClassLoader().getResourceAsStream(name); File fileOut = new File(System.getProperty("java.io.tmpdir") + "/" + path + name); LOGGER.info("Writing so to: " + fileOut.getAbsolutePath()); OutputStream out = FileUtils.openOutputStream(fileOut); IOUtils.copy(in, out); in.close(); out.close(); System.load(fileOut.toString()); } catch (Exception e) { throw new RuntimeException("Failed to load required so", e); } } }
|
总结
简单记录一下 加载dll so库的方式
基本上就是直接通过环境变量+库名加载 或者直接通过绝对路径加载
如果是在jar中 就加载class的时候 复制到os的目录然后在加载