如何从java本机接口(jni)调用getStackTrace方法

如何从java本机接口(jni)调用getStackTrace方法,java,java-native-interface,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[] getStackTraceN

我试图通过一些例子来理解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());
    }
}
本机代码(为了简单起见,避免错误处理)

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
printstacktracenactive
方法可以工作,它可以打印堆栈跟踪,但是,
getstacktracenactive
不能。当我检查核心转储文件时,它说java为
getStackTrace
抛出了一个异常
java/lang/NoSuchMethodError
。我感到困惑,因为我传递给GetStackTracenactive方法的参数是throwable类型,throwable应该具有方法
getStackTrace


我在这里可能遗漏了什么概念,在此感谢您的帮助。谢谢

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

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

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

你检查过你是否真的得到了一个方法id吗?在
java.lang.StackTraceeElement
之后是否缺少一个分号?我相信这就是发生错误的地方,我无法得到
getStackTrace
方法id,即使我像这样使用分号
()[Ljava.lang.StackTraceeElement;
它没有解决问题哦,那是因为那里有另一个错误,我一开始就漏掉了。它必须是
Ljava/lang/StackTraceeElement;
(正斜杠而不是句号)啊,我明白了,是的,这是个错误,顺便说一下,如果你回答这个问题,我会接受它