99#define MODIFIER_STATIC 9
1010
1111void javaReflectionGetMethods (JNIEnv *env, jclass clazz, std::list<jobject>* methods, bool includeStatic) {
12- jclass clazzclazz = env->GetObjectClass (clazz );
12+ jclass clazzclazz = env->FindClass ( " java/lang/Class " );
1313 jmethodID clazz_getMethods = env->GetMethodID (clazzclazz, " getMethods" , " ()[Ljava/lang/reflect/Method;" );
1414 jclass methodClazz = env->FindClass (" java/lang/reflect/Method" );
1515 jmethodID method_getModifiers = env->GetMethodID (methodClazz, " getModifiers" , " ()I" );
@@ -20,15 +20,26 @@ void javaReflectionGetMethods(JNIEnv *env, jclass clazz, std::list<jobject>* met
2020 jobject method = env->GetObjectArrayElement (methodObjects, i);
2121 jint methodModifiers = env->CallIntMethod (method, method_getModifiers);
2222 if (!includeStatic && (methodModifiers & MODIFIER_STATIC ) == MODIFIER_STATIC ) {
23- env->DeleteLocalRef (method);
2423 continue ;
2524 }
2625 methods->push_back (method);
2726 }
2827}
2928
29+ void javaReflectionGetConstructors (JNIEnv *env, jclass clazz, std::list<jobject>* methods) {
30+ jclass clazzclazz = env->FindClass (" java/lang/Class" );
31+ jmethodID clazz_getConstructors = env->GetMethodID (clazzclazz, " getConstructors" , " ()[Ljava/lang/reflect/Constructor;" );
32+
33+ jobjectArray constructorObjects = (jobjectArray)env->CallObjectMethod (clazz, clazz_getConstructors);
34+ jsize constructorCount = env->GetArrayLength (constructorObjects);
35+ for (jsize i=0 ; i<constructorCount; i++) {
36+ jobject constructor = env->GetObjectArrayElement (constructorObjects, i);
37+ methods->push_back (constructor);
38+ }
39+ }
40+
3041void javaReflectionGetFields (JNIEnv *env, jclass clazz, std::list<jobject>* fields) {
31- jclass clazzclazz = env->GetObjectClass (clazz );
42+ jclass clazzclazz = env->FindClass ( " java/lang/Class " );
3243 jmethodID clazz_getFields = env->GetMethodID (clazzclazz, " getFields" , " ()[Ljava/lang/reflect/Field;" );
3344 jclass fieldClazz = env->FindClass (" java/lang/reflect/Field" );
3445 jmethodID field_getModifiers = env->GetMethodID (fieldClazz, " getModifiers" , " ()I" );
@@ -260,8 +271,8 @@ jobject v8ToJava(JNIEnv* env, v8::Local<v8::Value> arg) {
260271 if (!isJavaObject.IsEmpty () && isJavaObject->IsBoolean ()) {
261272 JavaObject* javaObject = node::ObjectWrap::Unwrap<JavaObject>(obj);
262273 jobject jobj = javaObject->getObject ();
263- jclass nodeDynamicProxyClass = env->FindClass (" node/NodeDynamicProxyClass" );
264274
275+ jclass nodeDynamicProxyClass = env->FindClass (" node/NodeDynamicProxyClass" );
265276 if (env->IsInstanceOf (jobj, nodeDynamicProxyClass)) {
266277 jfieldID ptrField = env->GetFieldID (nodeDynamicProxyClass, " ptr" , " J" );
267278 DynamicProxyData* proxyData = (DynamicProxyData*)(long )env->GetLongField (jobj, ptrField);
@@ -513,3 +524,59 @@ int dynamicProxyDataVerify(DynamicProxyData* data) {
513524 printf (" *** ERROR: Lost reference to the dynamic proxy. You must maintain a reference in javascript land using ref() and unref(). ***\n " );
514525 return 0 ;
515526}
527+
528+ std::string methodNotFoundToString (JNIEnv *env, jclass clazz, std::string methodName, bool constructor, const v8::Arguments& args, int argStart, int argEnd) {
529+ std::ostringstream startOfMessage;
530+ std::ostringstream msg;
531+
532+ jclass classClazz = env->FindClass (" java/lang/Class" );
533+ jmethodID class_getName = env->GetMethodID (classClazz, " getName" , " ()Ljava/lang/String;" );
534+
535+ startOfMessage << " Could not find method \" " << methodName.c_str () << " (" ;
536+ for (int i=argStart; i<argEnd; i++) {
537+ jobject val = v8ToJava (env, args[i]);
538+ if (i != argStart) {
539+ startOfMessage << " , " ;
540+ }
541+ if (val == NULL ) {
542+ startOfMessage << " (null)" ;
543+ } else {
544+ jclass argClass = env->GetObjectClass (val);
545+ jstring argClassNameJava = (jstring)env->CallObjectMethod (argClass, class_getName);
546+ std::string argClassName = javaToString (env, argClassNameJava);
547+ startOfMessage << argClassName;
548+ }
549+ }
550+
551+ startOfMessage << " )\" on class \" " << javaObjectToString (env, clazz).c_str () << " \" ." ;
552+
553+ msg << startOfMessage.str () << " Possible matches:\n " ;
554+
555+ jclass memberClazz = env->FindClass (" java/lang/reflect/Member" );
556+ jmethodID member_getName = env->GetMethodID (memberClazz, " getName" , " ()Ljava/lang/String;" );
557+
558+ std::list<jobject> methods;
559+ if (constructor) {
560+ javaReflectionGetConstructors (env, clazz, &methods);
561+ } else {
562+ javaReflectionGetMethods (env, clazz, &methods, true );
563+ }
564+
565+ int count = 0 ;
566+ for (std::list<jobject>::iterator it = methods.begin (); it != methods.end (); it++) {
567+ jstring methodNameTestJava = (jstring)env->CallObjectMethod (*it, member_getName);
568+ std::string methodNameTest = javaToString (env, methodNameTestJava);
569+ if (methodNameTest == methodName) {
570+ msg << " " << javaObjectToString (env, *it).c_str () << " \n " ;
571+ count++;
572+ }
573+ }
574+
575+ if (count == 0 ) {
576+ std::ostringstream noMethodsMsg;
577+ noMethodsMsg << startOfMessage.str () << " No methods with that name." ;
578+ return noMethodsMsg.str ();
579+ }
580+
581+ return msg.str ();
582+ }
0 commit comments