2008-10-18 17 views
7

Bir sınıf bulamadığım zaman oluşturulan bir özel durumu teslim ederken iletiye jperowable erişmeye çalışıyorum. Ancak, jthrowable nesnesindeki getMessage() ileti kimliğine erişemiyorum ve nedenini bilmiyorum. GetMessage imzasını "() Ljava/lang/String" e (sonunda noktalı virgül olmadan, ama bu gerekli, doğru mu?) Değiştirmeyi denemedim. Bunun hakkında kafam karıştı. Hatta getMessage'ı toString ile değiştirmeyi denedim ve'un çalışmadığı . Açıkçası burada önemsiz bir şey yapıyorum. İşte JNI kodum neden jthrowable'ın getMessage yöntemini başarılı bir şekilde bulamıyor?

ben kullanıyorum kodu:

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; 
} 

(diğer şeyler arasında) bu kodun çıktısı şu şekildedir:

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

bana bu verir

cevap

8

Pekala, benim sorunum gibi görünüyor, GetObjectClass, sizin de sevdiğiniz gibi davranmıyor Bir jedrowable üzerinde ct, ya da en azından sonuçları elde etme yöntemleri için yararlı değildir. Bu iş ile kodun bu bölümünün değiştirilmesi:

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

Bu çok garip, bu. Umarım bu, gelecekte bir başkasına yardım eder.

+0

Bu bana yardımcı oldu! :-) –

+3

Bir istisna aktifken GetObjectClass() işlevi çalışmıyor mu? GetObjectClass çağırmadan önce '(* env) -> ExceptionClear (env)' yi deneyin. – Qwertie

3

Yaklaşımınızı denedim ve benim için çalıştı. Birkaç şey olsa da: C++ arayüzünü kullanıyorum (bu bir fark yaratmamasına rağmen) ve Ubuntu 8.04'te Java 6 güncelleme 10, x64 sürümünü kullanıyorum. Belki de Java sürümü ve/veya kullanılan platform bir fark yaratacaktır.

#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(); 
} 

benim test için jnitest java/lang/InternalError 'Hello, world!' kullandım; Farklı istisna türleri ile denemek için çekinmeyin!

İlgili konular