1 /*
2 * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
1093 * Prints error message and exits if the memory could not be allocated.
1094 */
1095 void *
1096 MemAlloc(size_t size)
1097 {
1098 void *p = malloc(size);
1099 if (p == 0) {
1100 perror("malloc");
1101 exit(1);
1102 }
1103 return p;
1104 }
1105
1106 static jstring platformEncoding = NULL;
1107 static jstring getPlatformEncoding(JNIEnv *env) {
1108 if (platformEncoding == NULL) {
1109 jstring propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
1110 if (propname) {
1111 jclass cls;
1112 jmethodID mid;
1113 NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System"));
1114 NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
1115 env, cls,
1116 "getProperty",
1117 "(Ljava/lang/String;)Ljava/lang/String;"));
1118 platformEncoding = (*env)->CallStaticObjectMethod (
1119 env, cls, mid, propname);
1120 }
1121 }
1122 return platformEncoding;
1123 }
1124
1125 static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
1126 jclass cls;
1127 jmethodID mid;
1128 NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset"));
1129 NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
1130 env, cls,
1131 "isSupported",
1132 "(Ljava/lang/String;)Z"));
1133 return (*env)->CallStaticBooleanMethod (env, cls, mid, enc);
1134 }
1135
1136 /*
1137 * Returns a new Java string object for the specified platform string.
1138 */
1139 static jstring
1140 NewPlatformString(JNIEnv *env, char *s)
1141 {
1142 int len = (int)strlen(s);
1143 jclass cls;
1144 jmethodID mid;
1145 jbyteArray ary;
1146 jstring enc;
1147
1148 if (s == NULL)
1149 return 0;
1150 enc = getPlatformEncoding(env);
1151
1152 ary = (*env)->NewByteArray(env, len);
1153 if (ary != 0) {
1154 jstring str = 0;
1155 (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s);
1156 if (!(*env)->ExceptionOccurred(env)) {
1157 #ifdef GAMMA
1158 /* We support running JVM with older JDK, so here we have to deal */
1159 /* with the case that sun.jnu.encoding is undefined (enc == NULL) */
1160 if (enc != NULL && isEncodingSupported(env, enc) == JNI_TRUE) {
1161 #else
1162 if (isEncodingSupported(env, enc) == JNI_TRUE) {
1163 #endif
1164 NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
1165 NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
1166 "([BLjava/lang/String;)V"));
1167 str = (*env)->NewObject(env, cls, mid, ary, enc);
1168 } else {
1169 /*If the encoding specified in sun.jnu.encoding is not
1170 endorsed by "Charset.isSupported" we have to fall back
1171 to use String(byte[]) explicitly here without specifying
1172 the encoding name, in which the StringCoding class will
1173 pickup the iso-8859-1 as the fallback converter for us.
1174 */
1175 NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
1176 NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
1177 "([B)V"));
1178 str = (*env)->NewObject(env, cls, mid, ary);
1179 }
1180 (*env)->DeleteLocalRef(env, ary);
1181 return str;
1182 }
1183 }
1184 return 0;
1185 }
1186
1187 /*
1188 * Returns a new array of Java string objects for the specified
1189 * array of platform strings.
1190 */
1191 static jobjectArray
1192 NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
1193 {
1194 jarray cls;
1195 jarray ary;
1196 int i;
1197
1198 NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
1199 NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
1200 for (i = 0; i < strc; i++) {
1201 jstring str = NewPlatformString(env, *strv++);
1202 NULL_CHECK0(str);
1203 (*env)->SetObjectArrayElement(env, ary, i, str);
1204 (*env)->DeleteLocalRef(env, str);
1205 }
1206 return ary;
1207 }
1208
1209 /*
1210 * Loads a class, convert the '.' to '/'.
1211 */
1212 static jclass
1213 LoadClass(JNIEnv *env, char *name)
1214 {
1215 char *buf = MemAlloc(strlen(name) + 1);
1216 char *s = buf, *t = name, c;
1217 jclass cls;
1218 jlong start, end;
1219
1220 if (_launcher_debug)
1221 start = CounterGet();
1222
1223 do {
1224 c = *t++;
1225 *s++ = (c == '.') ? '/' : c;
1226 } while (c != '\0');
1227 cls = (*env)->FindClass(env, buf);
1228 free(buf);
1229
1230 if (_launcher_debug) {
1231 end = CounterGet();
1232 printf("%ld micro seconds to load main class\n",
1233 (long)(jint)Counter2Micros(end-start));
1234 printf("----_JAVA_LAUNCHER_DEBUG----\n");
1235 }
1236
1237 return cls;
1238 }
1239
1240
1241 /*
1242 * Returns the main class name for the specified jar file.
1243 */
1244 static jstring
1245 GetMainClassName(JNIEnv *env, char *jarname)
1246 {
1247 #define MAIN_CLASS "Main-Class"
1248 jclass cls;
1249 jmethodID mid;
1250 jobject jar, man, attr;
1251 jstring str, result = 0;
1252
1253 NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile"));
1254 NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
1255 "(Ljava/lang/String;)V"));
1256 NULL_CHECK0(str = NewPlatformString(env, jarname));
1257 NULL_CHECK0(jar = (*env)->NewObject(env, cls, mid, str));
1258 NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "getManifest",
1259 "()Ljava/util/jar/Manifest;"));
1260 man = (*env)->CallObjectMethod(env, jar, mid);
1261 if (man != 0) {
1262 NULL_CHECK0(mid = (*env)->GetMethodID(env,
1263 (*env)->GetObjectClass(env, man),
1264 "getMainAttributes",
1265 "()Ljava/util/jar/Attributes;"));
1266 attr = (*env)->CallObjectMethod(env, man, mid);
1267 if (attr != 0) {
1268 NULL_CHECK0(mid = (*env)->GetMethodID(env,
1269 (*env)->GetObjectClass(env, attr),
1270 "getValue",
1271 "(Ljava/lang/String;)Ljava/lang/String;"));
1272 NULL_CHECK0(str = NewPlatformString(env, MAIN_CLASS));
1273 result = (*env)->CallObjectMethod(env, attr, mid, str);
1454 }
1455
1456 /*
1457 * JVM wants to know launcher type, so tell it.
1458 */
1459 #ifdef GAMMA
1460 void SetJavaLauncherProp() {
1461 AddOption("-Dsun.java.launcher=" LAUNCHER_TYPE, NULL);
1462 }
1463 #endif
1464
1465 /*
1466 * Prints the version information from the java.version and other properties.
1467 */
1468 static void
1469 PrintJavaVersion(JNIEnv *env)
1470 {
1471 jclass ver;
1472 jmethodID print;
1473
1474 NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version"));
1475 NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
1476
1477 (*env)->CallStaticVoidMethod(env, ver, print);
1478 }
1479
1480 /*
1481 * Prints default usage message.
1482 */
1483 static void
1484 PrintUsage(void)
1485 {
1486 int i;
1487
1488 fprintf(stdout,
1489 "Usage: %s [-options] class [args...]\n"
1490 " (to execute a class)\n"
1491 " or %s [-options] -jar jarfile [args...]\n"
1492 " (to execute a jar file)\n"
1493 "\n"
1494 "where options include:\n",
|
1 /*
2 * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
1093 * Prints error message and exits if the memory could not be allocated.
1094 */
1095 void *
1096 MemAlloc(size_t size)
1097 {
1098 void *p = malloc(size);
1099 if (p == 0) {
1100 perror("malloc");
1101 exit(1);
1102 }
1103 return p;
1104 }
1105
1106 static jstring platformEncoding = NULL;
1107 static jstring getPlatformEncoding(JNIEnv *env) {
1108 if (platformEncoding == NULL) {
1109 jstring propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
1110 if (propname) {
1111 jclass cls;
1112 jmethodID mid;
1113 NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
1114 NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
1115 env, cls,
1116 "getProperty",
1117 "(Ljava/lang/String;)Ljava/lang/String;"));
1118 platformEncoding = (*env)->CallStaticObjectMethod (
1119 env, cls, mid, propname);
1120 }
1121 }
1122 return platformEncoding;
1123 }
1124
1125 static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
1126 jclass cls;
1127 jmethodID mid;
1128 NULL_CHECK0 (cls = FindBootStrapClass(env, "java/nio/charset/Charset"));
1129 NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
1130 env, cls,
1131 "isSupported",
1132 "(Ljava/lang/String;)Z"));
1133 return (*env)->CallStaticBooleanMethod (env, cls, mid, enc);
1134 }
1135
1136 /*
1137 * Returns a new Java string object for the specified platform string.
1138 */
1139 static jstring
1140 NewPlatformString(JNIEnv *env, char *s)
1141 {
1142 int len = (int)strlen(s);
1143 jclass cls;
1144 jmethodID mid;
1145 jbyteArray ary;
1146 jstring enc;
1147
1148 if (s == NULL)
1149 return 0;
1150 enc = getPlatformEncoding(env);
1151
1152 ary = (*env)->NewByteArray(env, len);
1153 if (ary != 0) {
1154 jstring str = 0;
1155 (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s);
1156 if (!(*env)->ExceptionOccurred(env)) {
1157 #ifdef GAMMA
1158 /* We support running JVM with older JDK, so here we have to deal */
1159 /* with the case that sun.jnu.encoding is undefined (enc == NULL) */
1160 if (enc != NULL && isEncodingSupported(env, enc) == JNI_TRUE) {
1161 #else
1162 if (isEncodingSupported(env, enc) == JNI_TRUE) {
1163 #endif
1164 NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
1165 NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
1166 "([BLjava/lang/String;)V"));
1167 str = (*env)->NewObject(env, cls, mid, ary, enc);
1168 } else {
1169 /*If the encoding specified in sun.jnu.encoding is not
1170 endorsed by "Charset.isSupported" we have to fall back
1171 to use String(byte[]) explicitly here without specifying
1172 the encoding name, in which the StringCoding class will
1173 pickup the iso-8859-1 as the fallback converter for us.
1174 */
1175 NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
1176 NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
1177 "([B)V"));
1178 str = (*env)->NewObject(env, cls, mid, ary);
1179 }
1180 (*env)->DeleteLocalRef(env, ary);
1181 return str;
1182 }
1183 }
1184 return 0;
1185 }
1186
1187 /*
1188 * Returns a new array of Java string objects for the specified
1189 * array of platform strings.
1190 */
1191 static jobjectArray
1192 NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
1193 {
1194 jarray cls;
1195 jarray ary;
1196 int i;
1197
1198 NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
1199 NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
1200 for (i = 0; i < strc; i++) {
1201 jstring str = NewPlatformString(env, *strv++);
1202 NULL_CHECK0(str);
1203 (*env)->SetObjectArrayElement(env, ary, i, str);
1204 (*env)->DeleteLocalRef(env, str);
1205 }
1206 return ary;
1207 }
1208
1209 /*
1210 * Loads a class, convert the '.' to '/'.
1211 */
1212 static jclass
1213 LoadClass(JNIEnv *env, char *name)
1214 {
1215 char *buf = MemAlloc(strlen(name) + 1);
1216 char *s = buf, *t = name, c;
1217 jclass cls;
1218 jlong start, end;
1219
1220 if (_launcher_debug)
1221 start = CounterGet();
1222
1223 do {
1224 c = *t++;
1225 *s++ = (c == '.') ? '/' : c;
1226 } while (c != '\0');
1227 // use the application class loader for main-class
1228 cls = (*env)->FindClass(env, buf);
1229 free(buf);
1230
1231 if (_launcher_debug) {
1232 end = CounterGet();
1233 printf("%ld micro seconds to load main class\n",
1234 (long)(jint)Counter2Micros(end-start));
1235 printf("----_JAVA_LAUNCHER_DEBUG----\n");
1236 }
1237
1238 return cls;
1239 }
1240
1241
1242 /*
1243 * Returns the main class name for the specified jar file.
1244 */
1245 static jstring
1246 GetMainClassName(JNIEnv *env, char *jarname)
1247 {
1248 #define MAIN_CLASS "Main-Class"
1249 jclass cls;
1250 jmethodID mid;
1251 jobject jar, man, attr;
1252 jstring str, result = 0;
1253
1254 NULL_CHECK0(cls = FindBootStrapClass(env, "java/util/jar/JarFile"));
1255 NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
1256 "(Ljava/lang/String;)V"));
1257 NULL_CHECK0(str = NewPlatformString(env, jarname));
1258 NULL_CHECK0(jar = (*env)->NewObject(env, cls, mid, str));
1259 NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "getManifest",
1260 "()Ljava/util/jar/Manifest;"));
1261 man = (*env)->CallObjectMethod(env, jar, mid);
1262 if (man != 0) {
1263 NULL_CHECK0(mid = (*env)->GetMethodID(env,
1264 (*env)->GetObjectClass(env, man),
1265 "getMainAttributes",
1266 "()Ljava/util/jar/Attributes;"));
1267 attr = (*env)->CallObjectMethod(env, man, mid);
1268 if (attr != 0) {
1269 NULL_CHECK0(mid = (*env)->GetMethodID(env,
1270 (*env)->GetObjectClass(env, attr),
1271 "getValue",
1272 "(Ljava/lang/String;)Ljava/lang/String;"));
1273 NULL_CHECK0(str = NewPlatformString(env, MAIN_CLASS));
1274 result = (*env)->CallObjectMethod(env, attr, mid, str);
1455 }
1456
1457 /*
1458 * JVM wants to know launcher type, so tell it.
1459 */
1460 #ifdef GAMMA
1461 void SetJavaLauncherProp() {
1462 AddOption("-Dsun.java.launcher=" LAUNCHER_TYPE, NULL);
1463 }
1464 #endif
1465
1466 /*
1467 * Prints the version information from the java.version and other properties.
1468 */
1469 static void
1470 PrintJavaVersion(JNIEnv *env)
1471 {
1472 jclass ver;
1473 jmethodID print;
1474
1475 NULL_CHECK(ver = FindBootStrapClass(env, "sun/misc/Version"));
1476 NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
1477
1478 (*env)->CallStaticVoidMethod(env, ver, print);
1479 }
1480
1481 /*
1482 * Prints default usage message.
1483 */
1484 static void
1485 PrintUsage(void)
1486 {
1487 int i;
1488
1489 fprintf(stdout,
1490 "Usage: %s [-options] class [args...]\n"
1491 " (to execute a class)\n"
1492 " or %s [-options] -jar jarfile [args...]\n"
1493 " (to execute a jar file)\n"
1494 "\n"
1495 "where options include:\n",
|