From af61f240a52976e4a27f367df93cbf5ba39a2daf Mon Sep 17 00:00:00 2001 From: ishmal Date: Mon, 10 Mar 2008 21:27:23 +0000 Subject: [PATCH] bug fixes --- .../java/org/inkscape/cmn/ScriptRunner.java | 4 +- src/bind/javabind.cpp | 83 ++++++++++++++++--- src/bind/javabind.h | 3 +- 3 files changed, 75 insertions(+), 15 deletions(-) diff --git a/src/bind/java/org/inkscape/cmn/ScriptRunner.java b/src/bind/java/org/inkscape/cmn/ScriptRunner.java index 1214a66d4..a128af734 100644 --- a/src/bind/java/org/inkscape/cmn/ScriptRunner.java +++ b/src/bind/java/org/inkscape/cmn/ScriptRunner.java @@ -43,7 +43,7 @@ long backPtr; /** * Redirect stdout */ -private native void stdOutWrite(long ptr, int b); +public native void stdOutWrite(long ptr, int b); class StdOutStream extends OutputStream { @@ -59,7 +59,7 @@ public void write(int b) /** * Redirect stderr */ -private native void stdErrWrite(long ptr, int b); +public native void stdErrWrite(long ptr, int b); class StdErrStream extends OutputStream { diff --git a/src/bind/javabind.cpp b/src/bind/javabind.cpp index fbf12b16a..40b238c89 100644 --- a/src/bind/javabind.cpp +++ b/src/bind/javabind.cpp @@ -79,6 +79,35 @@ typedef jint (*CreateVMFunc)(JavaVM **, JNIEnv **, void *); //# UTILITY //######################################################################## +/** + * Normalize path. Java wants '/', even on Windows + */ +String normalizePath(const String &str) +{ + String buf; + for (unsigned int i=0 ; iExceptionOccurred(); + if (exc) + { + env->ExceptionClear(); + } + return buf; +} + jint getInt(JNIEnv *env, jobject obj, const char *name) { jfieldID fid = env->GetFieldID(env->GetObjectClass(obj), name, "I"); @@ -506,10 +535,8 @@ static void populateClassPath(const String &javaroot, cp.append(path); } closedir(dir); - + result = cp; - - return; } @@ -524,13 +551,13 @@ static void populateClassPath(const String &javaroot, * want. These native methods are only those needed for running * a script. For the main C++/Java bindings, see dobinding.cpp */ -static void stdOutWrite(jlong ptr, jint ch) +void JNICALL stdOutWrite(JNIEnv */*env*/, jobject /*obj*/, jlong ptr, jint ch) { JavaBinderyImpl *bind = (JavaBinderyImpl *)ptr; bind->stdOut(ch); } -static void stdErrWrite(jlong ptr, jint ch) +void JNICALL stdErrWrite(JNIEnv */*env*/, jobject /*obj*/, jlong ptr, jint ch) { JavaBinderyImpl *bind = (JavaBinderyImpl *)ptr; bind->stdErr(ch); @@ -548,6 +575,13 @@ static JNINativeMethod scriptRunnerMethods[] = //======================================================================== +/** + * This is used to grab output from the VM itself. See 'options' below. + */ +static int JNICALL vfprintfHook(FILE* f, const char *fmt, va_list args) +{ + g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, args); +} /** @@ -574,22 +608,26 @@ bool JavaBinderyImpl::loadJVM() String cp; populateClassPath(javaroot, cp); String classpath = "-Djava.class.path="; - classpath.append(cp); + classpath.append(normalizePath(cp)); msg("Class path is: '%s'", classpath.c_str()); String libpath = "-Djava.library.path="; libpath.append(javaroot); libpath.append(DIR_SEPARATOR); libpath.append("libm"); + libpath = normalizePath(libpath); msg("Lib path is: '%s'", libpath.c_str()); JavaVMInitArgs vm_args; - JavaVMOption options[2]; + JavaVMOption options[4]; options[0].optionString = (char *)classpath.c_str(); options[1].optionString = (char *)libpath.c_str(); - vm_args.version = JNI_VERSION_1_2; + options[2].optionString = "-verbose:jni"; + options[3].optionString = "vfprintf"; + options[3].extraInfo = (void *)vfprintfHook; + vm_args.version = JNI_VERSION_1_4; vm_args.options = options; - vm_args.nOptions = 2; + vm_args.nOptions = 4; vm_args.ignoreUnrecognized = true; if (createVM(&jvm, &env, &vm_args) < 0) @@ -751,12 +789,33 @@ bool JavaBinderyImpl::registerNatives(const String &className, err("Could not find class '%s'", className.c_str()); return false; } - int nrMethods = 0; + /** + * hack for JDK bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6493522 + */ + jmethodID mid = env->GetMethodID(env->GetObjectClass(cls), "getConstructors", + "()[Ljava/lang/reflect/Constructor;"); + if (!mid) + { + err("Could not get reflect mid for 'getConstructors'"); + return false; + } + env->CallObjectMethod(cls, mid); + /** + * end hack + */ + jint nrMethods = 0; for (const JNINativeMethod *m = methods ; m->name ; m++) nrMethods++; - if (env->RegisterNatives(cls, (const JNINativeMethod *)methods, nrMethods) < 0) + jint ret = env->RegisterNatives(cls, (const JNINativeMethod *)methods, nrMethods); + if (ret < 0) { - err("Could not register natives"); + err("Could not register %d native methods for '%s'", + nrMethods, className.c_str()); + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + env->ExceptionClear(); + } return false; } return true; diff --git a/src/bind/javabind.h b/src/bind/javabind.h index f01627a15..164110ea6 100644 --- a/src/bind/javabind.h +++ b/src/bind/javabind.h @@ -58,7 +58,8 @@ public: BIND_INT, BIND_BOOLEAN, BIND_DOUBLE, - BIND_STRING + BIND_STRING, + BIND_OBJECT } ValueType; /** -- 2.30.2