|
Added
Link Here
|
| 1 |
/******************************************************************************* |
| 2 |
* Copyright (c) 2008 Intel Corporation, IBM Corporation. |
| 3 |
* All rights reserved. This program and the accompanying materials |
| 4 |
* are made available under the terms of the Eclipse Public License v1.0 |
| 5 |
* which accompanies this distribution, and is available at |
| 6 |
* http://www.eclipse.org/legal/epl-v10.html |
| 7 |
* |
| 8 |
* $Id: TPTPJava.c,v 1.0 2008/01/17 03:35:47 ialelekov Exp $ |
| 9 |
*******************************************************************************/ |
| 10 |
|
| 11 |
/* |
| 12 |
* TPTP JVM provider |
| 13 |
* |
| 14 |
* TODO: error logging, thread synchronization |
| 15 |
* |
| 16 |
*/ |
| 17 |
|
| 18 |
#include <stdio.h> |
| 19 |
#include <stdlib.h> |
| 20 |
#include <string.h> |
| 21 |
|
| 22 |
#include "tptp/TPTPConfig.h" |
| 23 |
#include "tptp/TPTPJava.h" |
| 24 |
|
| 25 |
#define DEFINE_CLASSPATH "-Djava.class.path=" |
| 26 |
|
| 27 |
typedef jint (JNICALL *CreateJavaVM)(JavaVM**, void**, void*); |
| 28 |
|
| 29 |
JavaVM* jvm = NULL; |
| 30 |
|
| 31 |
/* Get the classpath from the system environment */ |
| 32 |
char* getSystemClasspath() { |
| 33 |
int classPathSize = 8096; |
| 34 |
char* classpath; |
| 35 |
int result; |
| 36 |
|
| 37 |
classpath = (char*) malloc(classPathSize); |
| 38 |
while (1) { |
| 39 |
result = getEnvironmentVariable("CLASSPATH", classpath, classPathSize); |
| 40 |
if (result <= classPathSize) break; |
| 41 |
|
| 42 |
classPathSize = result + 1; |
| 43 |
classpath = realloc(classpath, classPathSize); |
| 44 |
} |
| 45 |
|
| 46 |
return classpath; |
| 47 |
} |
| 48 |
|
| 49 |
int createJVM(const char* classpath) { |
| 50 |
DLL_REFERENCE jvmLib; |
| 51 |
CreateJavaVM vmCreate; |
| 52 |
JavaVMInitArgs vmArgs; |
| 53 |
JavaVMOption options[2]; |
| 54 |
JNIEnv* jenv = NULL; |
| 55 |
char* cpe=NULL; |
| 56 |
char* cp=NULL; |
| 57 |
int cplen; |
| 58 |
jint result; |
| 59 |
AC_Config_t* cfg; |
| 60 |
|
| 61 |
cfg = getTPTPConfig(); |
| 62 |
if (cfg == NULL) return AC_CONFIG_NOT_FOUND; |
| 63 |
if (cfg->jvmLibPath == NULL) return JVM_LIB_NOT_SET; |
| 64 |
|
| 65 |
// Load the dynamic library. |
| 66 |
if(!(jvmLib = LOAD_LIBRARY(cfg->jvmLibPath))) return JVM_LOAD_ERROR; |
| 67 |
|
| 68 |
// Resolve the entry point. |
| 69 |
if(!(vmCreate = (CreateJavaVM) RESOLVE_ENTRY_POINT(jvmLib, "JNI_CreateJavaVM"))) { |
| 70 |
return JVM_RESOLVE_ERROR; |
| 71 |
} |
| 72 |
|
| 73 |
vmArgs.nOptions = 0; |
| 74 |
|
| 75 |
#ifdef _WIN32 |
| 76 |
// Add the -Xrs option to prevent JVM shutdown upon user logoff |
| 77 |
options[vmArgs.nOptions++].optionString = "-Xrs"; |
| 78 |
#endif |
| 79 |
|
| 80 |
cplen = 0; |
| 81 |
if (classpath != NULL) |
| 82 |
cplen = strlen(classpath); |
| 83 |
|
| 84 |
cpe = getSystemClasspath(); |
| 85 |
if (cpe != NULL) cplen += strlen(cpe); |
| 86 |
|
| 87 |
if (cplen > 0) { |
| 88 |
cp = (char*) malloc(cplen + strlen(DEFINE_CLASSPATH) + 2); // including PATH_SEPARATOR |
| 89 |
strcpy(cp, DEFINE_CLASSPATH); |
| 90 |
|
| 91 |
if (classpath != NULL) strcat(cp, classpath); |
| 92 |
|
| 93 |
if (cpe != NULL) { |
| 94 |
if (classpath != NULL) { |
| 95 |
cplen = strlen(cp); |
| 96 |
*(cp + cplen) = PATH_SEPARATOR; |
| 97 |
*(cp + cplen + 1) = '\0'; |
| 98 |
} |
| 99 |
|
| 100 |
strcat(cp, cpe); |
| 101 |
} |
| 102 |
|
| 103 |
options[vmArgs.nOptions++].optionString = cp; |
| 104 |
} |
| 105 |
|
| 106 |
vmArgs.options = options; |
| 107 |
vmArgs.version = JNI_VERSION_1_2; |
| 108 |
vmArgs.ignoreUnrecognized = JNI_FALSE; |
| 109 |
|
| 110 |
// Instantiate the JVM, and clean up. |
| 111 |
result = (*vmCreate)(&jvm, (void**)&jenv, (void*)&vmArgs); |
| 112 |
|
| 113 |
if(cp != NULL) free(cp); |
| 114 |
if(cpe != NULL) free(cpe); |
| 115 |
|
| 116 |
return (result == 0) ? 0 : JVM_CREATION_ERROR; |
| 117 |
} |
| 118 |
|
| 119 |
static jstring nativeToJavaString(JNIEnv *env, const char *s) { |
| 120 |
jclass clsString; |
| 121 |
jmethodID mthInit; |
| 122 |
jbyteArray ba = NULL; |
| 123 |
jstring jstr; |
| 124 |
int slen; |
| 125 |
|
| 126 |
clsString = (*env)->FindClass(env, "java/lang/String"); |
| 127 |
if (clsString == NULL) return NULL; |
| 128 |
|
| 129 |
mthInit = (*env)->GetMethodID(env, clsString, "<init>", "([B)V"); |
| 130 |
if (mthInit == NULL) return NULL; |
| 131 |
|
| 132 |
slen = strlen(s); |
| 133 |
ba = (*env)->NewByteArray(env, slen); |
| 134 |
if (ba == NULL) return NULL; |
| 135 |
|
| 136 |
(*env)->SetByteArrayRegion(env, ba, 0, slen, (jbyte *)s); |
| 137 |
jstr = (*env)->NewObject(env, clsString, mthInit, ba); |
| 138 |
(*env)->DeleteLocalRef(env, ba); |
| 139 |
|
| 140 |
return jstr; |
| 141 |
} |
| 142 |
|
| 143 |
static char *JavaToNativeString(JNIEnv *env, jstring jstr) { |
| 144 |
jclass clsString; |
| 145 |
jmethodID mthGetBytes; |
| 146 |
jbyteArray ba = NULL; |
| 147 |
jthrowable ex; |
| 148 |
jint slen; |
| 149 |
char *s = NULL; |
| 150 |
|
| 151 |
clsString = (*env)->FindClass(env, "java/lang/String"); |
| 152 |
if (clsString == NULL) return NULL; |
| 153 |
|
| 154 |
mthGetBytes = (*env)->GetMethodID(env, clsString, "getBytes", "()[B"); |
| 155 |
if (mthGetBytes == NULL) return NULL; |
| 156 |
|
| 157 |
ba = (*env)->CallObjectMethod(env, jstr, mthGetBytes); |
| 158 |
ex = (*env)->ExceptionOccurred(env); |
| 159 |
if (ex != NULL) { |
| 160 |
(*env)->DeleteLocalRef(env, ex); |
| 161 |
return NULL; |
| 162 |
} |
| 163 |
|
| 164 |
slen = (*env)->GetArrayLength(env, ba); |
| 165 |
s = (char *) malloc(slen + 1); |
| 166 |
|
| 167 |
(*env)->GetByteArrayRegion(env, ba, 0, slen, (jbyte *)s); |
| 168 |
*(s+slen) = 0; |
| 169 |
|
| 170 |
(*env)->DeleteLocalRef(env, ba); |
| 171 |
|
| 172 |
return s; |
| 173 |
} |
| 174 |
|
| 175 |
void setClasspath(JNIEnv* jenv, const char* classpath) { |
| 176 |
jclass clsSystem = NULL; |
| 177 |
jmethodID mthGetProp = NULL; |
| 178 |
jmethodID mthSetProp = NULL; |
| 179 |
jobject obj = NULL; |
| 180 |
jstring prop, jcp; |
| 181 |
jthrowable exc; |
| 182 |
char *cp0, *cp; |
| 183 |
|
| 184 |
if (classpath == NULL) return; |
| 185 |
if (strlen(classpath) <= 0) return; |
| 186 |
|
| 187 |
clsSystem = (*jenv)->FindClass(jenv, "java/lang/System"); |
| 188 |
if (clsSystem == NULL) return; |
| 189 |
|
| 190 |
mthGetProp = (*jenv)->GetStaticMethodID(jenv, clsSystem, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;"); |
| 191 |
if (mthGetProp == NULL) return; |
| 192 |
|
| 193 |
mthSetProp = (*jenv)->GetStaticMethodID(jenv, clsSystem, "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); |
| 194 |
if (mthSetProp == NULL) return; |
| 195 |
|
| 196 |
prop = nativeToJavaString(jenv, "java.class.path"); |
| 197 |
if (prop == NULL) return; |
| 198 |
|
| 199 |
jcp = (jstring) (*jenv)->CallStaticObjectMethod(jenv, clsSystem, mthGetProp, prop); |
| 200 |
if (jcp == NULL) return; |
| 201 |
|
| 202 |
cp0 = JavaToNativeString(jenv, jcp); |
| 203 |
if (cp0 == NULL) { |
| 204 |
cp = (char*) classpath; |
| 205 |
} |
| 206 |
else { |
| 207 |
int len = strlen(cp0); |
| 208 |
cp = (char*) malloc(len + strlen(classpath) + 2); // including path separator |
| 209 |
strcpy(cp, cp0); |
| 210 |
*(cp + len) = PATH_SEPARATOR; |
| 211 |
*(cp + len + 1) = '\0'; |
| 212 |
strcat(cp, classpath); |
| 213 |
} |
| 214 |
|
| 215 |
jcp = nativeToJavaString(jenv, cp); |
| 216 |
if (jcp != NULL) { |
| 217 |
(*jenv)->CallStaticObjectMethod(jenv, clsSystem, mthSetProp, prop, jcp); |
| 218 |
|
| 219 |
exc = (*jenv)->ExceptionOccurred(jenv); |
| 220 |
if (exc) { |
| 221 |
(*jenv)->DeleteLocalRef(jenv, exc); |
| 222 |
} |
| 223 |
} |
| 224 |
|
| 225 |
if (cp0 != NULL) { |
| 226 |
free(cp); |
| 227 |
free(cp0); |
| 228 |
} |
| 229 |
} |
| 230 |
|
| 231 |
JavaVM* tptpCreateJVM(const char* classpath) { |
| 232 |
if (jvm == NULL) |
| 233 |
createJVM(classpath); |
| 234 |
else { |
| 235 |
JNIEnv* jenv; |
| 236 |
|
| 237 |
(*jvm)->AttachCurrentThread(jvm, (void**)&jenv, NULL); |
| 238 |
setClasspath(jenv, classpath); |
| 239 |
} |
| 240 |
|
| 241 |
return jvm; |
| 242 |
} |