hotspot/src/os/linux/launcher/java.c

Print this page
rev 611 : Merge
   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",