javabind.cpp revision dbb33756bd786e9432e18ec7be93f8c416e1b492
* This is a simple mechanism to bind Inkscape to Java, and thence * to all of the nice things that can be layered upon that. * Copyright (C) 2007-2008 Bob Jamison * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Note: We must limit Java or JVM-specific code to this file * This file is mostly about getting things up and running, and * providing the basic C-to-Java hooks. //######################################################################## //######################################################################## //######################################################################## //######################################################################## * Normalize path. Java wants '/', even on Windows for (
unsigned int i=0 ; i<
str.
size() ; i++)
* Convert a java string to a C++ string * Check if the VM has encountered an Exception. If so, get the String for it * and clear the exception //######################################################################## //######################################################################## //######################################################################## //######################################################################## void err(
const char *
fmt, ...)
void msg(
const char *
fmt, ...)
//######################################################################## //######################################################################## for (
unsigned int i=0 ; i<s.
size() ; i++)
* Common places to find jvm.dll under JAVA_HOME "\\jre\\bin\\client\\jvm.dll",
"\\bin\\client\\jvm.dll",
* Return the directory of the .exe that is currently running * Check a directory for several possibilities of sub-locations * under it, where a jvm might exist. //msg("trying '%s'", jpath.c_str()); * Attempt to find and load a jvm.dll file. Find the createVM() * function's address and return it * First, look for an embedded jre in the .exe's dir. * This allows us to package our own JRE if we want to. * Next, look for JAVA_HOME. This will allow the user * to override what's in the registry //not at JAVA_HOME. check the registry msg(
"JVM CurrentVersion not found in registry at '%s'",
regpath);
//msg("reg path: %s\n", regpath); msg(
"JVM RuntimeLib not found in registry at '%s'",
err(
"JVM not found at JAVA_HOME or in registry");
* If we are here, then we seem to have a valid path for jvm.dll err(
"Could not find 'JNI_CreateJavaVM' in shared library '%s'",
javaroot.append(INKSCAPE_BINDDIR); javaroot.append("\\java"); //######################################################################## //######################################################################## * Recursively descend into a directory looking for libjvm.so * Some common places on a Unix filesystem where JVMs are * Look for a Java VM (libjvm.so) in several Unix places /* Is there one specified by the user? */ //Look first for a Client VM //else default to the first * Attempt to find and load a jvm.dll file. Find the createVM() * function's address and return it err(
"No Java VM found. Is JAVA_HOME defined? Need to find 'libjvm.so'");
err(
"Could not find 'JNI_CreateJavaVM' in shared library");
//######################################################################## //######################################################################## return (
jvm != (
void *)0);
* This will set up the classpath for the launched VM. * We will add two things: * This will allow people to add classes and jars to the JVM without * needing to state them explicitly. * @param javaroot. Should be INKSCAPE_JAVADIR * @param result a string buffer to hold the result of this method //======================================================================== //======================================================================== * This is provided to scripts can grab the current copy or the * repr tree. If anyone has a smarter way of doing this, please implement. //JavaBinderyImpl *bind = (JavaBinderyImpl *)ptr; * This is provided to scripts can load an XML tree into Inkscape. * If anyone has a smarter way of doing this, please implement. JavaBinderyImpl *bind = (JavaBinderyImpl *)ptr; String s = getString(env, jstr); SPDocument *doc = sp_document_new_from_mem(s.c_str(), s.size(), true); * This method is used to allow the gateway class to * redirect its logging stream here. { (
char *)
"logWrite", (
char *)
"(JI)V", (
void *)
logWrite },
* This sets up the 'Gateway' java class for execution of * scripts. The class's constructor takes a jlong. This java long * is used to store the pointer to 'this'. When ScriptRunner makes * native calls, it passes that jlong back, so that it can call the * methods of this C++ class. err(
"setupGateway: cannot find class '%s' : %s",
err(
"setupGateway: cannot find constructor for '%s' : %s",
err(
"setupGateway: cannot construct '%s' : %s",
//======================================================================== //======================================================================== * This is used to grab output from the VM itself. See 'options' below. * This is the most important part of this class. Here we * attempt to find, load, and initialize a java (or mlvm?) virtual * @return true if successful, else false err(
"Could not find 'JNI_CreateJavaVM' in shared library");
//options[nOptions++].optionString = (char *)"-verbose:jni"; err(
"JNI_CreateJavaVM() failed");
// set jvm = NULL, otherwise, this method will return true when called for the second time while the gateway might not have been created! err(
"Java bindings: setupGateway() failed");
* This is a difficult method. What we are doing is trying to * call a static method with a list of arguments. Similar to * a varargs call, we need to marshal the Values into their * Java equivalents and make the proper call. * @param type the return type of the method * @param className the full (package / name) name of the java class * @param methodName the name of the method being invoked * that describes the param and return types of the method. * @param retval the return value of the java method * @return true if the call was successful, else false. This is not * the return value of the method. err(
"Could not find class '%s' : %s",
err(
"Could not find method '%s:%s/%s' : %s",
* Assemble your parameters into a form usable by JNI err(
"Unknown return type: %d",
type);
* Another difficult method. However, this time we are operating * on an existing instance jobject. * @param type the return type of the method * @param obj the instance upon which to make the call * @param methodName the name of the method being invoked * that describes the param and return types of the method. * @param retval the return value of the java method * @return true if the call was successful, else false. This is not * the return value of the method. err(
"Could not find method '%s/%s' : %s",
* Assemble your parameters into a form usable by JNI err(
"Unknown return type: %d",
type);
* Fetch the last exception from the JVM, if any. Clear it to * @return the exception's descriptio,if any. Else "" * Convenience method to call the static void main(String argv[]) * method of a given class * @param className full name of the java class * @args the argument strings to the method * @return true if successful, else false for (
unsigned int i=0 ; i<
args.
size() ; i++)
* Used to register an array of native methods for a named class * @param className the full name of the java class * @param the method array * @return true if successful, else false //msg("registerNatives: class '%s' found", className.c_str()); err(
"Could not get reflect mid for 'getConstructors' : %s",
err(
"Could not register %d native methods for '%s' : %s",
//######################################################################## //########################################################################