java - 如何从java native 接口(interface)(jni)调用getStackTrace方法

标签 java java-native-interface

我试图通过一些例子来理解 jni。我正在尝试使用 jni 获取 java 堆栈跟踪,这就是我正在做的事情

HelloJNI.java

package test.com.jni;

public class HelloJNI {
    static {
        System.loadLibrary("hello"); // Load native library at runtime
    }

    private native StackTraceElement[] getStackTraceNative(Throwable throwable);
    private native void printStackTraceNative(Throwable throwable);

    public static void main(String[] args) {
        test();
    }

    public static void test() {
        new HelloJNI().printStackTraceNative(new Throwable()); //Invoke native method
        new HelloJNI().getStackTraceNative(new Throwable());
    }
}

native 代码(为了简单起见,保留错误处理)

test_com_jni_HelloJNI.c

JNIEXPORT jobjectArray JNICALL Java_test_com_jni_HelloJNI_getStackTraceNative (JNIEnv * env, jobject object, jthrowable exception) {

    jclass exceptionClazz = (*env)->GetObjectClass(env, exception); 

    jmethodID getStackTraceMethod = (*env)->GetMethodID(env, exceptionClazz, "getStackTrace", "()[Ljava.lang.StackTraceElement");

    jobjectArray stacktraces = (*env)->CallObjectMethod(env, exception, getStackTraceMethod);

    return stacktraces;
}

JNIEXPORT void JNICALL Java_test_com_jni_HelloJNI_printStackTraceNative (JNIEnv * env, jobject object, jthrowable exception) {

    jclass exceptionClazz = (*env)->GetObjectClass(env, exception); // can't fail

    jmethodID printStackTraceMethod = (*env)->GetMethodID(env, exceptionClazz, "printStackTrace", "()V");

    (*env)->CallVoidMethod(env, exception, printStackTraceMethod);
}

现在,在此代码中, native printStackTraceNative 方法可以工作,并且可以打印堆栈跟踪,但是 getStackTraceNative 却不能。当我检查核心转储文件时,它说 java 为 getStackTrace 抛出了异常 java/lang/NoSuchMethodError。我很困惑,因为我传递给 getStackTraceNative 方法的参数是 throwable 类型,而 throwable 应该具有 getStackTrace 方法。

我在这里可能缺少什么概念,对此的任何帮助表示赞赏。谢谢

最佳答案

您的方法签名错误。在方法签名中,限定类名中的句点被正斜杠替换。因此,getStackTrace 的签名为 ()[Ljava/lang/StackTraceElement;(另请注意分号)

您可以使用 javap-s 选项从类文件中获取方法签名:

javap -classpath '/path/to/jre/lib/rt.jar' -s java.lang.Throwable

关于java - 如何从java native 接口(interface)(jni)调用getStackTrace方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49989868/

相关文章:

java - 具有多个参数的 JNI 自定义异常

c# - 使用窗口消息传递在 JAVA 和 C# 之间进行应用程序间通信

java - Oracle 12c 与 Websphere 8.5 迁移问题

java - Spring Boot - OAuth2 - 所有请求都被禁止

java - 如何删除ArrayList中对象的属性

java - Android 上的 JNI,如何将 int 从 c 传递到 java

java - 如何创建具有多个静态库的 JNI Android Studio 项目

java - Crypto 将代码从 Node js 翻译为 Java

Java 泛型/通配符类型不匹配

android - JNI 和多线程