Skip to content

Commit d2bac5a

Browse files
committed
added more general tests
fixed bugs with error handling on async calls
1 parent 93b6f3f commit d2bac5a

10 files changed

Lines changed: 128 additions & 25 deletions

File tree

src/java.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
133133
v8::Handle<v8::Value> argv[2];
134134
argv[0] = error;
135135
argv[1] = v8::Undefined();
136+
136137
v8::Function::Cast(*callback)->Call(v8::Context::GetCurrent()->Global(), 2, argv);
137138
return v8::Undefined();
138139
}

src/methodCallBaton.cpp

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ MethodCallBaton::MethodCallBaton(Java* java, jobject method, jarray args, v8::Ha
1010
m_args = (jarray)env->NewGlobalRef(args);
1111
m_callback = v8::Persistent<v8::Value>::New(callback);
1212
m_method = env->NewGlobalRef(method);
13+
m_error = NULL;
14+
m_result = NULL;
1315
}
1416

1517
MethodCallBaton::~MethodCallBaton() {
@@ -48,21 +50,29 @@ v8::Handle<v8::Value> MethodCallBaton::runSync() {
4850

4951
void MethodCallBaton::after(JNIEnv *env) {
5052
if(m_callback->IsFunction()) {
53+
v8::Handle<v8::Value> result = resultsToV8(env);
5154
v8::Handle<v8::Value> argv[2];
52-
argv[0] = v8::Undefined();
53-
argv[1] = resultsToV8(env);
55+
if(result->IsNativeError()) {
56+
argv[0] = result;
57+
argv[1] = v8::Undefined();
58+
} else {
59+
argv[0] = v8::Undefined();
60+
argv[1] = result;
61+
}
5462
v8::Function::Cast(*m_callback)->Call(v8::Context::GetCurrent()->Global(), 2, argv);
5563
}
5664

57-
env->DeleteGlobalRef(m_result);
65+
if(m_result) {
66+
env->DeleteGlobalRef(m_result);
67+
}
5868
}
5969

6070
v8::Handle<v8::Value> MethodCallBaton::resultsToV8(JNIEnv *env) {
6171
v8::HandleScope scope;
6272

63-
if(!m_error.IsEmpty() && !m_error->IsNull()) {
64-
v8::Handle<v8::Value> err = m_error;
65-
m_error.Dispose();
73+
if(m_error) {
74+
v8::Handle<v8::Value> err = javaExceptionToV8(env, m_error, m_errorString);
75+
env->DeleteGlobalRef(m_error);
6676
return scope.Close(err);
6777
}
6878

@@ -112,11 +122,16 @@ void NewInstanceBaton::execute(JNIEnv *env) {
112122
//printf("invoke: %s\n", javaObjectToString(env, m_method).c_str());
113123

114124
jobject result = env->CallObjectMethod(m_method, constructor_newInstance, m_args);
125+
jthrowable err = env->ExceptionOccurred();
126+
if(err) {
127+
m_error = (jthrowable)env->NewGlobalRef(err);
128+
m_errorString = "Error creating class";
129+
env->ExceptionClear();
130+
return;
131+
}
132+
115133
m_resultType = TYPE_OBJECT;
116134
m_result = env->NewGlobalRef(result);
117-
if(env->ExceptionCheck()) {
118-
m_error = v8::Persistent<v8::Value>::New(javaExceptionToV8(env, "Error running method"));
119-
}
120135
}
121136

122137
void StaticMethodCallBaton::execute(JNIEnv *env) {
@@ -137,8 +152,10 @@ void StaticMethodCallBaton::execute(JNIEnv *env) {
137152
m_resultType = javaGetType(env, returnType);
138153
jobject result = env->CallObjectMethod(m_method, method_invoke, NULL, m_args);
139154
m_result = env->NewGlobalRef(result);
140-
if(env->ExceptionCheck()) {
141-
m_error = v8::Persistent<v8::Value>::New(javaExceptionToV8(env, "Error running method"));
155+
jthrowable err = env->ExceptionOccurred();
156+
if(err) {
157+
m_error = (jthrowable)env->NewGlobalRef(err);
158+
m_errorString = "Error running static method";
142159
}
143160
}
144161

@@ -160,8 +177,10 @@ void InstanceMethodCallBaton::execute(JNIEnv *env) {
160177
m_resultType = javaGetType(env, returnType);
161178
jobject result = env->CallObjectMethod(m_method, method_invoke, m_javaObject->getObject(), m_args);
162179
m_result = env->NewGlobalRef(result);
163-
if(env->ExceptionCheck()) {
164-
m_error = v8::Persistent<v8::Value>::New(javaExceptionToV8(env, "Error running method"));
180+
jthrowable err = env->ExceptionOccurred();
181+
if(err) {
182+
m_error = (jthrowable)env->NewGlobalRef(err);
183+
m_errorString = "Error running instance method";
165184
}
166185
}
167186

src/methodCallBaton.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ class MethodCallBaton {
2828

2929
Java* m_java;
3030
v8::Persistent<v8::Value> m_callback;
31-
v8::Persistent<v8::Value> m_error;
31+
jthrowable m_error;
32+
std::string m_errorString;
3233
jarray m_args;
3334
jobject m_result;
3435
jobject m_method;

src/utils.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -263,13 +263,15 @@ jarray v8ToJava(JNIEnv* env, const v8::Arguments& args, int start, int end, std:
263263
return results;
264264
}
265265

266+
v8::Handle<v8::Value> javaExceptionToV8(JNIEnv* env, jthrowable ex, const std::string& alternateMessage) {
267+
v8::HandleScope scope;
268+
269+
std::string msg = alternateMessage + "\n" + javaObjectToString(env, ex);
270+
return scope.Close(v8::Exception::TypeError(v8::String::New(msg.c_str())));
271+
}
272+
266273
v8::Handle<v8::Value> javaExceptionToV8(JNIEnv* env, const std::string& alternateMessage) {
274+
v8::HandleScope scope;
267275
jthrowable ex = env->ExceptionOccurred();
268-
if(ex) {
269-
printf("BEGIN Java Exception -------\n");
270-
env->ExceptionDescribe(); // TODO: handle error
271-
printf("END Java Exception ---------\n");
272-
// TODO: convert error to v8 error
273-
}
274-
return v8::Exception::TypeError(v8::String::New(alternateMessage.c_str()));
276+
return scope.Close(javaExceptionToV8(env, ex, alternateMessage));
275277
}

src/utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@ jobject javaFindField(JNIEnv* env, jclass clazz, std::string fieldName);
3939
jarray v8ToJava(JNIEnv* env, const v8::Arguments& args, int start, int end, std::list<int> *methodArgTypes);
4040
jobject v8ToJava(JNIEnv* env, v8::Local<v8::Value> arg, int *methodArgType);
4141
v8::Handle<v8::Value> javaExceptionToV8(JNIEnv* env, const std::string& alternateMessage);
42+
v8::Handle<v8::Value> javaExceptionToV8(JNIEnv* env, jthrowable ex, const std::string& alternateMessage);
4243

4344
#endif

test/Test.class

321 Bytes
Binary file not shown.

test/Test.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
public class Test {
3+
private int i;
4+
5+
public Test() {}
6+
public Test(int i) { this.i = i; }
7+
8+
public int getInt() { return i; }
9+
}

test/java-test.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
2+
var java = require("./testHelpers").java;
3+
4+
var nodeunit = require("nodeunit");
5+
var util = require("util");
6+
7+
exports['Java'] = nodeunit.testCase({
8+
"newInstance": function(test) {
9+
java.newInstance("Test", function(err, result) {
10+
test.ok(result);
11+
test.equal(result.getClassSync().toStringSync(), "class Test");
12+
test.done();
13+
});
14+
},
15+
16+
"newInstanceSync": function(test) {
17+
var result = java.newInstanceSync("Test");
18+
test.ok(result);
19+
test.equal(result.getClassSync().toStringSync(), "class Test");
20+
test.done();
21+
},
22+
23+
"newInstance with args": function(test) {
24+
java.newInstance("Test", 42, function(err, result) {
25+
test.ok(result);
26+
test.equal(result.getIntSync(), 42);
27+
test.done();
28+
});
29+
},
30+
31+
"newInstanceSync with args": function(test) {
32+
var result = java.newInstanceSync("Test", 42);
33+
test.ok(result);
34+
test.equal(result.getIntSync(), 42);
35+
test.done();
36+
},
37+
38+
"newInstance bad class name": function(test) {
39+
java.newInstance("BadClassName", function(err, result) {
40+
test.ok(err);
41+
test.ok(!result);
42+
test.done();
43+
});
44+
},
45+
46+
"newInstanceSync bad class name": function(test) {
47+
test.throws(function() {
48+
java.newInstanceSync("BadClassName");
49+
});
50+
test.done();
51+
},
52+
53+
"newInstance bad arg types": function(test) {
54+
java.newInstance("Test", "z", function(err, result) {
55+
test.ok(err);
56+
test.ok(!result);
57+
test.done();
58+
});
59+
},
60+
61+
"newInstanceSync bad arg types": function(test) {
62+
test.throws(function() {
63+
java.newInstanceSync("Test", "z");
64+
});
65+
test.done();
66+
},
67+
});

test/simple-test.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
2-
3-
var java = require("../");
4-
java.classpath.push("test/commons-lang3-3.1.jar");
1+
var java = require("./testHelpers").java;
52

63
var nodeunit = require("nodeunit");
74
var util = require("util");

test/testHelpers.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
var java = require("../");
3+
java.classpath.push("test/");
4+
java.classpath.push("test/commons-lang3-3.1.jar");
5+
6+
module.exports.java = java;

0 commit comments

Comments
 (0)