Skip to content

Commit a90ebd5

Browse files
committed
print stack trace on check exception
1 parent 390dbc4 commit a90ebd5

5 files changed

Lines changed: 58 additions & 42 deletions

File tree

src/java.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ void Java::destroyJVM(JavaVM** jvm, JNIEnv** env) {
215215
jclass classClazz = env->FindClass("java/lang/ClassLoader");
216216
jmethodID class_getClassLoader = env->GetStaticMethodID(classClazz, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
217217
jobject classLoader = env->CallStaticObjectMethod(classClazz, class_getClassLoader);
218-
assert(!env->ExceptionCheck());
218+
checkJavaException(env);
219219

220220
jobject result = env->NewGlobalRef(classLoader);
221221
return scope.Close(javaToV8(self, env, result));
@@ -520,7 +520,7 @@ void Java::destroyJVM(JavaVM** jvm, JNIEnv** env) {
520520
jmethodID string_charAt = env->GetMethodID(stringClazz, "charAt", "(I)C");
521521
jchar itemValues[1];
522522
itemValues[0] = env->CallCharMethod(val, string_charAt, 0);
523-
assert(!env->ExceptionCheck());
523+
checkJavaException(env);
524524
env->SetCharArrayRegion((jcharArray)results, i, 1, itemValues);
525525
}
526526
}
@@ -548,7 +548,7 @@ void Java::destroyJVM(JavaVM** jvm, JNIEnv** env) {
548548
jmethodID boolean_booleanValue = env->GetMethodID(booleanClazz, "booleanValue", "()Z");
549549
jboolean booleanValues[1];
550550
booleanValues[0] = env->CallBooleanMethod(val, boolean_booleanValue);
551-
assert(!env->ExceptionCheck());
551+
checkJavaException(env);
552552
env->SetBooleanArrayRegion((jbooleanArray)results, i, 1, booleanValues);
553553
}
554554
}

src/javaObject.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
jclass classClazz = env->FindClass("java/lang/Class");
2222
jmethodID class_getName = env->GetMethodID(classClazz, "getName", "()Ljava/lang/String;");
2323
jobject classNameJava = env->CallObjectMethod(objClazz, class_getName);
24-
assert(!env->ExceptionCheck());
24+
checkJavaException(env);
2525
std::string className = javaObjectToString(env, classNameJava);
2626
std::replace(className.begin(), className.end(), '.', '_');
2727
std::replace(className.begin(), className.end(), '$', '_');
@@ -63,7 +63,7 @@
6363
jmethodID field_getName = env->GetMethodID(fieldClazz, "getName", "()Ljava/lang/String;");
6464
for(std::list<jobject>::iterator it = fields.begin(); it != fields.end(); ++it) {
6565
jstring fieldNameJava = (jstring)env->CallObjectMethod(*it, field_getName);
66-
assert(!env->ExceptionCheck());
66+
checkJavaException(env);
6767
std::string fieldNameStr = javaToString(env, fieldNameJava);
6868

6969
v8::Handle<v8::String> fieldName = v8::String::New(fieldNameStr.c_str());

src/methodCallBaton.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ v8::Handle<v8::Value> MethodCallBaton::resultsToV8(JNIEnv *env) {
9393
jclass throwableClazz = env->FindClass("java/lang/Throwable");
9494
jmethodID throwable_getCause = env->GetMethodID(throwableClazz, "getCause", "()Ljava/lang/Throwable;");
9595
cause = (jthrowable)env->CallObjectMethod(m_error, throwable_getCause);
96-
assert(!env->ExceptionCheck());
96+
checkJavaException(env);
9797
}
9898

9999
v8::Handle<v8::Value> err = javaExceptionToV8(m_java, env, cause, m_errorString);

src/utils.cpp

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ void javaReflectionGetMethods(JNIEnv *env, jclass clazz, std::list<jobject>* met
1818
jmethodID method_getModifiers = env->GetMethodID(methodClazz, "getModifiers", "()I");
1919

2020
jobjectArray methodObjects = (jobjectArray)env->CallObjectMethod(clazz, clazz_getMethods);
21-
assert(!env->ExceptionCheck());
21+
checkJavaException(env);
2222
jsize methodCount = env->GetArrayLength(methodObjects);
2323
for(jsize i=0; i<methodCount; i++) {
2424
jobject method = env->GetObjectArrayElement(methodObjects, i);
@@ -36,7 +36,7 @@ void javaReflectionGetConstructors(JNIEnv *env, jclass clazz, std::list<jobject>
3636
jmethodID clazz_getConstructors = env->GetMethodID(clazzclazz, "getConstructors", "()[Ljava/lang/reflect/Constructor;");
3737

3838
jobjectArray constructorObjects = (jobjectArray)env->CallObjectMethod(clazz, clazz_getConstructors);
39-
assert(!env->ExceptionCheck());
39+
checkJavaException(env);
4040
jsize constructorCount = env->GetArrayLength(constructorObjects);
4141
for(jsize i=0; i<constructorCount; i++) {
4242
jobject constructor = env->GetObjectArrayElement(constructorObjects, i);
@@ -56,7 +56,7 @@ void javaReflectionGetFields(JNIEnv *env, jclass clazz, std::list<jobject>* fiel
5656
for(jsize i=0; i<fieldCount; i++) {
5757
jobject field = env->GetObjectArrayElement(fieldObjects, i);
5858
jint fieldModifiers = env->CallIntMethod(field, field_getModifiers);
59-
assert(!env->ExceptionCheck());
59+
checkJavaException(env);
6060
if((fieldModifiers & MODIFIER_STATIC) == MODIFIER_STATIC) {
6161
continue;
6262
}
@@ -141,7 +141,7 @@ JNIEnv* javaGetEnv(JavaVM* jvm, jobject classLoader) {
141141
jmethodID thread_currentThread = env->GetStaticMethodID(threadClazz, "currentThread", "()Ljava/lang/Thread;");
142142
jmethodID thread_setContextClassLoader = env->GetMethodID(threadClazz, "setContextClassLoader", "(Ljava/lang/ClassLoader;)V");
143143
jobject currentThread = env->CallStaticObjectMethod(threadClazz, thread_currentThread);
144-
assert(!env->ExceptionCheck());
144+
checkJavaException(env);
145145
env->CallObjectMethod(currentThread, thread_setContextClassLoader, classLoader);
146146
assert(!env->ExceptionCheck());
147147

@@ -157,9 +157,9 @@ jobject getSystemClassLoader(JNIEnv *env) {
157157
jmethodID thread_currentThread = env->GetStaticMethodID(threadClazz, "currentThread", "()Ljava/lang/Thread;");
158158
jmethodID thread_getContextClassLoader = env->GetMethodID(threadClazz, "getContextClassLoader", "()Ljava/lang/ClassLoader;");
159159
jobject currentThread = env->CallStaticObjectMethod(threadClazz, thread_currentThread);
160-
assert(!env->ExceptionCheck());
160+
checkJavaException(env);
161161
jobject result = env->CallObjectMethod(currentThread, thread_getContextClassLoader);
162-
assert(!env->ExceptionCheck());
162+
checkJavaException(env);
163163
return result;
164164
}
165165

@@ -227,13 +227,13 @@ jobject javaFindField(JNIEnv* env, jclass clazz, std::string& fieldName) {
227227
jmethodID field_getName = env->GetMethodID(fieldClazz, "getName", "()Ljava/lang/String;");
228228
jmethodID class_getFields = env->GetMethodID(clazzclazz, "getFields", "()[Ljava/lang/reflect/Field;");
229229
jobjectArray fieldObjects = (jobjectArray)env->CallObjectMethod(clazz, class_getFields);
230-
assert(!env->ExceptionCheck());
230+
checkJavaException(env);
231231

232232
jsize fieldCount = env->GetArrayLength(fieldObjects);
233233
for(jsize i=0; i<fieldCount; i++) {
234234
jobject field = env->GetObjectArrayElement(fieldObjects, i);
235235
jstring fieldNameJava = (jstring)env->CallObjectMethod(field, field_getName);
236-
assert(!env->ExceptionCheck());
236+
checkJavaException(env);
237237

238238
std::string itFieldName = javaToString(env, fieldNameJava);
239239
if(strcmp(itFieldName.c_str(), fieldName.c_str()) == 0) {
@@ -337,9 +337,9 @@ jobject v8ToJava_javaObject(JNIEnv* env, v8::Local<v8::Object> obj) {
337337
jclass objectClazz = env->FindClass("java/lang/Object");
338338
jmethodID object_getClass = env->GetMethodID(objectClazz, "getClass", "()Ljava/lang/Class;");
339339
jobject jobjClass = env->CallObjectMethod(jobj, object_getClass);
340-
assert(!env->ExceptionCheck());
340+
checkJavaException(env);
341341
classLoader = env->CallObjectMethod(jobjClass, class_getClassLoader);
342-
assert(!env->ExceptionCheck());
342+
checkJavaException(env);
343343
}
344344

345345
jclass proxyClass = env->FindClass("java/lang/reflect/Proxy");
@@ -357,12 +357,23 @@ jobject v8ToJava_javaObject(JNIEnv* env, v8::Local<v8::Object> obj) {
357357
return NULL;
358358
}
359359
jobj = env->CallStaticObjectMethod(proxyClass, proxy_newProxyInstance, classLoader, classArray, jobj);
360-
assert(!env->ExceptionCheck());
360+
checkJavaException(env);
361361
}
362362

363363
return jobj;
364364
}
365365

366+
void checkJavaException(JNIEnv* env) {
367+
if(env->ExceptionCheck()) {
368+
jthrowable ex = env->ExceptionOccurred();
369+
env->ExceptionClear();
370+
371+
std::string exString = javaExceptionToString(env, ex);
372+
printf("%s\n", exString.c_str());
373+
assert(false);
374+
}
375+
}
376+
366377
jobject v8ToJava_javaLong(JNIEnv* env, v8::Local<v8::Object> obj) {
367378
jobject longValue = v8ToJava(env, obj->Get(v8::String::New("longValue")));
368379
jclass longClazz = env->FindClass("java/lang/Long");
@@ -383,31 +394,34 @@ jobjectArray v8ToJava(JNIEnv* env, const v8::Arguments& args, int start, int end
383394
return results;
384395
}
385396

397+
std::string javaExceptionToString(JNIEnv* env, jthrowable ex) {
398+
jclass stringWriterClazz = env->FindClass("java/io/StringWriter");
399+
jmethodID stringWriter_constructor = env->GetMethodID(stringWriterClazz, "<init>", "()V");
400+
jmethodID stringWriter_toString = env->GetMethodID(stringWriterClazz, "toString", "()Ljava/lang/String;");
401+
jobject stringWriter = env->NewObject(stringWriterClazz, stringWriter_constructor);
402+
403+
jclass printWriterClazz = env->FindClass("java/io/PrintWriter");
404+
jmethodID printWriter_constructor = env->GetMethodID(printWriterClazz, "<init>", "(Ljava/io/Writer;)V");
405+
jobject printWriter = env->NewObject(printWriterClazz, printWriter_constructor, stringWriter);
406+
407+
jclass throwableClazz = env->FindClass("java/lang/Throwable");
408+
jmethodID throwable_printStackTrace = env->GetMethodID(throwableClazz, "printStackTrace", "(Ljava/io/PrintWriter;)V");
409+
env->CallObjectMethod(ex, throwable_printStackTrace, printWriter);
410+
checkJavaException(env);
411+
jstring strObj = (jstring)env->CallObjectMethod(stringWriter, stringWriter_toString);
412+
checkJavaException(env);
413+
414+
return javaToString(env, strObj);
415+
}
416+
386417
v8::Handle<v8::Value> javaExceptionToV8(Java* java, JNIEnv* env, jthrowable ex, const std::string& alternateMessage) {
387418
v8::HandleScope scope;
388419

389420
std::ostringstream msg;
390421
msg << alternateMessage;
391422

392423
if(ex) {
393-
jclass stringWriterClazz = env->FindClass("java/io/StringWriter");
394-
jmethodID stringWriter_constructor = env->GetMethodID(stringWriterClazz, "<init>", "()V");
395-
jmethodID stringWriter_toString = env->GetMethodID(stringWriterClazz, "toString", "()Ljava/lang/String;");
396-
jobject stringWriter = env->NewObject(stringWriterClazz, stringWriter_constructor);
397-
398-
jclass printWriterClazz = env->FindClass("java/io/PrintWriter");
399-
jmethodID printWriter_constructor = env->GetMethodID(printWriterClazz, "<init>", "(Ljava/io/Writer;)V");
400-
jobject printWriter = env->NewObject(printWriterClazz, printWriter_constructor, stringWriter);
401-
402-
jclass throwableClazz = env->FindClass("java/lang/Throwable");
403-
jmethodID throwable_printStackTrace = env->GetMethodID(throwableClazz, "printStackTrace", "(Ljava/io/PrintWriter;)V");
404-
env->CallObjectMethod(ex, throwable_printStackTrace, printWriter);
405-
assert(!env->ExceptionCheck());
406-
jstring strObj = (jstring)env->CallObjectMethod(stringWriter, stringWriter_toString);
407-
assert(!env->ExceptionCheck());
408-
409-
std::string stackTrace = javaToString(env, strObj);
410-
msg << "\n" << stackTrace;
424+
msg << "\n" << javaExceptionToString(env, ex);
411425

412426
v8::Local<v8::Value> v8ex = v8::Exception::Error(v8::String::New(msg.str().c_str()));
413427
((v8::Object*)*v8ex)->Set(v8::String::New("cause"), javaToV8(java, env, ex));
@@ -434,7 +448,7 @@ jvalueType javaGetArrayComponentType(JNIEnv *env, jobjectArray array) {
434448

435449
jmethodID class_getComponentType = env->GetMethodID(clazzclazz, "getComponentType", "()Ljava/lang/Class;");
436450
jobject arrayComponentTypeClass = env->CallObjectMethod(arrayClass, class_getComponentType);
437-
assert(!env->ExceptionCheck());
451+
checkJavaException(env);
438452

439453
jvalueType arrayComponentType = javaGetType(env, (jclass)arrayComponentTypeClass);
440454
return arrayComponentType;
@@ -571,15 +585,15 @@ v8::Handle<v8::Value> javaToV8(Java* java, JNIEnv* env, jobject obj) {
571585
jclass byteClazz = env->FindClass("java/lang/Byte");
572586
jmethodID byte_byteValue = env->GetMethodID(byteClazz, "byteValue", "()B");
573587
jbyte result = env->CallByteMethod(obj, byte_byteValue);
574-
assert(!env->ExceptionCheck());
588+
checkJavaException(env);
575589
return scope.Close(v8::Number::New(result));
576590
}
577591
case TYPE_LONG:
578592
{
579593
jclass longClazz = env->FindClass("java/lang/Long");
580594
jmethodID long_longValue = env->GetMethodID(longClazz, "longValue", "()J");
581595
jlong result = env->CallLongMethod(obj, long_longValue);
582-
assert(!env->ExceptionCheck());
596+
checkJavaException(env);
583597
std::string strValue = javaObjectToString(env, obj);
584598
v8::Local<v8::Value> v8Result = v8::NumberObject::New(result);
585599
v8::NumberObject* v8ResultNumberObject = v8::NumberObject::Cast(*v8Result);
@@ -592,7 +606,7 @@ v8::Handle<v8::Value> javaToV8(Java* java, JNIEnv* env, jobject obj) {
592606
jclass integerClazz = env->FindClass("java/lang/Integer");
593607
jmethodID integer_intValue = env->GetMethodID(integerClazz, "intValue", "()I");
594608
jint result = env->CallIntMethod(obj, integer_intValue);
595-
assert(!env->ExceptionCheck());
609+
checkJavaException(env);
596610
return scope.Close(v8::Integer::New(result));
597611
}
598612
case TYPE_SHORT:
@@ -608,7 +622,7 @@ v8::Handle<v8::Value> javaToV8(Java* java, JNIEnv* env, jobject obj) {
608622
jclass doubleClazz = env->FindClass("java/lang/Double");
609623
jmethodID double_doubleValue = env->GetMethodID(doubleClazz, "doubleValue", "()D");
610624
jdouble result = env->CallDoubleMethod(obj, double_doubleValue);
611-
assert(!env->ExceptionCheck());
625+
checkJavaException(env);
612626
return scope.Close(v8::Number::New(result));
613627
}
614628
case TYPE_FLOAT:
@@ -655,7 +669,7 @@ jobject javaFindMethod(JNIEnv *env, jclass clazz, std::string& methodName, jobje
655669
jstring methodNameJavaStr = env->NewStringUTF(methodNameCStr);
656670
jobjectArray methodArgClasses = javaObjectArrayToClasses(env, methodArgs);
657671
jobject method = env->CallStaticObjectMethod(methodUtilsClazz, methodUtils_getMatchingAccessibleMethod, clazz, methodNameJavaStr, methodArgClasses);
658-
assert(!env->ExceptionCheck());
672+
checkJavaException(env);
659673
return method;
660674
}
661675

@@ -702,7 +716,7 @@ std::string methodNotFoundToString(JNIEnv *env, jclass clazz, std::string method
702716
} else {
703717
jclass argClass = env->GetObjectClass(val);
704718
jstring argClassNameJava = (jstring)env->CallObjectMethod(argClass, class_getName);
705-
assert(!env->ExceptionCheck());
719+
checkJavaException(env);
706720
std::string argClassName = javaToString(env, argClassNameJava);
707721
startOfMessage << argClassName;
708722
}

src/utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ jobjectArray v8ToJava(JNIEnv* env, const v8::Arguments& args, int start, int end
6363
jobject v8ToJava(JNIEnv* env, v8::Local<v8::Value> arg);
6464
v8::Handle<v8::Value> javaExceptionToV8(Java* java, JNIEnv* env, const std::string& alternateMessage);
6565
v8::Handle<v8::Value> javaExceptionToV8(Java* java, JNIEnv* env, jthrowable ex, const std::string& alternateMessage);
66+
std::string javaExceptionToString(JNIEnv* env, jthrowable ex);
67+
void checkJavaException(JNIEnv* env);
6668
v8::Handle<v8::Value> javaArrayToV8(Java* java, JNIEnv* env, jobjectArray objArray);
6769
v8::Handle<v8::Value> javaToV8(Java* java, JNIEnv* env, jobject obj);
6870
jobjectArray javaObjectArrayToClasses(JNIEnv *env, jobjectArray objs);

0 commit comments

Comments
 (0)