You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Maven将*.so文件打包进*.jar并实现加载?部署遇阻求助

解决Linux下Spring Boot Jar加载内部.so文件的问题

问题根源

  • System.loadLibrary("mylib")依赖系统库路径或java.library.path,Jar内的.so文件不在这些路径范围内,直接调用无法加载。
  • Jar包属于压缩归档文件,内部资源无法通过getResource("//")获取文件系统路径,因此会返回null并报错。
  • 将.so文件放入BOOT-INF/lib目录时,Spring Boot会误将其识别为嵌套Jar包尝试解析,触发错误:Exception in thread "main" java.lang.IllegalStateException: 无法获取BOOT-INF/lib/libmylib.so条目对应的嵌套归档文件

正确实现步骤

1. Maven打包配置:将.so文件打包到Jar指定目录

在pom.xml中配置资源插件,把.so文件复制到Jar的BOOT-INF/classes/native自定义目录下,避免与其他资源冲突:

<build>
    <resources>
        <resource>
            <directory>src/main/resources/native</directory>
            <targetPath>BOOT-INF/classes/native</targetPath>
            <includes>
                <include>**/*.so</include>
            </includes>
        </resource>
    </resources>
    <!-- 保留原有Spring Boot打包插件配置 -->
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

将libmylib.so放入项目的src/main/resources/native目录中。

2. 编写加载代码:提取Jar内的.so到临时文件再加载

Jar内的资源无法直接被System.load加载,需先将.so文件复制到系统临时目录,再加载临时文件:

public class NativeLibLoader {
    public static void loadMylib() throws IOException {
        // 读取Jar内的.so资源
        String libResourcePath = "/native/libmylib.so";
        try (InputStream is = NativeLibLoader.class.getResourceAsStream(libResourcePath)) {
            if (is == null) {
                throw new RuntimeException("未找到libmylib.so资源");
            }
            // 创建临时文件,JVM退出时自动删除
            File tempLibFile = File.createTempFile("libmylib", ".so");
            tempLibFile.deleteOnExit();
            // 将资源写入临时文件
            try (FileOutputStream fos = new FileOutputStream(tempLibFile)) {
                byte[] buffer = new byte[1024];
                int readLen;
                while ((readLen = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, readLen);
                }
            }
            // 加载临时文件中的本地库
            System.load(tempLibFile.getAbsolutePath());
        }
    }
}

在业务代码初始化阶段调用NativeLibLoader.loadMylib()即可完成加载。

3. 运行Jar包

保持原有运行命令不变:

java -jar demo.jar -server -Dfile.encoding=UTF-8 -Dspring.profiles.active=prod

额外说明

  • 临时文件会在JVM退出时自动删除,不会残留垃圾文件。
  • 若需适配多架构(如x86_64、arm64),可根据系统架构动态选择对应路径的.so文件,例如/native/x86_64/libmylib.so。

内容的提问来源于stack exchange,提问作者豆沙饼

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 01:27:39