Skip to content

Commit 3275d48

Browse files
committed
fix lucene example
1 parent 1c65e57 commit 3275d48

6 files changed

Lines changed: 88 additions & 56 deletions

File tree

src/java.cpp

Lines changed: 6 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
200200
jobjectArray methodArgs = v8ToJava(env, args, argsStart, argsEnd);
201201
jobject method = javaFindConstructor(env, clazz, methodArgs);
202202
if(method == NULL) {
203-
EXCEPTION_CALL_CALLBACK("Could not find constructor for class " << className);
203+
std::string msg = methodNotFoundToString(env, clazz, className, true, args, argsStart, argsEnd);
204+
EXCEPTION_CALL_CALLBACK(msg);
204205
return v8::Undefined();
205206
}
206207

@@ -238,9 +239,8 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
238239
jobjectArray methodArgs = v8ToJava(env, args, argsStart, argsEnd);
239240
jobject method = javaFindConstructor(env, clazz, methodArgs);
240241
if(method == NULL) {
241-
std::ostringstream errStr;
242-
errStr << "Could not find constructor for class " << className.c_str();
243-
return ThrowException(javaExceptionToV8(env, errStr.str()));
242+
std::string msg = methodNotFoundToString(env, clazz, className, true, args, argsStart, argsEnd);
243+
return ThrowException(javaExceptionToV8(env, msg));
244244
}
245245

246246
// run
@@ -308,46 +308,6 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
308308
return scope.Close(result);
309309
}
310310

311-
/*static*/ std::string Java::methodNotFoundToString(JNIEnv *env, jclass clazz, std::string methodName, const v8::Arguments& args, int argStart, int argEnd) {
312-
std::ostringstream startOfMessage;
313-
std::ostringstream msg;
314-
315-
startOfMessage << "Could not find method \"" << methodName.c_str() << "(";
316-
for(int i=argStart; i<argEnd; i++) {
317-
jobject val = v8ToJava(env, args[i]);
318-
if(i != argStart) {
319-
startOfMessage << ", ";
320-
}
321-
startOfMessage << javaObjectToString(env, val);
322-
}
323-
startOfMessage << ")\" on class \""<< javaObjectToString(env, clazz).c_str() << "\".";
324-
325-
msg << startOfMessage.str() << " Possible matches:\n";
326-
327-
jclass methodClazz = env->FindClass("java/lang/reflect/Method");
328-
jmethodID method_getName = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;");
329-
330-
std::list<jobject> methods;
331-
javaReflectionGetMethods(env, clazz, &methods, true);
332-
int count = 0;
333-
for(std::list<jobject>::iterator it = methods.begin(); it != methods.end(); it++) {
334-
jstring methodNameTestJava = (jstring)env->CallObjectMethod(*it, method_getName);
335-
std::string methodNameTest = javaToString(env, methodNameTestJava);
336-
if(methodNameTest == methodName) {
337-
msg << " " << javaObjectToString(env, *it).c_str() << "\n";
338-
count++;
339-
}
340-
}
341-
342-
if(count == 0) {
343-
std::ostringstream noMethodsMsg;
344-
noMethodsMsg << startOfMessage.str() << " No methods with that name.";
345-
return noMethodsMsg.str();
346-
}
347-
348-
return msg.str();
349-
}
350-
351311
/*static*/ v8::Handle<v8::Value> Java::callStaticMethod(const v8::Arguments& args) {
352312
v8::HandleScope scope;
353313
Java* self = node::ObjectWrap::Unwrap<Java>(args.This());
@@ -376,7 +336,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
376336
jobjectArray methodArgs = v8ToJava(env, args, argsStart, argsEnd);
377337
jobject method = javaFindMethod(env, clazz, methodName, methodArgs);
378338
if(method == NULL) {
379-
std::string msg = methodNotFoundToString(env, clazz, methodName, args, argsStart, argsEnd);
339+
std::string msg = methodNotFoundToString(env, clazz, methodName, false, args, argsStart, argsEnd);
380340
EXCEPTION_CALL_CALLBACK(msg);
381341
return v8::Undefined();
382342
}
@@ -416,7 +376,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
416376
jobjectArray methodArgs = v8ToJava(env, args, argsStart, argsEnd);
417377
jobject method = javaFindMethod(env, clazz, methodName, methodArgs);
418378
if(method == NULL) {
419-
std::string msg = methodNotFoundToString(env, clazz, methodName, args, argsStart, argsEnd);
379+
std::string msg = methodNotFoundToString(env, clazz, methodName, false, args, argsStart, argsEnd);
420380
return ThrowException(javaExceptionToV8(env, msg));
421381
}
422382

src/java.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ class Java : public node::ObjectWrap {
3131
static v8::Handle<v8::Value> newByte(const v8::Arguments& args);
3232
static v8::Handle<v8::Value> getStaticFieldValue(const v8::Arguments& args);
3333
static v8::Handle<v8::Value> setStaticFieldValue(const v8::Arguments& args);
34-
static std::string methodNotFoundToString(JNIEnv *env, jclass clazz, std::string methodName, const v8::Arguments& args, int argStart, int argEnd);
3534
v8::Handle<v8::Value> ensureJvm();
3635

3736
static v8::Persistent<v8::FunctionTemplate> s_ct;

src/javaObject.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
v8::HandleScope scope;
1515

1616
JNIEnv *env = java->getJavaEnv();
17+
obj = env->NewGlobalRef(obj);
18+
1719
PUSH_LOCAL_JAVA_FRAME();
1820

1921
jclass objClazz = env->GetObjectClass(obj);
@@ -83,7 +85,7 @@
8385
JavaObject::JavaObject(Java *java, jobject obj) {
8486
m_java = java;
8587
JNIEnv *env = m_java->getJavaEnv();
86-
m_obj = env->NewGlobalRef(obj);
88+
m_obj = obj;
8789
m_class = (jclass)env->NewGlobalRef(env->GetObjectClass(obj));
8890
}
8991

@@ -128,7 +130,8 @@ JavaObject::~JavaObject() {
128130

129131
jobject method = javaFindMethod(env, self->m_class, methodNameStr, methodArgs);
130132
if(method == NULL) {
131-
EXCEPTION_CALL_CALLBACK("Could not find method " << methodNameStr);
133+
std::string msg = methodNotFoundToString(env, self->m_class, methodNameStr, false, args, argsStart, argsEnd);
134+
EXCEPTION_CALL_CALLBACK(msg);
132135
POP_LOCAL_JAVA_FRAME();
133136
return v8::Undefined();
134137
}
@@ -159,9 +162,8 @@ JavaObject::~JavaObject() {
159162

160163
jobject method = javaFindMethod(env, self->m_class, methodNameStr, methodArgs);
161164
if(method == NULL) {
162-
std::ostringstream errStr;
163-
errStr << "Could not find method " << methodNameStr;
164-
v8::Handle<v8::Value> ex = javaExceptionToV8(env, errStr.str());
165+
std::string msg = methodNotFoundToString(env, self->m_class, methodNameStr, false, args, argsStart, argsEnd);
166+
v8::Handle<v8::Value> ex = javaExceptionToV8(env, msg);
165167
POP_LOCAL_JAVA_FRAME();
166168
return ThrowException(ex);
167169
}

src/javaObject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class JavaObject : public node::ObjectWrap {
1717
static v8::Local<v8::Object> New(Java* java, jobject obj);
1818

1919
jobject getObject() { return m_obj; }
20+
jclass getClass() { return m_class; }
2021

2122
void Ref() { node::ObjectWrap::Ref(); }
2223
void Unref() { node::ObjectWrap::Unref(); }

src/utils.cpp

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#define MODIFIER_STATIC 9
1010

1111
void 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+
3041
void 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+
}

src/utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct DynamicProxyData {
4747
int dynamicProxyDataVerify(DynamicProxyData* data);
4848

4949
void javaReflectionGetMethods(JNIEnv *env, jclass clazz, std::list<jobject>* methods, bool includeStatic);
50+
void javaReflectionGetConstructors(JNIEnv *env, jclass clazz, std::list<jobject>* methods);
5051
void javaReflectionGetFields(JNIEnv *env, jclass clazz, std::list<jobject>* fields);
5152
std::string javaToString(JNIEnv *env, jstring str);
5253
std::string javaObjectToString(JNIEnv *env, jobject obj);
@@ -70,6 +71,8 @@ jobject javaFindField(JNIEnv* env, jclass clazz, std::string& fieldName);
7071
jobject javaFindMethod(JNIEnv *env, jclass clazz, std::string& methodName, jobjectArray methodArgs);
7172
jobject javaFindConstructor(JNIEnv *env, jclass clazz, jobjectArray methodArgs);
7273

74+
std::string methodNotFoundToString(JNIEnv *env, jclass clazz, std::string methodName, bool constructor, const v8::Arguments& args, int argStart, int argEnd);
75+
7376
#define UNUSED_VARIABLE(var) var = var;
7477

7578
#define ARGS_FRONT_OBJECT(ARGNAME) \

0 commit comments

Comments
 (0)