0%

java加载so、dll笔记

前言

在一些比较不同的公司中 没有提供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;

/**
* 加载linux下的so库
* <a href="https://stackoverflow.com/questions/1611357/how-to-make-a-jar-file-that-includes-dll-files">加载jar中的so库</a>
*
* @author ming
* @date 2023-07-11 16:04:52
*/
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() {
//linux 下是so文件
String name = SDK_NAME + ".so";
String path = "lib_" + System.currentTimeMillis() + "/";
try {
// 放在classPath下 需要从classLoader的目录下获取 如果是放在当前文件的包下 需要 TestLoad.class.getResourceAsStream(name); 即可
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的目录然后在加载