2008-10-18 10 views
7

मैं कक्षा को खोजने में असफल होने पर उत्पन्न अपवाद को संभालने के दौरान एक jthrowable में संदेश तक पहुंचने का प्रयास कर रहा हूं। हालांकि, मैं jthrowable ऑब्जेक्ट पर getMessage() की संदेश आईडी तक पहुंचने में असमर्थ हूं, और मुझे नहीं पता कि क्यों। मैंने getMessage के हस्ताक्षर को बदलने के लिए कोशिश की है (") Ljava/lang/स्ट्रिंग" (अंत में अर्धविराम के बिना, लेकिन यह जरूरी है, है ना?) कोई खुशी नहीं है। मैं इसके बारे में नरक के रूप में उलझन में हूँ। मैंने getString के साथ getMessage को बदलने की कोशिश की, और कि काम नहीं किया। जाहिर है, मैं यहां कुछ मामूली गलत कर रहा हूं।मेरा जेएनआई कोड सफलतापूर्वक एक 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 जिस तरह से आप एक्सपे करेंगे इसे एक जबरदस्त करने के लिए, या कम से कम इसके परिणाम विधियों के प्रयोजनों के लिए उपयोगी नहीं हैं। इस के साथ कोड के उस भाग की जगह काम करता है:

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

घिनौने रूप में अजीब, कि। मुझे उम्मीद है कि यह भविष्य में किसी और की मदद करता है, हालांकि।

+0

इससे मेरी मदद की! :-) –

+3

क्या यह संभव है कि अपवाद सक्रिय होने पर GetObjectClass() काम नहीं करता है? GetObjectClass को कॉल करने से पहले '(* env) -> अपवाद क्लीयर (env) 'आज़माएं। – Qwertie

3

मैंने आपके दृष्टिकोण की कोशिश की, और यह मेरे लिए काम किया। हालांकि कुछ चीजें: मैं सी ++ इंटरफ़ेस का उपयोग कर रहा हूं (हालांकि इससे कोई फर्क नहीं पड़ता), और मैं उबंटू 8.04 पर जावा 6 अपडेट 10, x64 संस्करण का उपयोग कर रहा हूं। संभवतः जावा संस्करण और/या मंच का उपयोग एक फर्क पड़ता है।

#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!' का उपयोग किया है; विभिन्न अपवाद प्रकारों के साथ प्रयास करने के लिए स्वतंत्र महसूस करें!