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

使用JNA和JUnit测试本地库:退出库后测试意外终止

JNA调用自定义本地库后程序意外终止问题

我开发了一个测试JNA集成Linux和Windows本地库的小型应用,用JUnit测试验证结果时遇到问题:第一个测试调用库方法后程序会意外终止,控制台能看到库方法输出的"welcome",但Java代码finally块里的"EXIT"从未打印,程序直接停止。

替换测试用系统库(比如libc.so的cosh方法)时,JUnit测试完全正常,多次调用也没问题,所以问题肯定出在我自己的本地库中。

Java相关代码

interface NativeLibraryInterface extends Library {
    static final String LIB_NAME_WINDOWS = "mylibW";
    static final String LIB_NAME_LINUX = "mylibL";

    NativeLibraryInterface INSTANCE = Native.load(Platform.isWindows() ? LIB_NAME_WINDOWS : LIB_NAME_LINUX, NativeLibraryInterface.class);

    int func1(int argc, String[] argv) throws LastErrorException;
}


public interface INativeLibraryApi {
    int myFunc1(String... args) throws LastErrorException;
}


public class NativeLibraryApi implements INativeLibraryApi {

    @Override
    public int myFunc1(String... args) throws LastErrorException {
        try {
            return NativeLibraryInterface.INSTANCE.func1(args.length, args);
        } catch (LastErrorException e) {
            System.out.println(e.getLocalizedMessage());
            return -1;
        } finally {
            System.out.println("EXIT");
        }
    }

}


final class NativeLibraryTest {
    static INativeLibraryApi nativeApi;

    @BeforeAll
    static void setup() {
        nativeApi = new NativeLibraryApi();
    }

    @Test
    void test1() throws Exception {
        int result = nativeApi.myFunc1("myArgA", "myArgB");
        assertEquals(0, result);
    }

    @Test
    void test2() throws Exception {
        int result = nativeApi.myFunc1("myArgC", "myArgD", "myArgE");
        assertEquals(0, result);
    }

}

自定义本地库代码

编译选项:-g -ansi -pedantic -Wall -Wextra -m64 -O0
链接选项:-shared

myLibrary.hpp

class MyLibrary {
public:
   MyLibrary ();
   ~MyLibrary ();

   int myFunc1 (
      int argc,
      char* argv[]
      );
};

extern "C" int func1 (int argc, char* argv[]);

myLibrary.cpp

#include "myLibrary.hpp"

MyLibrary::MyLibrary ()
{
}


MyLibrary::~MyLibrary ()
{
}


int MyLibrary::myFunc1 (int argc, char* argv[])
{
    std::cout << "welcome" << std::endl;
    exit (EXIT_SUCCESS);
}


extern "C" int func1(int argc, char* argv[])
{
   MyLibrary library;

   return library.myFunc1(argc, argv);
}

问题原因与解决方法

问题根源在本地库的myFunc1方法里调用了exit(EXIT_SUCCESS);——这个C标准库函数会直接终止整个进程,而不是返回给调用者。Java进程被这个exit调用直接杀死,导致Java代码的finally块根本没机会执行,程序直接终止。

解决方法很简单:把exit(EXIT_SUCCESS);替换成返回值,让函数正常返回给JNA:

int MyLibrary::myFunc1 (int argc, char* argv[])
{
    std::cout << "welcome" << std::endl;
    return EXIT_SUCCESS;
}

这样修改后,本地库函数执行完成后会正常返回,Java代码能继续执行finally块的逻辑,后续的JUnit测试也能正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:33:23