Code

bug fixes
authorishmal <ishmal@users.sourceforge.net>
Mon, 10 Mar 2008 21:27:23 +0000 (21:27 +0000)
committerishmal <ishmal@users.sourceforge.net>
Mon, 10 Mar 2008 21:27:23 +0000 (21:27 +0000)
src/bind/java/org/inkscape/cmn/ScriptRunner.java
src/bind/javabind.cpp
src/bind/javabind.h

index 1214a66d4308053af5b93b1194e2a22bf3783d2d..a128af734ddbe7199806025099bc0c74e4fbc337 100644 (file)
@@ -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
 {
 
index fbf12b16ac8f316941a5b2784adb6a60556cb397..40b238c89244ac2967e30dcf71e06f37149f7c70 100644 (file)
@@ -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 ; i<str.size() ; i++)
+        {
+        char ch = str[i];
+        if (ch == '\\')
+            buf.push_back('/');
+        else
+            buf.push_back(ch);
+               }
+       return buf;
+}
+
+
+String getException(JNIEnv *env)
+{
+    String buf;
+    jthrowable exc = env->ExceptionOccurred();
+    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;
index f01627a1533125e20366991ce676a8bdc214109b..164110ea6c95a8fb730f30e6882c89b68ced9070 100644 (file)
@@ -58,7 +58,8 @@ public:
         BIND_INT,
         BIND_BOOLEAN,
         BIND_DOUBLE,
-        BIND_STRING
+        BIND_STRING,
+        BIND_OBJECT
         } ValueType;
 
     /**