Pregunta

Estoy tratando de acceder al mensaje en un jthrowable mientras doy una excepción generada cuando no encuentro una clase. Sin embargo, no puedo acceder al ID de mensaje de getMessage () en el objeto jthrowable, y no sé por qué. He intentado cambiar la firma de getMessage a " () Ljava / lang / String " (Sin el punto y coma al final, pero eso es necesario, ¿verdad?) Sin alegría. Estoy confundido como un infierno sobre esto. Incluso intenté reemplazar getMessage con toString, y eso no funcionó. Obviamente estoy haciendo algo trivialmente mal aquí.

Aquí está el código que estoy usando:

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

La salida de este código (entre otras cosas) se ve así:

  

En serio, ¿cómo llego aquí ?!
  Excepción en el hilo " main " java.lang.NoClassDefFoundError: com / planet / core360 / docgen / Processor

javap -p -s java.lang.Throwable me da esto:

  

Compilado desde " Throwable.java "
  clase pública java.lang.Throwable extiende java.lang.Object implementa java.io.Serializable {
  ...
  public java.lang.String getMessage ();
    Firma: () Ljava / lang / String;
  ...

¿Fue útil?

Solución

De acuerdo, parece que mi problema fue que GetObjectClass no actúa de la manera que esperaría en un jthrowable, o al menos sus resultados no son útiles para los fines de conseguir métodos. Reemplazar esa parte del código con esto funciona:

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

Malditamente extraño, eso. Sin embargo, espero que esto ayude a alguien más en el futuro.

Otros consejos

Intenté tu enfoque, y funcionó para mí. Algunas cosas sin embargo: estoy usando la interfaz C ++ (aunque eso no debería hacer una diferencia), y estoy usando Java 6 actualización 10, edición x64, en Ubuntu 8.04. Quizás la versión de Java y / o la plataforma utilizada marcarán la diferencia.

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

He usado jnitest java / lang / InternalError 'Hello, world!' para mis pruebas; siéntase libre de probar con diferentes tipos de excepciones!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top