std::string methodNotFoundToString(JNIEnv *env, jclass clazz, std::string methodName, bool constructor, const v8::Arguments& args, int argStart, int argEnd) { std::ostringstream startOfMessage; std::ostringstream msg; jclass classClazz = env->FindClass("java/lang/Class"); jmethodID class_getName = env->GetMethodID(classClazz, "getName", "()Ljava/lang/String;"); startOfMessage << "Could not find method \"" << methodName.c_str() << "("; for(int i=argStart; i<argEnd; i++) { jobject val = v8ToJava(env, args[i]); if(i != argStart) { startOfMessage << ", "; } if(val == NULL) { startOfMessage << "(null)"; } else { jclass argClass = env->GetObjectClass(val); jstring argClassNameJava = (jstring)env->CallObjectMethod(argClass, class_getName); std::string argClassName = javaToString(env, argClassNameJava); startOfMessage << argClassName; } } startOfMessage << ")\" on class \""<< javaObjectToString(env, clazz).c_str() << "\"."; msg << startOfMessage.str() << " Possible matches:\n"; jclass memberClazz = env->FindClass("java/lang/reflect/Member"); jmethodID member_getName = env->GetMethodID(memberClazz, "getName", "()Ljava/lang/String;"); std::list<jobject> methods; if(constructor) { javaReflectionGetConstructors(env, clazz, &methods); } else { javaReflectionGetMethods(env, clazz, &methods, true); } int count = 0; for(std::list<jobject>::iterator it = methods.begin(); it != methods.end(); ++it) { jstring methodNameTestJava = (jstring)env->CallObjectMethod(*it, member_getName); std::string methodNameTest = javaToString(env, methodNameTestJava); if(methodNameTest == methodName) { msg << " " << javaObjectToString(env, *it).c_str() << "\n"; count++; } } if(count == 0) { std::ostringstream noMethodsMsg; noMethodsMsg << startOfMessage.str() << " No methods with that name."; return noMethodsMsg.str(); } return msg.str(); }
/*static*/ v8::Local<v8::Object> JavaObject::New(Java *java, jobject obj) { v8::HandleScope scope; JNIEnv *env = java->getJavaEnv(); obj = env->NewGlobalRef(obj); JavaScope javaScope(env); jclass objClazz = env->GetObjectClass(obj); jclass classClazz = env->FindClass("java/lang/Class"); jmethodID class_getName = env->GetMethodID(classClazz, "getName", "()Ljava/lang/String;"); jobject classNameJava = env->CallObjectMethod(objClazz, class_getName); std::string className = javaObjectToString(env, classNameJava); std::replace(className.begin(), className.end(), '.', '_'); std::replace(className.begin(), className.end(), '$', '_'); std::replace(className.begin(), className.end(), '[', 'a'); className = "nodeJava_" + className; v8::Persistent<v8::FunctionTemplate> persistentFuncTemplate; if(sFunctionTemplates.find(className) != sFunctionTemplates.end()) { //printf("existing className: %s\n", className.c_str()); persistentFuncTemplate = sFunctionTemplates[className]; } else { //printf("create className: %s\n", className.c_str()); v8::Local<v8::FunctionTemplate> funcTemplate = v8::FunctionTemplate::New(); funcTemplate->InstanceTemplate()->SetInternalFieldCount(1); funcTemplate->SetClassName(v8::String::NewSymbol(className.c_str())); std::list<jobject> methods; javaReflectionGetMethods(env, objClazz, &methods, false); jclass methodClazz = env->FindClass("java/lang/reflect/Method"); jmethodID method_getName = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;"); for(std::list<jobject>::iterator it = methods.begin(); it != methods.end(); it++) { jstring methodNameJava = (jstring)env->CallObjectMethod(*it, method_getName); std::string methodNameStr = javaToString(env, methodNameJava); v8::Handle<v8::String> methodName = v8::String::New(methodNameStr.c_str()); v8::Local<v8::FunctionTemplate> methodCallTemplate = v8::FunctionTemplate::New(methodCall, methodName); funcTemplate->PrototypeTemplate()->Set(methodName, methodCallTemplate->GetFunction()); v8::Handle<v8::String> methodNameSync = v8::String::New((methodNameStr + "Sync").c_str()); v8::Local<v8::FunctionTemplate> methodCallSyncTemplate = v8::FunctionTemplate::New(methodCallSync, methodName); funcTemplate->PrototypeTemplate()->Set(methodNameSync, methodCallSyncTemplate->GetFunction()); } std::list<jobject> fields; javaReflectionGetFields(env, objClazz, &fields); jclass fieldClazz = env->FindClass("java/lang/reflect/Field"); jmethodID field_getName = env->GetMethodID(fieldClazz, "getName", "()Ljava/lang/String;"); for(std::list<jobject>::iterator it = fields.begin(); it != fields.end(); it++) { jstring fieldNameJava = (jstring)env->CallObjectMethod(*it, field_getName); std::string fieldNameStr = javaToString(env, fieldNameJava); v8::Handle<v8::String> fieldName = v8::String::New(fieldNameStr.c_str()); funcTemplate->InstanceTemplate()->SetAccessor(fieldName, fieldGetter, fieldSetter); } sFunctionTemplates[className] = persistentFuncTemplate = v8::Persistent<v8::FunctionTemplate>::New(funcTemplate); } v8::Local<v8::Function> ctor = persistentFuncTemplate->GetFunction(); v8::Local<v8::Object> javaObjectObj = ctor->NewInstance(); javaObjectObj->SetHiddenValue(v8::String::New("__isJavaObject"), v8::Boolean::New(true)); JavaObject *self = new JavaObject(java, obj); self->Wrap(javaObjectObj); return scope.Close(javaObjectObj); }