[Jsmooth-cvs] jsmooth/skeletons/commonjava JArgs.cpp, NONE, 1.1 JArgs.h, NONE, 1.1 JClassProxy.cpp,
Status: Beta
Brought to you by:
reyes
Update of /cvsroot/jsmooth/jsmooth/skeletons/commonjava In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv15833 Modified Files: JavaMachineManager.cpp Makefile.win ResourceManager.cpp ResourceManager.h SunJVMLauncher.cpp SunJVMLauncher.h Added Files: JArgs.cpp JArgs.h JClassProxy.cpp JClassProxy.h JMethodCaller.cpp JMethodCaller.h JVMBase.cpp JVMBase.h SunJVMDLL.cpp SunJVMDLL.h SunJVMExe.cpp SunJVMExe.h test.cpp Log Message: Large refactoring of the DLL and EXE launchers --- NEW FILE: JMethodCaller.cpp --- /* JSmooth: a VM wrapper toolkit for Windows Copyright (C) 2003-2007 Rodrigo Reyes <re...@ch...> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JMethodCaller.h" JMethodCaller::JMethodCaller(const std::string& clazz, const std::string& method) : m_isValid(false), m_static(false) { m_clazz = clazz; parseSignature(method); } JMethodCaller::JMethodCaller(const std::string& method) { parseSignature(method); } jvalue JMethodCaller::invoke(SunJVMDLL& jvm, jobject& obj, jvalue args[]) { jvalue res; DEBUG("invoking " + m_clazz + ": " + m_methodname + ", " + getJavaSignature()); jclass cl = jvm.findClass(m_clazz); if (cl == 0) { DEBUG("Can't find class " + m_clazz + " !!"); return res; } jmethodID m = jvm.findMethod(cl, m_methodname, getJavaSignature(), false); switch (m_returntype.TYPE) { case JVOID: jvm.invokeVoid(obj, m, args); break; case JBOOLEAN: res.z = jvm.invokeBoolean(obj, m, args); break; case JBYTE: res.b = jvm.invokeByte(obj, m, args); break; case JCHAR: res.c = jvm.invokeChar(obj, m, args); break; case JSHORT: res.s = jvm.invokeShort(obj, m, args); break; case JINT: res.i = jvm.invokeInt(obj, m, args); break; case JLONG: res.j = jvm.invokeLong(obj, m, args); break; case JFLOAT: res.f = jvm.invokeFloat(obj, m, args); break; case JDOUBLE: res.d = jvm.invokeDouble(obj, m, args); break; case JOBJECT: res.l = jvm.invokeObject(obj, m, args); break; } return res; } jvalue JMethodCaller::invokeStatic(SunJVMDLL& launcher, jvalue args[]) { jvalue res; jclass cl = launcher.findClass(m_clazz); jmethodID m = launcher.findMethod(cl, m_methodname, getJavaSignature(), true); DEBUG("Invoke Static " + m_methodname + " " + getJavaSignature()); switch (m_returntype.TYPE) { case JVOID: launcher.invokeVoidStatic(cl, m, args); break; case JBOOLEAN: res.z = launcher.invokeBooleanStatic(cl, m, args); break; case JBYTE: res.b = launcher.invokeByteStatic(cl, m, args); break; case JCHAR: res.c = launcher.invokeCharStatic(cl, m, args); break; case JSHORT: res.s = launcher.invokeShortStatic(cl, m, args); break; case JINT: res.i = launcher.invokeIntStatic(cl, m, args); break; case JLONG: res.j = launcher.invokeLongStatic(cl, m, args); break; case JOBJECT: res.l = launcher.invokeObjectStatic(cl, m, args); break; } return res; } std::string JMethodCaller::getJavaSignature() { std::string res = "("; for (std::vector<JDATATYPE>::iterator i=m_arguments.begin(); i != m_arguments.end(); i++) { res += StringUtils::replace(getDatatypeSignature(*i), ".", "/"); } res += ")"; res += getDatatypeSignature(m_returntype); return res; } std::string JMethodCaller::getDatatypeSignature(const JDATATYPE& d) { std::string res; for (int j=0; j<d.ARRAYLEVEL; j++) res += "["; switch(d.TYPE) { case JBOOLEAN: res += "Z"; break; case JBYTE: res += "B"; break; case JCHAR: res += "C"; break; case JSHORT: res += "S"; break; case JINT: res += "I"; break; case JLONG: res += "J"; break; case JFLOAT: res += "F"; break; case JDOUBLE: res += "D"; break; case JVOID: res += "V"; break; case JOBJECT: res += "L" + d.CLASSNAME + ";"; break; } return res; } std::string JMethodCaller::toString() { if (m_parsingError != "") return m_parsingError; std::string res = ""; res += "Returntype(" + m_returntype.toString() + ") "; res += "methodname(" + m_methodname + ") "; res += "argumentlist("; for (std::vector<JDATATYPE>::iterator i=m_arguments.begin(); i != m_arguments.end(); i++) { res += "::" + i->toString(); } res += ") "; return res; } bool JMethodCaller::parseSignature(const std::string& fqmethod) { JDATATYPE emptyData; emptyData.ARRAYLEVEL = 0; emptyData.CLASSNAME = ""; emptyData.TYPE = -1; emptyData.INTERNALNAME = ""; // // Clear data // m_returntype = emptyData; m_arguments.clear(); m_methodname = ""; m_parsingError = ""; m_isValid = false; std::vector<std::string> tokens = StringUtils::split(fqmethod, " \t(,);[]", "", false, true); // states of the automata: // 0: expecting the return type (goes to 0 or 1) // 1: expecting the method name or a modifier (goes to 1 or 2) // 2: expecting a ( (goes to 3) // 3: expecting a type (goes to 4) // 4: expecting a modifier, a name, a ",", or a ")" (goes to 3 or 4 or 9) // 9: end of the automata (end) int state = 0; JDATATYPE curData; // DEBUG("Start parsing " + fqmethod); for (std::vector<std::string>::iterator i=tokens.begin(); i != tokens.end(); i++) { while ( (i != tokens.end() ) && ((*i == " ") || (*i == "\t"))) i++; if (i == tokens.end()) { if (state == 9) { m_isValid = true; return true; } m_parsingError = "Uncomplete parsing"; return false; } // DEBUG("Current non-space token: " + *i + ", state: " + StringUtils::toString(state)); string tok = *i; switch (state) { // 0: expecting the return type case 0: { int type = parseType(tok); curData = emptyData; if (type == JOBJECT) { curData.TYPE = JOBJECT; curData.CLASSNAME = tok; } else curData.TYPE = type; // DEBUG("Return type found : " + StringUtils::toString(curData.TYPE)); state = 1; } break; case 1: if (tok == "[") { while ( (i != tokens.end()) && (*i != "]") ) i++; if (i == tokens.end()) { m_parsingError = "Unfinished array modifier"; return false; } curData.ARRAYLEVEL++; // DEBUG("Return type modifier: array+1"); } else { m_returntype = curData; curData = emptyData; m_methodname = tok; // DEBUG("Found method name: " + tok); state = 2; } break; case 2: if (tok == "(") state = 3; else { m_parsingError = "Expecting a (, got a " + tok; return false; } // DEBUG("Now parsing arguments..."); break; case 3: { int type = parseType(tok); // DEBUG("Argument type parsed: " + StringUtils::toString(type)); curData = emptyData; if (type == JOBJECT) { curData.TYPE = JOBJECT; curData.CLASSNAME = tok; } else curData.TYPE = type; state = 4; } break; case 4: if (tok == ")") { // DEBUG("End of argument list"); m_arguments.push_back(curData); state = 9; } else if (tok == ",") { m_arguments.push_back(curData); state = 3; // DEBUG("New argument starting"); } else if (tok == "[") { // DEBUG("Array started, looking for end"); while ( (i != tokens.end()) && (*i != "]") ) { // DEBUG("Array-skipping " + *i); i++; } if (i == tokens.end()) { m_parsingError = "Unfinished array modifier"; // DEBUG(m_parsingError); return false; } else i++; curData.ARRAYLEVEL++; // DEBUG("Parsed array modifier"); } else { if (curData.INTERNALNAME == "") curData.INTERNALNAME = tok; else { m_parsingError = "Unexpected token " + tok; return false; } } break; case 9: // DEBUG("Completed successfully"); m_isValid = true; return true; default: DEBUG("ERROR, unknown state " + StringUtils::toString(state)); } // DEBUG("New state: " + StringUtils::toString(state)); } if (state == 9) { // DEBUG("Parsed correctly"); m_isValid = true; return true; } // DEBUG("INCORRECT STATE"); return false; } int JMethodCaller::parseType(const std::string& tok) { if (tok == "boolean") return JBOOLEAN; else if (tok == "byte") return JBYTE; else if (tok == "char") return JCHAR; else if (tok == "short") return JSHORT; else if (tok == "int") return JINT; else if (tok == "long") return JLONG; else if (tok == "double") return JDOUBLE; else if (tok == "void") return JVOID; else return JOBJECT; } --- NEW FILE: SunJVMExe.h --- /* JSmooth: a VM wrapper toolkit for Windows Copyright (C) 2003-2007 Rodrigo Reyes <re...@ch...> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __SUNJVMEXE_H_ #define __SUNJVMEXE_H_ #include <string> #include "Version.h" #include "StringUtils.h" #include "FileUtils.h" #include "ResourceManager.h" #include "JavaProperty.h" #include "JVMBase.h" /** * Manages a Sun's JVM available on the computer. * @author Rodrigo Reyes <re...@ch...> */ class SunJVMExe : public JVMBase { private: std::string m_jrehome; Version m_version; public: SunJVMExe(const std::string& jrehome); SunJVMExe(const std::string& jrehome, const Version& v); Version guessVersion(); bool run(const std::string& mainclass, bool useconsole); std::string lookUpExecutable(bool useconsole); std::string getClassPath(bool full); private: }; #endif --- NEW FILE: SunJVMDLL.cpp --- /* JSmooth: a VM wrapper toolkit for Windows Copyright (C) 2003-2007 Rodrigo Reyes <re...@ch...> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "SunJVMDLL.h" #include "JClassProxy.h" SunJVMDLL::SunJVMDLL(const std::string& jvmdll, const Version& v) { m_dllpath = jvmdll; m_version = v; m_statusCode = SunJVMDLL::JVM_NOT_STARTED; m_vmlib = NULL; } SunJVMDLL::~SunJVMDLL() { if (m_vmlib != NULL) { FreeLibrary(m_vmlib); } } bool SunJVMDLL::run(const std::string& mainclass) { if (m_statusCode == SunJVMDLL::JVM_NOT_STARTED) instanciate(); if (m_statusCode == SunJVMDLL::JVM_LOADED) { JClassProxy disp(this, mainclass); jstring emptystr = newUTFString(std::string("")); jobjectArray mainargs = newObjectArray(m_arguments.size(), "java.lang.String", emptystr); for (int i =0; i<m_arguments.size(); i++) { env()->SetObjectArrayElement(mainargs, i, newUTFString(m_arguments[i])); } printf("arguments array = %d\n", mainargs); jvalue ma[1]; ma[0].l = mainargs; disp.invokeStatic(std::string("void main(java.lang.String[] args)"), ma); return true; } return false; } bool SunJVMDLL::instanciate() { m_vmlib = LoadLibrary(m_dllpath.c_str()); if (m_vmlib == NULL) { m_statusCode = SunJVMDLL::JVM_DLL_CANT_LOAD; return false; } CreateJavaVM_t CreateJavaVM = (CreateJavaVM_t)GetProcAddress(m_vmlib, "JNI_CreateJavaVM"); GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs = (GetDefaultJavaVMInitArgs_t)GetProcAddress(m_vmlib, "JNI_GetDefaultJavaVMInitArgs"); if ((CreateJavaVM == NULL) || (GetDefaultJavaVMInitArgs == NULL)) { m_statusCode = SunJVMDLL::JVM_CANT_USE_VM; return false; } DEBUG("VM Created successfully"); m_javavm = new JavaVM(); m_javaenv = new JNIEnv(); bool res; if ((m_version.getMajor() == 1) && (m_version.getMinor() == 1)) res = setupVM11DLL(CreateJavaVM, GetDefaultJavaVMInitArgs); else res = setupVM12DLL(CreateJavaVM, GetDefaultJavaVMInitArgs); if (res) { m_statusCode = SunJVMDLL::JVM_LOADED; return true; } return false; } bool SunJVMDLL::setupVM12DLL(CreateJavaVM_t CreateJavaVM, GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs) { vector<string> jpropstrv; for (int i=0; i<m_properties.size(); i++) jpropstrv.push_back( "-D" + m_properties[i].getName() + "=" + m_properties[i].getValue()); // DEBUG("MAXHEAP: " + StringUtils::toString(m_maxHeap)); // DEBUG("INITIALHEAP: " + StringUtils::toString(m_initialHeap)); if (m_maxHeap > 0) { jpropstrv.push_back("-Xmx" +StringUtils::toString(m_maxHeap)); } if (m_initialHeap > 0) { jpropstrv.push_back("-Xms" + StringUtils::toString(m_initialHeap)); } JavaVMInitArgs vm_args; GetDefaultJavaVMInitArgs(&vm_args); JavaVMOption options[1 + jpropstrv.size()]; std::string cpoption = "-Djava.class.path=" + StringUtils::join(m_pathElements, ";"); DEBUG("Classpath: " + cpoption); options[0].optionString = (char*)cpoption.c_str(); vm_args.version = 0x00010002; vm_args.version = JNI_VERSION_1_2; vm_args.options = options; vm_args.nOptions = 1 + jpropstrv.size(); for (int i=0; i<jpropstrv.size(); i++) { options[1 + i].optionString = (char*)jpropstrv[i].c_str(); DEBUG(string("Option added:") + options[1+i].optionString); } vm_args.ignoreUnrecognized = JNI_TRUE; // // Create the VM if (CreateJavaVM( &m_javavm, &m_javaenv, &vm_args) != 0) { DEBUG("Can't create VM"); m_statusCode = SunJVMDLL::JVM_CANT_CREATE_VM; return false; } DEBUG("VM 1.2+ Created successfully !!"); return true; } bool SunJVMDLL::setupVM11DLL(CreateJavaVM_t CreateJavaVM, GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs) { JDK1_1InitArgs vm_args; vm_args.version = 0x00010001; GetDefaultJavaVMInitArgs(&vm_args); if (m_maxHeap > 0) vm_args.maxHeapSize = m_maxHeap; if (m_initialHeap > 0) vm_args.minHeapSize = m_initialHeap; // // create the properties array // char const * props[m_properties.size()+1]; vector<string> jpropstrv; for (int i=0; i<m_properties.size(); i++) jpropstrv[i] = m_properties[i].getName() + "=" + m_properties[i].getValue(); for (int i=0; i<m_properties.size(); i++) props[i] = jpropstrv[i].c_str(); props[m_properties.size()] = NULL; vm_args.properties = (char**)props; /* Append USER_CLASSPATH to the default system class path */ std::string classpath = vm_args.classpath; classpath += StringUtils::join(m_pathElements, ";"); DEBUG("Classpath = " + classpath); vm_args.classpath = (char*)classpath.c_str(); // // Create the VM if (CreateJavaVM( &m_javavm, &m_javaenv, &vm_args) != 0) { DEBUG("Can't create VM"); m_statusCode = SunJVMDLL::JVM_CANT_CREATE_VM; return false; } DEBUG("VM 1.1 Created successfully !!"); return true; } jclass SunJVMDLL::findClass(const std::string& clazz) { std::string classname = StringUtils::replace(clazz,".", "/"); DEBUG("Looking up for class <" + classname + ">"); jclass cls = env()->FindClass(classname.c_str()); if (cls == 0) DEBUG("Can't find class " + classname + " !"); return cls; } jmethodID SunJVMDLL::findMethod(jclass& cls, const std::string& methodname, const std::string& signature, bool isStatic) { jmethodID mid; if (isStatic) mid = env()->GetStaticMethodID(cls, methodname.c_str(), signature.c_str()); else mid = env()->GetMethodID(cls, methodname.c_str(), signature.c_str()); return mid; } JavaVM* SunJVMDLL::getJavaVM() { return m_javavm; } jstring SunJVMDLL::newUTFString(const std::string& str) { return env()->NewStringUTF(str.c_str()); } jobject SunJVMDLL::newObject(jclass clazz, jmethodID& methodid, jvalue arguments[]) { return env()->NewObjectA(clazz, methodid, arguments); } jobjectArray SunJVMDLL::newObjectArray(int size, jclass clazz, jobject initialValue) { return env()->NewObjectArray((jsize)size, clazz, initialValue); } jobjectArray SunJVMDLL::newObjectArray(int size, const std::string& classname, jobject initialValue) { jclass cls = findClass(classname); return newObjectArray(size, cls, initialValue); } // // Static method invocation // void SunJVMDLL::invokeVoidStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]) { env()->CallStaticVoidMethodA(clazz, methodid, arguments); } jboolean SunJVMDLL::invokeBooleanStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]) { return env()->CallStaticBooleanMethodA(clazz, methodid, arguments); } jbyte SunJVMDLL::invokeByteStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]) { return env()->CallStaticByteMethodA(clazz, methodid, arguments); } jchar SunJVMDLL::invokeCharStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]) { return env()->CallStaticCharMethodA(clazz, methodid, arguments); } jshort SunJVMDLL::invokeShortStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]) { return env()->CallStaticShortMethodA(clazz, methodid, arguments); } jint SunJVMDLL::invokeIntStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]) { return env()->CallStaticIntMethodA(clazz, methodid, arguments); } jlong SunJVMDLL::invokeLongStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]) { return env()->CallStaticLongMethodA(clazz, methodid, arguments); } jfloat SunJVMDLL::invokeFloatStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]) { return env()->CallStaticFloatMethodA(clazz, methodid, arguments); } jdouble SunJVMDLL::invokeDoubleStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]) { return env()->CallStaticDoubleMethodA(clazz, methodid, arguments); } jobject SunJVMDLL::invokeObjectStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]) { return env()->CallStaticObjectMethodA(clazz, methodid, arguments); } // // method invocation // void SunJVMDLL::invokeVoid(jobject& obj, jmethodID& methodid, jvalue arguments[]) { env()->CallVoidMethodA(obj, methodid, arguments); } jboolean SunJVMDLL::invokeBoolean(jobject& obj, jmethodID& methodid, jvalue arguments[]) { return env()->CallBooleanMethodA(obj, methodid, arguments); } jbyte SunJVMDLL::invokeByte(jobject& obj, jmethodID& methodid, jvalue arguments[]) { return env()->CallByteMethodA(obj, methodid, arguments); } jchar SunJVMDLL::invokeChar(jobject& obj, jmethodID& methodid, jvalue arguments[]) { return env()->CallCharMethodA(obj, methodid, arguments); } jshort SunJVMDLL::invokeShort(jobject& obj, jmethodID& methodid, jvalue arguments[]) { return env()->CallShortMethodA(obj, methodid, arguments); } jint SunJVMDLL::invokeInt(jobject& obj, jmethodID& methodid, jvalue arguments[]) { return env()->CallIntMethodA(obj, methodid, arguments); } jlong SunJVMDLL::invokeLong(jobject& obj, jmethodID& methodid, jvalue arguments[]) { return env()->CallLongMethodA(obj, methodid, arguments); } jfloat SunJVMDLL::invokeFloat(jobject& obj, jmethodID& methodid, jvalue arguments[]) { return env()->CallFloatMethodA(obj, methodid, arguments); } jdouble SunJVMDLL::invokeDouble(jobject& obj, jmethodID& methodid, jvalue arguments[]) { return env()->CallDoubleMethodA(obj, methodid, arguments); } jobject SunJVMDLL::invokeObject(jobject& obj, jmethodID& methodid, jvalue arguments[]) { return env()->CallObjectMethodA(obj, methodid, arguments); } Index: ResourceManager.h =================================================================== RCS file: /cvsroot/jsmooth/jsmooth/skeletons/commonjava/ResourceManager.h,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** ResourceManager.h 12 Apr 2007 20:01:50 -0000 1.13 --- ResourceManager.h 28 Apr 2007 08:43:43 -0000 1.14 *************** *** 60,63 **** --- 60,65 ---- HGLOBAL m_jarHandler; int m_jarSize; + + std::vector<std::string> m_arguments; std::vector<std::string> m_deleteOnFinalize; *************** *** 168,171 **** --- 170,175 ---- void addUserArgument(std::string argument); + std::vector<std::string> getArguments(); + int getResourceSize(int id); HGLOBAL getResource(int id); --- NEW FILE: JArgs.cpp --- /* JSmooth: a VM wrapper toolkit for Windows Copyright (C) 2003-2007 Rodrigo Reyes <re...@ch...> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JArgs.h" JArgs::JArgs() { } JArgs::JArgs(SunJVMDLL* vm) { m_vm = vm; } jvalue* JArgs::allocArray() { jvalue* args = new jvalue[m_values.size()]; for (int i=0; i<m_values.size(); i++) { args[i] = m_values[i]; } return args; } JArgs& JArgs::add(int i) { jvalue v; v.i = i; m_values.push_back(v); return *this; } JArgs& JArgs::add(jobject &o) { jvalue v; v.l = o; m_values.push_back(v); return *this; } JArgs& JArgs::add(bool b) { jvalue v; v.z = b; m_values.push_back(v); return *this; } JArgs& JArgs::add(const std::string& str ) { jvalue v; v.l = m_vm->newUTFString(str); m_values.push_back(v); return *this; } --- NEW FILE: SunJVMDLL.h --- /* JSmooth: a VM wrapper toolkit for Windows Copyright (C) 2003-2007 Rodrigo Reyes <re...@ch...> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __SUNJVMDLL_H_ #define __SUNJVMDLL_H_ #include <string> #include "jni.h" #include "Version.h" #include "StringUtils.h" #include "FileUtils.h" #include "ResourceManager.h" #include "JavaProperty.h" #include "JVMBase.h" typedef jint (JNICALL *CreateJavaVM_t)(JavaVM **pvm, JNIEnv **env, void *args); typedef jint (JNICALL *GetDefaultJavaVMInitArgs_t)(void *args); /** * Manages a Sun's JVM available on the computer. * @author Rodrigo Reyes <re...@ch...> */ class SunJVMDLL : public JVMBase { public: enum StatusCode { JVM_NOT_STARTED=0, JVM_DLL_CANT_LOAD , JVM_CANT_CREATE_VM , JVM_CANT_USE_VM, JVM_LOADED } ; /** * The path to the .DLL that can be used to create a JVM * instance. The string may be empty is the information is not * known. */ std::string m_dllpath; Version m_version; HINSTANCE m_vmlib; StatusCode m_statusCode; protected: JavaVM *m_javavm; JNIEnv *m_javaenv; public: SunJVMDLL(const std::string& jvmdll, const Version& v); ~SunJVMDLL(); bool instanciate(); bool setupVM12DLL(CreateJavaVM_t CreateJavaVM, GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs); bool setupVM11DLL(CreateJavaVM_t CreateJavaVM, GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs); JNIEnv* env() { JNIEnv* env; jint result = m_javavm->AttachCurrentThread((void**)&env, 0); return env; } bool run(const std::string& mainclass); jclass findClass(const std::string& clazz); jmethodID findMethod(jclass& cls, const std::string& methodname, const std::string& signature, bool isStatic); JavaVM* getJavaVM(); jstring newUTFString(const std::string& str); jobject newObject(jclass clazz, jmethodID& methodid, jvalue arguments[]); jobjectArray newObjectArray(int size, jclass clazz, jobject initialValue); jobjectArray newObjectArray(int size, const std::string& classname, jobject initialValue); void invokeVoidStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); jboolean invokeBooleanStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); jbyte invokeByteStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); jchar invokeCharStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); jshort invokeShortStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); jint invokeIntStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); jlong invokeLongStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); jfloat invokeFloatStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); jdouble invokeDoubleStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); jobject invokeObjectStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); void invokeVoid(jobject& obj, jmethodID& methodid, jvalue arguments[]); jboolean invokeBoolean(jobject& obj, jmethodID& methodid, jvalue arguments[]); jbyte invokeByte(jobject& obj, jmethodID& methodid, jvalue arguments[]); jchar invokeChar(jobject& obj, jmethodID& methodid, jvalue arguments[]); jshort invokeShort(jobject& obj, jmethodID& methodid, jvalue arguments[]); jint invokeInt(jobject& obj, jmethodID& methodid, jvalue arguments[]); jlong invokeLong(jobject& obj, jmethodID& methodid, jvalue arguments[]); jfloat invokeFloat(jobject& obj, jmethodID& methodid, jvalue arguments[]); jdouble invokeDouble(jobject& obj, jmethodID& methodid, jvalue arguments[]); jobject invokeObject(jobject& obj, jmethodID& methodid, jvalue arguments[]); }; #endif Index: SunJVMLauncher.h =================================================================== RCS file: /cvsroot/jsmooth/jsmooth/skeletons/commonjava/SunJVMLauncher.h,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** SunJVMLauncher.h 12 Apr 2007 20:01:50 -0000 1.11 --- SunJVMLauncher.h 28 Apr 2007 08:43:43 -0000 1.12 *************** *** 23,27 **** #include <string> ! #include <jni.h> #include "Version.h" --- 23,27 ---- #include <string> ! #include "jni.h" #include "Version.h" *************** *** 31,34 **** --- 31,37 ---- #include "JavaProperty.h" + #include "SunJVMDLL.h" + #include "SunJVMExe.h" + typedef jint (JNICALL *CreateJavaVM_t)(JavaVM **pvm, JNIEnv **env, void *args); typedef jint (JNICALL *GetDefaultJavaVMInitArgs_t)(void *args); *************** *** 55,60 **** }; ! int Status; ! protected: --- 58,62 ---- }; ! int LaunchingStatus; protected: *************** *** 105,111 **** --- 107,118 ---- * false otherwise. */ + virtual bool runProc(ResourceManager& resource, bool noConsole, const string& origin); + virtual bool setupVM(ResourceManager& resource, JVMBase* vm); + + std::string toString() const; + Version guessVersionByProcess(const string& exepath); *************** *** 119,122 **** --- 126,138 ---- int destroyVM(); + JavaVM* getJavaVM(); + + jclass findClass(const std::string& clazz); + jmethodID findMethod(jclass& cls, const std::string& methodname, const std::string& signature, bool isStatic); + + void invokeVoidStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); + // jvaluea invokeIntStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); + jint invokeIntStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); + jlong invokeLongStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]); private: *************** *** 129,135 **** bool runVM11proc(ResourceManager& resource, bool noConsole, const string& origin); bool runVM12proc(ResourceManager& resource, bool noConsole, const string& origin); ! ! std::string sizeToString(int size); ! std::string sizeToString(std::string size); }; --- 145,149 ---- bool runVM11proc(ResourceManager& resource, bool noConsole, const string& origin); bool runVM12proc(ResourceManager& resource, bool noConsole, const string& origin); ! }; Index: JavaMachineManager.cpp =================================================================== RCS file: /cvsroot/jsmooth/jsmooth/skeletons/commonjava/JavaMachineManager.cpp,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** JavaMachineManager.cpp 9 Apr 2007 17:18:16 -0000 1.16 --- JavaMachineManager.cpp 28 Apr 2007 08:43:43 -0000 1.17 *************** *** 120,136 **** { DEBUG("- Trying to use PATH"); ! string exename = dontUseConsole?"javaw.exe":"java.exe"; SunJVMLauncher launcher; ! launcher.VmVersion = launcher.guessVersionByProcess("java.exe"); ! if (launcher.VmVersion.isValid() ! && (!min.isValid() || (min <= launcher.VmVersion)) ! && (!max.isValid() || (launcher.VmVersion <= max))) ! { ! DEBUG("Found valid java machine " + exename + " on PATH (" + launcher.VmVersion.toString() + ")"); ! Version v12("1.2.0"); ! if (launcher.runExe(exename, false, m_resman, dontUseConsole, (launcher.VmVersion<v12)?"1.1":"1.2", "path")) ! return true; ! } } } --- 120,140 ---- { DEBUG("- Trying to use PATH"); ! SunJVMLauncher launcher; ! return launcher.runProc(m_resman, ! dontUseConsole, "path"); ! ! // string exename = dontUseConsole?"javaw.exe":"java.exe"; ! // SunJVMLauncher launcher; ! // launcher.VmVersion = launcher.guessVersionByProcess("java.exe"); ! // if (launcher.VmVersion.isValid() ! // && (!min.isValid() || (min <= launcher.VmVersion)) ! // && (!max.isValid() || (launcher.VmVersion <= max))) ! // { ! // DEBUG("Found valid java machine " + exename + " on PATH (" + launcher.VmVersion.toString() + ")"); ! // Version v12("1.2.0"); ! // if (launcher.runExe(exename, false, m_resman, dontUseConsole, (launcher.VmVersion<v12)?"1.1":"1.2", "path")) ! // return true; ! // } } } Index: Makefile.win =================================================================== RCS file: /cvsroot/jsmooth/jsmooth/skeletons/commonjava/Makefile.win,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Makefile.win 12 Apr 2007 20:01:50 -0000 1.6 --- Makefile.win 28 Apr 2007 08:43:43 -0000 1.7 *************** *** 8,13 **** MINGW = RES = ! OBJ = JavaMachineManager.o JVMEnvVarLookup.o JVMRegistryLookup.o MSJViewLauncher.o Properties.o ResourceManager.o SunJVMLauncher.o Version.o global.o JavaProperty.o $(RES) ! LINKOBJ = JavaMachineManager.o JVMEnvVarLookup.o JVMRegistryLookup.o MSJViewLauncher.o Properties.o ResourceManager.o SunJVMLauncher.o Version.o global.o JavaProperty.o $(RES) LIBS = -L"$(MINGW)/lib" INCS = -I"../util-core" -I"$(MINGW)/include" -I"$(JDK)/include" -I"$(JDK)/include/win32" --- 8,13 ---- MINGW = RES = ! OBJ = JVMBase.o SunJVMExe.o JArgs.o JClassProxy.o SunJVMDLL.o JavaMachineManager.o JVMEnvVarLookup.o JVMRegistryLookup.o MSJViewLauncher.o Properties.o ResourceManager.o SunJVMLauncher.o Version.o global.o JavaProperty.o JMethodCaller.o $(RES) ! LINKOBJ = JVMBase.o SunJVMExe.o JArgs.o JClassProxy.o SunJVMDLL.o JavaMachineManager.o JVMEnvVarLookup.o JVMRegistryLookup.o MSJViewLauncher.o Properties.o ResourceManager.o SunJVMLauncher.o Version.o global.o JavaProperty.o JMethodCaller.o $(RES) LIBS = -L"$(MINGW)/lib" INCS = -I"../util-core" -I"$(MINGW)/include" -I"$(JDK)/include" -I"$(JDK)/include/win32" *************** *** 25,31 **** $(RM) $(OBJ) $(BIN) ! $(BIN): $(LINKOBJ) ar r $(BIN) $(LINKOBJ) ranlib $(BIN) JavaMachineManager.o: JavaMachineManager.cpp --- 25,32 ---- $(RM) $(OBJ) $(BIN) ! $(BIN): $(LINKOBJ) test.cpp ar r $(BIN) $(LINKOBJ) ranlib $(BIN) + $(CPP) $(CXXFLAGS) test.cpp $(BIN) ../util-core/util-core.a -o test.exe JavaMachineManager.o: JavaMachineManager.cpp --- NEW FILE: JMethodCaller.h --- /* JSmooth: a VM wrapper toolkit for Windows Copyright (C) 2003-2007 Rodrigo Reyes <re...@ch...> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JMETHODCALLER_H_ #define __JMETHODCALLER_H_ #include <string> #include <vector> #include "common.h" #include "StringUtils.h" #include "SunJVMDLL.h" /** * * @author Rodrigo Reyes <re...@ch...> */ class JMethodCaller { enum { JBOOLEAN = 1, JBYTE, JCHAR, JSHORT, JINT, JLONG, JFLOAT, JDOUBLE, JVOID, JOBJECT } ; struct JDATATYPE { int TYPE; std::string CLASSNAME; int ARRAYLEVEL; std::string INTERNALNAME; std::string toString() { std::string modifier = ""; for (int i=0; i<ARRAYLEVEL; i++) modifier += "[]"; switch(TYPE) { case JBOOLEAN: return "boolean " + INTERNALNAME + modifier; case JBYTE: return "byte " + INTERNALNAME + modifier; case JCHAR: return "char " + INTERNALNAME + modifier; case JSHORT: return "short " + INTERNALNAME + modifier; case JINT: return "int " + INTERNALNAME + modifier; case JLONG: return "long " + INTERNALNAME + modifier; case JFLOAT: return "float " + INTERNALNAME + modifier; case JDOUBLE: return "double " + INTERNALNAME + modifier; case JVOID: return "void " + INTERNALNAME + modifier; case JOBJECT: return "Class " + CLASSNAME + " " + INTERNALNAME + modifier; } return "<UnknownJavaType>" + modifier; } }; private: bool m_static; std::string m_clazz; std::string m_methodname; JDATATYPE m_returntype; std::vector<JDATATYPE> m_arguments; std::string m_parsingError; bool m_isValid; public: JMethodCaller(const std::string& clazz, const std::string& method); JMethodCaller(const std::string& method); jvalue invokeStatic(SunJVMDLL& launcher, jvalue args[]); jvalue invoke(SunJVMDLL& jvm, jobject& obj, jvalue args[]); std::string toString(); std::string getJavaSignature(); private: bool parseSignature(const std::string& fqmethod); std::string getDatatypeSignature(const JDATATYPE& d); int parseType(const std::string& tok); }; #endif Index: ResourceManager.cpp =================================================================== RCS file: /cvsroot/jsmooth/jsmooth/skeletons/commonjava/ResourceManager.cpp,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** ResourceManager.cpp 12 Apr 2007 20:01:50 -0000 1.21 --- ResourceManager.cpp 28 Apr 2007 08:43:43 -0000 1.22 *************** *** 59,63 **** return; } ! // // loads the jar information --- 59,69 ---- return; } ! ! // ! // Split the arguments ! // ! m_arguments = StringUtils::split(getProperty(KEY_ARGUMENTS, ""), " \t\n\r", "\"\'"); ! ! // // loads the jar information *************** *** 260,264 **** for (map<string, string>::iterator i = props.begin(); i != props.end(); i++) { ! DEBUG(" - Property: " + i->first + "=" + i->second); } } --- 266,270 ---- for (map<string, string>::iterator i = props.begin(); i != props.end(); i++) { ! DEBUG(" - Property: " + i->first + "=<" + i->second+">"); } } *************** *** 266,271 **** void ResourceManager::setUserArguments(std::vector<std::string> arguments) { ! if (arguments.size() > 0) ! setProperty(KEY_ARGUMENTS, ""); for (std::vector<std::string>::iterator i=arguments.begin(); i != arguments.end(); i++) { --- 272,277 ---- void ResourceManager::setUserArguments(std::vector<std::string> arguments) { ! m_arguments.clear(); ! for (std::vector<std::string>::iterator i=arguments.begin(); i != arguments.end(); i++) { *************** *** 291,299 **** else { ! setProperty(KEY_ARGUMENTS, getProperty(KEY_ARGUMENTS) + " " + StringUtils::fixQuotes(argument) ); ! DEBUG("Added user argument " + argument); } } int ResourceManager::getResourceSize(int id) { --- 297,310 ---- else { ! m_arguments.push_back(argument); ! // setProperty(KEY_ARGUMENTS, getProperty(KEY_ARGUMENTS) + " " + StringUtils::requoteForCommandLine(StringUtils::escape(argument)) ); } } + std::vector<std::string> ResourceManager::getArguments() + { + return m_arguments; + } + int ResourceManager::getResourceSize(int id) { Index: SunJVMLauncher.cpp =================================================================== RCS file: /cvsroot/jsmooth/jsmooth/skeletons/commonjava/SunJVMLauncher.cpp,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** SunJVMLauncher.cpp 12 Apr 2007 20:01:50 -0000 1.25 --- SunJVMLauncher.cpp 28 Apr 2007 08:43:43 -0000 1.26 *************** *** 20,23 **** --- 20,28 ---- #include "SunJVMLauncher.h" + #include "Process.h" + + #include "SunJVMDLL.h" + #include "JArgs.h" + #include "JClassProxy.h" extern "C" { [...1654 lines suppressed...] ! ! // jint SunJVMLauncher::invokeIntStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]) ! // { ! // JNIEnv *env = new JNIEnv(); ! // jint result = m_javavm->AttachCurrentThread((void**)&env, 0); ! // DEBUG("Attached thread to the VM: " + StringUtils::toString(result)); ! // JNIEnv* jenv = env; ! ! // return jenv->CallStaticIntMethodA(clazz, methodid, arguments); ! // } ! ! // jlong SunJVMLauncher::invokeLongStatic(jclass clazz, jmethodID& methodid, jvalue arguments[]) ! // { ! // JNIEnv *env = new JNIEnv(); ! // jint result = m_javavm->AttachCurrentThread((void**)&env, 0); ! // DEBUG("Attached thread to the VM: " + StringUtils::toString(result)); ! // JNIEnv* jenv = env; ! ! // return jenv->CallStaticLongMethodA(clazz, methodid, arguments); ! // } --- NEW FILE: JClassProxy.cpp --- /* JSmooth: a VM wrapper toolkit for Windows Copyright (C) 2003-2007 Rodrigo Reyes <re...@ch...> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JClassProxy.h" JClassProxy::JClassProxy(SunJVMDLL* vm, const std::string& classname) { m_vm = vm; m_class = m_vm->findClass(classname); m_classname = classname; } jobject JClassProxy::newInstance(const std::string& signature, JArgs args) { jvalue* jv = args.allocArray(); jobject res = newInstance(signature, jv); delete jv; return res; } jobject JClassProxy::newInstance(const std::string& signature, jvalue arguments[]) { JMethodCaller caller(signature); jmethodID m = m_vm->findMethod(m_class, "<init>", caller.getJavaSignature(), false); printf("Constructor %s:%s: %d/%d\n", signature.c_str(), caller.getJavaSignature().c_str(), m, m_class); return m_vm->newObject(m_class, m, arguments); } jvalue JClassProxy::invoke(jobject& obj, const std::string& fqmethod, JArgs args) { JMethodCaller jmc(m_classname, fqmethod); jvalue* jv = args.allocArray(); jvalue res = jmc.invoke(*m_vm, obj, jv); delete jv; return res; } jvalue JClassProxy::invoke(jobject& obj, const std::string& fqmethod, jvalue arguments[]) { DEBUG("INVOKING " + m_classname + " :: " + fqmethod); JMethodCaller jmc(m_classname, fqmethod); return jmc.invoke(*m_vm, obj, arguments); } jvalue JClassProxy::invokeStatic(const std::string& fqmethod, JArgs args) { JMethodCaller jmc(m_classname, fqmethod); jvalue* jv = args.allocArray(); jvalue res = jmc.invokeStatic(*m_vm, jv); delete jv; return res; } jvalue JClassProxy::invokeStatic(const std::string& fqmethod, jvalue arguments[]) { JMethodCaller jmc(m_classname, fqmethod); return jmc.invokeStatic(*m_vm, arguments); } --- NEW FILE: JVMBase.cpp --- /* JSmooth: a VM wrapper toolkit for Windows Copyright (C) 2003-2007 Rodrigo Reyes <re...@ch...> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JVMBase.h" JVMBase::JVMBase() { m_maxHeap = -1; m_initialHeap = -1; } void JVMBase::addPathElement(const std::string& element) { m_pathElements.push_back(element); } void JVMBase::addProperty(const JavaProperty& prop) { m_properties.push_back(prop); } void JVMBase::setMaxHeap(long size) { m_maxHeap = size; } void JVMBase::setInitialHeap(long size) { m_initialHeap = size; } void JVMBase::addArgument(const std::string& arg) { // m_arguments.push_back(StringUtils::requoteForCommandLine(arg)); m_arguments.push_back(arg); } void JVMBase::setArguments(const std::string& args) { m_arguments.clear(); DEBUG("arguments:<" + args + ">"); // std::string ua = StringUtils::unescape(args); // DEBUG("arguments unescaped:<" + ua + ">"); vector<string> splitted = StringUtils::split(args, " \t\n\r", "\"\'", false); for (int i=0; i<splitted.size(); i++) { DEBUG("SPLITTED-ARG[" + StringUtils::toString(i)+"]="+ splitted[i]); this->addArgument(splitted[i]); } } --- NEW FILE: SunJVMExe.cpp --- /* JSmooth: a VM wrapper toolkit for Windows Copyright (C) 2003-2007 Rodrigo Reyes <re...@ch...> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "SunJVMExe.h" #include <vector> #include <string> #include "Process.h" #include "FileUtils.h" SunJVMExe::SunJVMExe(const std::string& jrehome) { m_jrehome = jrehome; } SunJVMExe::SunJVMExe(const std::string& jrehome, const Version& v) { m_jrehome = jrehome; m_version = v; } bool SunJVMExe::run(const std::string& mainclass, bool useconsole) { if (!m_version.isValid()) { m_version = guessVersion(); } if (!m_version.isValid()) return false; std::vector<std::string> execv; execv.push_back(StringUtils::requoteForCommandLine(lookUpExecutable(useconsole))); if (m_maxHeap > 0) { if ((m_version.getMajor()==1)&&(m_version.getMinor()==1)) execv.push_back("-mx" + StringUtils::toString(m_maxHeap)); else execv.push_back("-Xmx" + StringUtils::toString(m_maxHeap)); } if (m_initialHeap > 0) { if ((m_version.getMajor()==1)&&(m_version.getMinor()==1)) execv.push_back("-ms" + StringUtils::toString(m_initialHeap)); else execv.push_back("-Xms" + StringUtils::toString(m_initialHeap)); } for (int i=0; i<m_properties.size(); i++) execv.push_back( StringUtils::requoteForCommandLine("-D" + m_properties[i].getName()) + "=" + StringUtils::requoteForCommandLine(m_properties[i].getValue())); std::string classpath; if ((m_version.getMajor()==1)&&(m_version.getMinor()==1)) classpath = getClassPath(true); else classpath = getClassPath(false); if (classpath.size() > 0) execv.push_back("-classpath " + StringUtils::requoteForCommandLine(classpath)); execv.push_back(mainclass); for (int i=0; i<m_arguments.size(); i++) { execv.push_back( StringUtils::requoteForCommandLine(m_arguments[i]) ); } std::string execmd = StringUtils::join(execv, " "); DEBUG("COMMAND: <" + execmd + ">"); Process proc(execmd, useconsole); if (proc.run()) { DEBUG("Started successfully"); proc.join(); return true; } else { DEBUG("Failed running " + execmd); } return false; } std::string SunJVMExe::lookUpExecutable(bool useconsole) { std::string java; if (m_jrehome.size() == 0) { return useconsole?"java.exe":"javaw.exe"; } if (useconsole) { if (FileUtils::fileExists(m_jrehome, "bin\\java.exe")) java = FileUtils::concFile(m_jrehome, "bin\\java.exe"); else if (FileUtils::fileExists(m_jrehome, "bin\\jre.exe")) java = FileUtils::concFile(m_jrehome, "bin\\jre.exe"); else { std::vector<std::string> javas = FileUtils::recursiveSearch(m_jrehome, "java.exe"); DEBUG("REC: " + StringUtils::toString(javas)); if (javas.size() == 0) javas = FileUtils::recursiveSearch(m_jrehome, "jre.exe"); if (javas.size() > 0) java = javas[0]; } } else { if (FileUtils::fileExists(m_jrehome, "bin\\javaw.exe")) java = FileUtils::concFile(m_jrehome, "bin\\javaw.exe"); else if (FileUtils::fileExists(m_jrehome, "bin\\jrew.exe")) java = FileUtils::concFile(m_jrehome, "bin\\jrew.exe"); else { std::vector<std::string> javas = FileUtils::recursiveSearch(m_jrehome, "javaw.exe"); DEBUG("REC: " + StringUtils::toString(javas)); if (javas.size() == 0) javas = FileUtils::recursiveSearch(m_jrehome, "jrew.exe"); if (javas.size() > 0) java = javas[0]; } } return java; } Version SunJVMExe::guessVersion() { std::string exepath = lookUpExecutable(true); string exeline = exepath + " -version"; Version result; // Return immediatly if the exe does not exist if (!FileUtils::fileExists(exepath)) return result; string tmpfilename = FileUtils::createTempFileName(".tmp"); Process proc(exeline, true); proc.setRedirect(tmpfilename); proc.run(); proc.join(); std::string voutput = FileUtils::readFile(tmpfilename); vector<string> split = StringUtils::split(voutput, " \t\n\r", "\""); for (vector<string>::iterator i=split.begin(); i != split.end(); i++) { Version v(*i); if (v.isValid()) { result = v; break; } } FileUtils::deleteOnReboot(tmpfilename); return result; } std::string SunJVMExe::getClassPath(bool full) { std::vector<std::string> cp; for (std::vector<std::string>::const_iterator i=m_pathElements.begin(); i!=m_pathElements.end(); i++) cp.push_back(*i); if (full) { std::string javaexe = lookUpExecutable(true); std::string home = FileUtils::getParent( FileUtils::getParent( javaexe )); if (FileUtils::fileExists(home)) { vector<string> cpzips = FileUtils::recursiveSearch(home, "*.zip"); cp.insert(cp.end(), cpzips.begin(), cpzips.end()); vector<string> cpjars = FileUtils::recursiveSearch(home, "*.jar"); cp.insert(cp.end(), cpjars.begin(), cpjars.end()); } } return StringUtils::join(cp, ";"); } --- NEW FILE: JArgs.h --- /* JSmooth: a VM wrapper toolkit for Windows Copyright (C) 2003-2007 Rodrigo Reyes <re...@ch...> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JARGS_H_ #define __JARGS_H_ #include "jni.h" #include "StringUtils.h" #include "SunJVMDLL.h" class JArgs { private: std::vector<jvalue> m_values; SunJVMDLL* m_vm; public: JArgs(); JArgs(SunJVMDLL* vm); JArgs(int i) { add(i); } JArgs(bool i) { add(i); } JArgs(jobject& o) { add(o); } JArgs(const std::string& o) { add(o); } jvalue* allocArray(); JArgs& add(int i); JArgs& add(bool b); JArgs& add(jobject& obj); JArgs& add(jobjectArray& arr) { add((jobject)arr); } JArgs& add(jstring& obj) { return add((jstring)obj); } JArgs& add(const std::string& str ); JArgs& operator+(int i) { return add(i); } JArgs& operator+(bool i) { return add(i); } JArgs& operator+(jobject& i) { return add(i); } JArgs& operator+(const std::string& i) { return add(i); } }; #endif --- NEW FILE: JClassProxy.h --- /* JSmooth: a VM wrapper toolkit for Windows Copyright (C) 2003-2007 Rodrigo Reyes <re...@ch...> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __JCLASSPROXY_H_ #define __JCLASSPROXY_H_ #include <string> #include <vector> #include "common.h" #include "StringUtils.h" #include "SunJVMDLL.h" /** * * @author Rodrigo Reyes <re...@ch...> */ #include "JMethodCaller.h" #include "SunJVMDLL.h" #include "JArgs.h" class JClassProxy { private: jclass m_class; SunJVMDLL* m_vm; std::string m_classname; public: JClassProxy(SunJVMDLL* vm, const std::string& classname); jobject newInstance(const std::string& signature, JArgs args); jobject newInstance(const std::string& signature, jvalue arguments[]); jvalue invoke(jobject& obj, const std::string& fqmethod, JArgs args); jvalue invoke(jobject& obj, const std::string& fqmethod, jvalue arguments[]); jvalue invokeStatic(const std::string& fqmethod, JArgs args); jvalue invokeStatic(const std::string& fqmethod, jvalue arguments[]); }; #endif --- NEW FILE: test.cpp --- #include "JClassProxy.h" #include "JMethodCaller.h" #include "SunJVMDLL.h" #include "SunJVMExe.h" #include "Thread.h" #include "JVMRegistryLookup.h" void _debugOutput(const std::string& text) { printf("%s\n", text.c_str()); } void _debugWaitKey() { } void thread_test(void* param) { SunJVMDLL* jvm = (SunJVMDLL*)param; jclass c1 = jvm->findClass("java.lang.System"); printf("class java.lang.System = %d\n", c1); jmethodID m1 = jvm->findMethod(c1, "currentTimeMillis", "()J", true); printf("method currentTimeMillis = %d\n", m1); jvalue v[0]; for(int i=0; i<100; i++) { long t = jvm->invokeLongStatic(c1, m1, v); printf("%d... current millis : %ld\n", i, t); Thread::sleep(1000); fflush(stdout); } } int test_dll() { SunJVMDLL jvm("c:\\Program Files\\Java\\jdk1.5.0_11\\jre\\bin\\client\\jvm.dll", Version("1.2")); //SunJVMDLL jvm("c:\\Program Files\\JavaSoft\\JRE\\1.1\\bin\\javai.dll", Version("1.1")); jvm.addPathElement("..\\..\\sample\\sample.jar"); jvm.setMaxHeap(6231616); jvm.setInitialHeap(6231616); jvm.instanciate(); JClassProxy disp(&jvm, "JSmoothPropertiesDisplayer"); jstring emptystr = jvm.newUTFString(std::string("")); jobjectArray mainargs = jvm.newObjectArray(0, "java.lang.String", emptystr); printf("arguments array = %d\n", mainargs); jvalue ma[1]; ma[0].l = mainargs; disp.invokeStatic(std::string("void main(java.lang.String[] args)"), ma); jvalue frameargs[1]; JClassProxy frameproxy(&jvm, "javax.swing.JFrame"); jstring str = jvm.newUTFString(std::string("Ceci est un test!")); jobject frame2 = frameproxy.newInstance("void javax.swing.JFrame(java.lang.String str)", JArgs((jobject)str)); printf("FRAME=%d\n", frame2); frameproxy.invoke(frame2, "void setVisible(boolean b)", JArgs((bool)true)); Thread t1; t1.start(thread_test, &jvm); t1.sleep(6000); Thread t2; t2.start(thread_test,&jvm); t1.join(); t2.join(); } int main() { std::string jrehome = "c:\\Program Files\\JavaSoft\\JRE\\1.1"; // jrehome = "c:\\Program Files\\JavaSoft\\JRE\\1.3.1_02"; SunJVMExe jre(jrehome); jre.addPathElement("."); jre.addPathElement("..\\..\\sample\\sample.jar"); jre.setMaxHeap(6231616); jre.setInitialHeap(6231616); //SunJVMDLL jvm("c:\\Program Files\\JavaSoft\\JRE\\1.1\\bin\\javai.dll", Version("1.1")); DEBUG( "FOUND: " + jre.lookUpExecutable(false) ); DEBUG("Version...: " + jre.guessVersion().toString()); DEBUG("PARENT: " + FileUtils::getParent(jrehome)); DEBUG("CP1= " + jre.getClassPath(false)); DEBUG("CP2= " + jre.getClassPath(true)); jre.run("maclasse", false); vector<SunJVMLauncher> launchers = JVMRegistryLookup::lookupJVM(); for (int i=0; i<launchers.size(); i++) { DEBUG(launchers[i].toString()); } } --- NEW FILE: JVMBase.h --- /* JSmooth: a VM wrapper toolkit for Windows Copyright (C) 2003-2007 Rodrigo Reyes <re...@ch...> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __SUNJVMBASE_H_ #define __SUNJVMBASE_H_ #include <string> #include "jni.h" #include "Version.h" #include "StringUtils.h" #include "FileUtils.h" #include "ResourceManager.h" #include "JavaProperty.h" /** * @author Rodrigo Reyes <re...@ch...> */ class JVMBase { protected: std::vector<std::string> m_pathElements; std::vector<JavaProperty> m_properties; int m_maxHeap; int m_initialHeap; std::vector<std::string> m_arguments; public: JVMBase(); void addPathElement(const std::string& element); void addProperty(const JavaProperty& prop); void setMaxHeap(long size); void setInitialHeap(long size); void addArgument(const std::string& arg); void setArguments(const std::string& args); }; #endif |