2008-10-18 4 views
7

클래스를 찾지 못하면 생성 된 예외를 처리하는 동안 jthrowable의 메시지에 액세스하려고합니다. 그러나 jthrowable 객체의 getMessage() 메시지 ID에 액세스 할 수 없으며 그 이유를 알 수 없습니다. 나는 기쁨없이 getMessage의 서명을 "(Ljava/lang/String") 끝에 변경하려고 시도했다. (세미콜론을 사용하지 않았지만 꼭 필요한 것인가?) 나는 이것에 대해 지옥처럼 혼란 스럽다. 나는 toString을 getMessage로 대체하려고 시도해 보았고, 이 작동하지 않았다. 분명히 나는 ​​여기서 사소한 잘못을하고있다. 여기 JNI 코드가 jthrowable의 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; 
} 

(다른 것들 사이)이 코드의 출력은 다음과 같습니다

Compiled from "Throwable.java"
public class java.lang.Throwable extends java.lang.Object implements java.io.Serializable{
...
public java.lang.String getMessage();
Signature:()Ljava/lang/String;
...

:

Seriously, how do I get here?!
Exception in thread "main" java.lang.NoClassDefFoundError: com/planet/core360/docgen/Processor

javap -p -s java.lang.Throwable

나에게이 있습니다

답변

8

좋아, 내 문제는 마치 GetObjectClass이 당신이 원하는대로 행동하지 않는다는 것입니다. 그것을 jthrowable에 ct하거나 최소한 그것의 결과는 메서드를 가져 오는 목적으로는 유용하지 않습니다. 코드의 해당 부분을 다음 코드로 바꿉니다.

java_class = (*jEnv)->FindClass (jEnv, "java/lang/Throwable"); 
method = (*jEnv)->GetMethodID (jEnv, java_class, "getMessage", "()Ljava/lang/String;"); 

어쨌든 이상합니다. 나는 이것이 미래의 다른 누군가에게 도움이되기를 바랍니다.

+0

그것은 나를 도왔습니다! :-) –

+3

예외가 활성화되었을 때 GetObjectClass()가 작동하지 않을 수 있습니까? GetObjectClass를 호출하기 전에'(* env) -> ExceptionClear (env)'를 시도하십시오. – Qwertie

3

나는 당신의 접근 방식을 시도했고 그것은 나를 위해 일했다. 하지만 몇 가지 사항 : 나는 C++ 인터페이스를 사용하고 있지만 (차이는 없어야 함) 우분투 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!'를 사용했습니다; 다른 예외 유형으로 시도해보십시오!

관련 문제