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

栏目: java · 发布时间: 2021-04-13

简介  这篇文章主要介绍了如何从java本机接口调用getStackTrace方法(jni)(示例代码)以及相关的经验技巧,文章约2284字,浏览量119,点赞数1,值得参考!

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

hello JNI.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);
}

现在在这个代码中本机printStackTraceNative方法工作,它打印堆栈跟踪,但getStackTraceNative没有。当我检查核心转储文件时,它说java已经为java/lang/NoSuchMethodError抛出了一个异常getStackTrace。我很困惑,因为我传递给getStackTraceNative方法的参数是throwable类型,throwable应该有方法getStackTrace

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

答案

你的方法签名错了。在方法签名中,限定类名称中的句点将由正斜杠替换。因此,getStackTrace的签名是()[Ljava/lang/StackTraceElement;(也注意分号)

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,版权归原作者或者来源机构所有,感谢作者,如果未能解决你的问题,请参考以下文章。

回调函数(示例代码)

java 获取 正在执行的方法名

回调函数、Java接口回调 总结(示例代码)

2018第25周总结(示例代码)

异步消息的传递-回调机制