我正在尝试在jthrowable中访问消息,同时处理在找不到类时生成的异常。但是,我无法在jthrowable对象上访问getMessage()的消息ID,我不知道为什么。我已经尝试将getMessage的签名更改为“()Ljava / lang / String”(最后没有分号,但这是必要的,对吧?)没有快乐。我对此很困惑。我甚至尝试用toString替换getMessage,而 无效。显然我在这里做了一些非常错误的事情。
这是我正在使用的代码:
jthrowable java_exception;
jclass java_class;
jmethodID method;
java_exception = (*jEnv)->ExceptionOccurred(jEnv);
assert (java_exception != NULL);
java_class = (*jEnv)->GetObjectClass (jEnv, java_exception);
assert (java_class != NULL);
method = (*jEnv)->GetMethodID (jEnv, java_class, "getMessage", "()Ljava/lang/String;");
if (method == NULL) {
printf ("Seriously, how do I get here?!\n");
(*jEnv)->ExceptionDescribe (jEnv);
return;
}
此代码的输出(以及其他内容)如下所示:
说真的,我怎么到这里来?!
线程“main”中的异常java.lang.NoClassDefFoundError:com / planet / core360 / docgen / Processor
javap -p -s java.lang.Throwable
给了我这个:
编译自“Throwable.java”
public class java.lang.Throwable extends java.lang.Object implements java.io.Serializable {
...
public java.lang.String getMessage();
签名:()Ljava / lang / String;
......
答案 0 :(得分:8)
好吧,看起来我的问题是GetObjectClass
没有像你期望的那样按照jthrowable的方式行事,或者至少它的结果对于获取方法没有用。用这个代替代码的那部分:
java_class = (*jEnv)->FindClass (jEnv, "java/lang/Throwable");
method = (*jEnv)->GetMethodID (jEnv, java_class, "getMessage", "()Ljava/lang/String;");
该死的奇怪。不过,我希望这有助于其他人。
答案 1 :(得分:3)
我尝试了你的方法,它对我有用。但有一些事情:我正在使用C ++接口(虽然这不应该有所作为),而且我在Ubuntu 8.04上使用Java 6 update 10,x64 edition。也许使用的Java版本和/或平台会有所作为。
#include <cstdio>
#include <jni.h>
int
main(int argc, char** argv)
{
if (argc != 3) {
std::fprintf(stderr, "usage: %s class message\n", argv[0]);
return 1;
}
JavaVM* jvm;
void* penv;
JavaVMInitArgs args = {JNI_VERSION_1_6};
if (jint res = JNI_CreateJavaVM(&jvm, &penv, &args)) {
std::fprintf(stderr, "Can's create JVM: %d\n", res);
return -res;
}
JNIEnv* env(static_cast<JNIEnv*>(penv));
jint vers(env->GetVersion());
std::printf("JNI version %d.%d\n", vers >> 16, vers & 0xffff);
env->ThrowNew(env->FindClass(argv[1]), argv[2]);
jthrowable exc(env->ExceptionOccurred());
std::printf("Exception: %p\n", exc);
if (exc) {
jclass exccls(env->GetObjectClass(exc));
jclass clscls(env->FindClass("java/lang/Class"));
jmethodID getName(env->GetMethodID(clscls, "getName", "()Ljava/lang/String;"));
jstring name(static_cast<jstring>(env->CallObjectMethod(exccls, getName)));
char const* utfName(env->GetStringUTFChars(name, 0));
jmethodID getMessage(env->GetMethodID(exccls, "getMessage", "()Ljava/lang/String;"));
jstring message(static_cast<jstring>(env->CallObjectMethod(exc, getMessage)));
char const* utfMessage(env->GetStringUTFChars(message, 0));
std::printf("Exception: %s: %s\n", utfName, utfMessage);
env->ReleaseStringUTFChars(message, utfMessage);
env->ReleaseStringUTFChars(name, utfName);
}
return -jvm->DestroyJavaVM();
}
我使用jnitest java/lang/InternalError 'Hello, world!'
进行测试;随意尝试不同的异常类型!