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

如何在Quarkus中使用JNI?@QuarkusTest本地库加载失败求助

解决QuarkusTest中加载本地JNI库的UnsatisfiedLinkError问题

问题背景

本地库编译后位于项目target目录(Windows为MyLib.dll,Linux为MyLib.so),普通单元测试通过System.loadLibrary("MyLib")可正常使用,但在@QuarkusTest中抛出java.lang.UnsatisfiedLinkError: 'long org.acme.xxx.new_ObjectInMyLib()'错误。

解决方案

1. 正确配置Quarkus的JNI库路径

在测试环境配置文件(src/test/resources/application-test.properties)中添加:

# 直接指向target目录,跨平台自动适配
quarkus.jni.library-paths=${project.build.directory}

无需额外添加quarkus-core-deployment依赖,quarkus-core已包含JNI支持。

2. 手动加载库并刷新系统库路径(配置不生效时备用)

如果自动配置仍不生效,可在测试类启动前手动设置java.library.path并刷新JVM的库路径缓存:

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.BeforeAll;
import java.io.File;
import java.lang.reflect.Field;

@QuarkusTest
public class MyLibIntegrationTest {

    @BeforeAll
    static void initializeNativeLibrary() {
        // 获取target目录的绝对路径
        String targetDir = new File(System.getProperty("project.build.directory")).getAbsolutePath();
        // 更新java.library.path
        System.setProperty("java.library.path", targetDir);
        
        // 反射重置ClassLoader的sys_paths,触发JVM重新扫描库路径
        try {
            Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
            sysPathsField.setAccessible(true);
            sysPathsField.set(null, null);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException("Failed to refresh JVM library path", e);
        }
        
        // 加载本地库
        System.loadLibrary("MyLib");
    }

    // 测试用例...
}

3. 排查其他可能原因

  • 架构匹配:确保本地库的CPU架构(x86/amd64)与运行测试的JVM架构一致;
  • JNI签名一致性:用javah工具重新生成JNI头文件,确认Java方法的全限定名、参数/返回类型与本地库实现完全匹配;
  • DevServices影响:如果启用了Quarkus DevServices(如容器化测试),需确保容器内环境能访问到本地库(可将库挂载到容器中)。

内容的提问来源于stack exchange,提问作者Morlin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 18:43:12