Skip to content

Commit d502320

Browse files
committed
Create java.lang.reflect.Proxy once per instance instead of on every invocation.
Fix postInstall.js on Windows.
1 parent bbb0a9a commit d502320

3 files changed

Lines changed: 63 additions & 58 deletions

File tree

postInstall.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ require('find-java-home')(function(err, home){
3131

3232
function getCorrectSoForPlatform(soFiles){
3333
var so = _getCorrectSoForPlatform(soFiles);
34-
return removeDuplicateJre(so);
34+
if (so) {
35+
so = removeDuplicateJre(so);
36+
}
37+
return so;
3538
}
3639

3740
function removeDuplicateJre(filePath){

src/java.cpp

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -353,14 +353,66 @@ NAN_METHOD(Java::newProxy) {
353353
return NanThrowError(javaExceptionToV8(self, env, errStr.str()));
354354
}
355355

356+
// create the NodeDynamicProxyClass
357+
jclass constructorClazz = env->FindClass("java/lang/reflect/Constructor");
358+
jmethodID constructor_newInstance = env->GetMethodID(constructorClazz, "newInstance", "([Ljava/lang/Object;)Ljava/lang/Object;");
359+
360+
//printf("invoke: %s\n", javaMethodCallToString(env, m_method, constructor_newInstance, m_args).c_str());
361+
356362
// run constructor
357-
v8::Handle<v8::Value> callback = NanNull();
358-
NewInstanceBaton* baton = new NewInstanceBaton(self, clazz, method, methodArgs, callback);
359-
v8::Handle<v8::Value> result = baton->runSync();
360-
delete baton;
361-
if(result->IsNativeError()) {
362-
return NanThrowError(result);
363+
jobject dynamicProxy = env->CallObjectMethod(method, constructor_newInstance, methodArgs);
364+
if(env->ExceptionCheck()) {
365+
std::ostringstream errStr;
366+
errStr << "Error creating class";
367+
return NanThrowError(javaExceptionToV8(self, env, errStr.str()));
368+
}
369+
370+
jclass dynamicInterface = javaFindClass(env, interfaceName);
371+
if(dynamicInterface == NULL) {
372+
std::ostringstream errStr;
373+
errStr << "Could not find interface ";
374+
errStr << interfaceName;
375+
return NanThrowError(javaExceptionToV8(self, env, errStr.str()));
376+
}
377+
jclass classClazz = env->FindClass("java/lang/Class");
378+
jobjectArray classArray = env->NewObjectArray(1, classClazz, NULL);
379+
if(classArray == NULL) {
380+
std::ostringstream errStr;
381+
errStr << "Could not create class array for Proxy";
382+
return NanThrowError(javaExceptionToV8(self, env, errStr.str()));
383+
}
384+
env->SetObjectArrayElement(classArray, 0, dynamicInterface);
385+
386+
jmethodID class_getClassLoader = env->GetMethodID(classClazz, "getClassLoader", "()Ljava/lang/ClassLoader;");
387+
jobject classLoader = env->CallObjectMethod(dynamicInterface, class_getClassLoader);
388+
assert(!env->ExceptionCheck());
389+
390+
if(classLoader == NULL) {
391+
jclass objectClazz = env->FindClass("java/lang/Object");
392+
jmethodID object_getClass = env->GetMethodID(objectClazz, "getClass", "()Ljava/lang/Class;");
393+
jobject jobjClass = env->CallObjectMethod(dynamicProxy, object_getClass);
394+
checkJavaException(env);
395+
classLoader = env->CallObjectMethod(jobjClass, class_getClassLoader);
396+
checkJavaException(env);
363397
}
398+
if(classLoader == NULL) {
399+
std::ostringstream errStr;
400+
errStr << "Could not get classloader for Proxy";
401+
return NanThrowError(javaExceptionToV8(self, env, errStr.str()));
402+
}
403+
404+
// create proxy instance
405+
jclass proxyClass = env->FindClass("java/lang/reflect/Proxy");
406+
jmethodID proxy_newProxyInstance = env->GetStaticMethodID(proxyClass, "newProxyInstance", "(Ljava/lang/ClassLoader;[Ljava/lang/Class;Ljava/lang/reflect/InvocationHandler;)Ljava/lang/Object;");
407+
jobject proxyInstance = env->CallStaticObjectMethod(proxyClass, proxy_newProxyInstance, classLoader, classArray, dynamicProxy);
408+
if(env->ExceptionCheck()) {
409+
std::ostringstream errStr;
410+
errStr << "Error creating java.lang.reflect.Proxy";
411+
return NanThrowError(javaExceptionToV8(self, env, errStr.str()));
412+
}
413+
414+
v8::Handle<v8::Value> result = javaToV8(self, env, proxyInstance);
415+
364416
NanAssignPersistent(dynamicProxyData->jsObject, result);
365417
NanReturnValue(result);
366418
}

src/utils.cpp

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -310,57 +310,7 @@ jobject v8ToJava(JNIEnv* env, v8::Local<v8::Value> arg) {
310310

311311
jobject v8ToJava_javaObject(JNIEnv* env, v8::Local<v8::Object> obj) {
312312
JavaObject* javaObject = node::ObjectWrap::Unwrap<JavaObject>(obj);
313-
jobject jobj = javaObject->getObject();
314-
315-
jclass nodeDynamicProxyClass = env->FindClass("node/NodeDynamicProxyClass");
316-
if(env->IsInstanceOf(jobj, nodeDynamicProxyClass)) {
317-
jfieldID ptrField = env->GetFieldID(nodeDynamicProxyClass, "ptr", "J");
318-
DynamicProxyData* proxyData = (DynamicProxyData*)(long)env->GetLongField(jobj, ptrField);
319-
if(!dynamicProxyDataVerify(proxyData)) {
320-
return NULL;
321-
}
322-
323-
jclass dynamicInterface = javaFindClass(env, proxyData->interfaceName);
324-
if(dynamicInterface == NULL) {
325-
printf("Could not find interface %s\n", proxyData->interfaceName.c_str());
326-
return NULL;
327-
}
328-
jclass classClazz = env->FindClass("java/lang/Class");
329-
jobjectArray classArray = env->NewObjectArray(1, classClazz, NULL);
330-
env->SetObjectArrayElement(classArray, 0, dynamicInterface);
331-
332-
jmethodID class_getClassLoader = env->GetMethodID(classClazz, "getClassLoader", "()Ljava/lang/ClassLoader;");
333-
jobject classLoader = env->CallObjectMethod(dynamicInterface, class_getClassLoader);
334-
assert(!env->ExceptionCheck());
335-
336-
if(classLoader == NULL) {
337-
jclass objectClazz = env->FindClass("java/lang/Object");
338-
jmethodID object_getClass = env->GetMethodID(objectClazz, "getClass", "()Ljava/lang/Class;");
339-
jobject jobjClass = env->CallObjectMethod(jobj, object_getClass);
340-
checkJavaException(env);
341-
classLoader = env->CallObjectMethod(jobjClass, class_getClassLoader);
342-
checkJavaException(env);
343-
}
344-
345-
jclass proxyClass = env->FindClass("java/lang/reflect/Proxy");
346-
jmethodID proxy_newProxyInstance = env->GetStaticMethodID(proxyClass, "newProxyInstance", "(Ljava/lang/ClassLoader;[Ljava/lang/Class;Ljava/lang/reflect/InvocationHandler;)Ljava/lang/Object;");
347-
if(classLoader == NULL) {
348-
printf("Could not get classloader for Proxy\n");
349-
return NULL;
350-
}
351-
if(classArray == NULL) {
352-
printf("Could not create class array for Proxy\n");
353-
return NULL;
354-
}
355-
if(jobj == NULL) {
356-
printf("Not a valid object to wrap\n");
357-
return NULL;
358-
}
359-
jobj = env->CallStaticObjectMethod(proxyClass, proxy_newProxyInstance, classLoader, classArray, jobj);
360-
checkJavaException(env);
361-
}
362-
363-
return jobj;
313+
return javaObject->getObject();
364314
}
365315

366316
void checkJavaException(JNIEnv* env) {

0 commit comments

Comments
 (0)