Skip to content

Commit b15fd34

Browse files
committed
working method call
1 parent 7ddb61f commit b15fd34

7 files changed

Lines changed: 63 additions & 28 deletions

File tree

src/java.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,19 +115,21 @@ void NewInstanceBaton::run(JNIEnv *env) {
115115
return;
116116
}
117117

118-
m_result = env->NewObject(clazz, method);
118+
jobject result = env->NewObject(clazz, method);
119119
if(env->ExceptionCheck()) {
120120
env->ExceptionDescribe(); // TODO: handle error
121121
return;
122122
}
123+
124+
m_result = env->NewGlobalRef(result);
123125
}
124126

125127
void NewInstanceBaton::doCallback() {
126128
if(m_callback->IsFunction()) {
127129
v8::Handle<v8::Value> argv[2];
128130
argv[0] = v8::Undefined();
129131
argv[1] = JavaObject::New(m_java, m_result);
130-
131132
v8::Function::Cast(*this->m_callback)->Call(v8::Context::GetCurrent()->Global(), 2, argv);
132133
}
134+
m_java->getJavaEnv()->DeleteGlobalRef(m_result);
133135
}

src/javaObject.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
jclass methodClazz = env->FindClass("java/lang/reflect/Method");
3030
jmethodID method_getNameMethod = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;");
3131
for(std::list<jobject>::iterator it = self->m_methods.begin(); it != self->m_methods.end(); it++) {
32-
v8::Handle<v8::String> methodName = v8::String::New(javaToString(env, (jstring)env->CallObjectMethod(*it, method_getNameMethod)).c_str());
32+
const char* methodNameStr = javaToString(env, (jstring)env->CallObjectMethod(*it, method_getNameMethod)).c_str();
33+
v8::Handle<v8::String> methodName = v8::String::New(methodNameStr);
3334
v8::Local<v8::FunctionTemplate> methodCallTemplate = v8::FunctionTemplate::New(methodCall, methodName);
3435
javaObjectObj->Set(methodName, methodCallTemplate->GetFunction());
3536
}
@@ -39,12 +40,12 @@
3940

4041
JavaObject::JavaObject(Java *java, jobject obj) {
4142
m_java = java;
42-
m_obj = obj;
43-
m_class = java->getJavaEnv()->GetObjectClass(obj);
43+
m_obj = m_java->getJavaEnv()->NewGlobalRef(obj);
44+
m_class = m_java->getJavaEnv()->GetObjectClass(obj);
4445
}
4546

4647
JavaObject::~JavaObject() {
47-
48+
m_java->getJavaEnv()->DeleteGlobalRef(m_obj);
4849
}
4950

5051
/*static*/ v8::Handle<v8::Value> JavaObject::methodCall(const v8::Arguments& args) {

src/methodCallBaton.cpp

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,25 @@
44
#include "javaObject.h"
55

66
MethodCallBaton::MethodCallBaton(Java* java, JavaObject* obj, jobject method, std::list<jobject> args, v8::Handle<v8::Value> &callback) {
7+
JNIEnv *env = java->getJavaEnv();
8+
79
m_java = java;
810
m_javaObject = obj;
9-
m_method = method;
10-
m_args = args;
11+
m_method = env->NewGlobalRef(method);
12+
for(std::list<jobject>::iterator it = args.begin(); it != args.end(); it++) {
13+
m_args.push_back(env->NewGlobalRef(*it));
14+
}
1115
m_callback = v8::Persistent<v8::Value>::New(callback);
1216
m_javaObject->Ref();
1317
}
1418

1519
MethodCallBaton::~MethodCallBaton() {
20+
JNIEnv *env = m_java->getJavaEnv();
21+
env->DeleteGlobalRef(m_method);
22+
for(std::list<jobject>::iterator it = m_args.begin(); it != m_args.end(); it++) {
23+
env->DeleteGlobalRef(*it);
24+
}
25+
1626
m_callback.Dispose();
1727
m_javaObject->Unref();
1828
}
@@ -30,18 +40,8 @@ MethodCallBaton::~MethodCallBaton() {
3040
jclass objectClazz = env->FindClass("java/lang/Object");
3141
jobjectArray parameters = env->NewObjectArray(0, objectClazz, NULL); // TODO: init parameters
3242
self->m_resultType = javaGetType(env, returnType);
33-
switch(self->m_resultType) {
34-
case TYPE_INT:
35-
printf("m_method: %s\n", javaObjectToString(env, self->m_method).c_str());
36-
printf("obj: %s\n", javaObjectToString(env, self->m_javaObject->m_obj).c_str());
37-
printf("parameters: %s\n", javaObjectToString(env, parameters).c_str());
38-
self->m_result.i = env->CallIntMethod(self->m_method, method_invoke, self->m_javaObject->m_obj, parameters);
39-
printf("%d\n", self->m_result.i);
40-
break;
41-
case TYPE_OBJECT:
42-
self->m_result.l = env->CallObjectMethod(self->m_method, method_invoke, self->m_javaObject->m_obj, parameters);
43-
break;
44-
}
43+
jobject result = env->CallObjectMethod(self->m_method, method_invoke, self->m_javaObject->m_obj, parameters);
44+
self->m_result = env->NewGlobalRef(result);
4545
if(env->ExceptionCheck()) {
4646
env->ExceptionDescribe(); // TODO: handle error
4747
return;
@@ -52,21 +52,31 @@ MethodCallBaton::~MethodCallBaton() {
5252

5353
/*static*/ int MethodCallBaton::EIO_AfterMethodCall(eio_req* req) {
5454
MethodCallBaton* self = static_cast<MethodCallBaton*>(req->data);
55-
55+
JNIEnv *env = self->m_java->getJavaEnv();
56+
5657
if(self->m_callback->IsFunction()) {
5758
v8::Handle<v8::Value> argv[2];
5859
argv[0] = v8::Undefined();
5960
switch(self->m_resultType) {
6061
case TYPE_INT:
61-
argv[1] = v8::Integer::New(self->m_result.i);
62+
{
63+
jclass integerClazz = env->FindClass("java/lang/Integer");
64+
jmethodID integer_intValue = env->GetMethodID(integerClazz, "intValue", "()I");
65+
int result = env->CallIntMethod(self->m_result, integer_intValue);
66+
argv[1] = v8::Integer::New(result);
67+
}
6268
break;
6369
case TYPE_OBJECT:
64-
argv[1] = JavaObject::New(self->m_java, self->m_result.l);
70+
argv[1] = JavaObject::New(self->m_java, self->m_result);
71+
break;
72+
case TYPE_STRING:
73+
argv[1] = v8::String::New(javaObjectToString(env, self->m_result).c_str());
6574
break;
6675
}
6776
v8::Function::Cast(*self->m_callback)->Call(v8::Context::GetCurrent()->Global(), 2, argv);
6877
}
6978

79+
env->DeleteGlobalRef(self->m_result);
7080
ev_unref(EV_DEFAULT_UC);
7181
delete self;
7282
return 0;

src/methodCallBaton.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class MethodCallBaton {
2525
v8::Persistent<v8::Value> m_callback;
2626
jobject m_method;
2727
std::list<jobject> m_args;
28-
jvalue m_result;
28+
jobject m_result;
2929
int m_resultType;
3030
};
3131

src/utils.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ std::string javaToString(JNIEnv *env, jstring str) {
2525
}
2626

2727
std::string javaObjectToString(JNIEnv *env, jobject obj) {
28+
if(obj == NULL) {
29+
return "";
30+
}
2831
jclass objClazz = env->GetObjectClass(obj);
2932
jmethodID methodId = env->GetMethodID(objClazz, "toString", "()Ljava/lang/String;");
3033
jstring result = (jstring)env->CallObjectMethod(obj, methodId);
@@ -68,6 +71,8 @@ jvalueType javaGetType(JNIEnv *env, jclass type) {
6871
const char *typeStr = javaObjectToString(env, type).c_str();
6972
if(strcmp(typeStr, "int") == 0) {
7073
return TYPE_INT;
74+
} else if(strcmp(typeStr, "class java.lang.String") == 0) {
75+
return TYPE_STRING;
7176
}
7277

7378
//jclass intClazz = env->FindClass("java/lang/Integer");

src/utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
typedef enum _jvalueType {
1010
TYPE_INT,
11-
TYPE_OBJECT
11+
TYPE_OBJECT,
12+
TYPE_STRING
1213
} jvalueType;
1314

1415
std::list<jobject> javaReflectionGetDeclaredMethods(JNIEnv *env, jclass clazz);

test/simple-test.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,31 @@ var nodeunit = require("nodeunit");
55
var util = require("util");
66

77
exports['Simple'] = nodeunit.testCase({
8-
"create an instance of a class (async)": function(test) {
8+
"create an instance of a class and call methods (getName) (async)": function(test) {
9+
java.newInstance("java.util.ArrayList", function(err, list) {
10+
if(err) { console.log(err); return; }
11+
test.ok(list);
12+
if(list) {
13+
list.getClass(function(err, result) {
14+
if(err) { console.log(err); return; }
15+
result.getName(function(err, result) {
16+
if(err) { console.log(err); return; }
17+
test.equal(result, "java.util.ArrayList");
18+
test.done();
19+
});
20+
});
21+
}
22+
});
23+
},
24+
25+
"create an instance of a class and call methods (size) (async)": function(test) {
926
java.newInstance("java.util.ArrayList", function(err, list) {
1027
if(err) { console.log(err); return; }
1128
test.ok(list);
1229
if(list) {
1330
list.size(function(err, result) {
1431
if(err) { console.log(err); return; }
15-
console.log("result", result);
16-
//test.equal(result, 0);
32+
test.equal(result, 0);
1733
test.done();
1834
});
1935
}

0 commit comments

Comments
 (0)