jdk/src/share/bin/java.c
changeset 1323 e14a3b3536cd
parent 1145 404b11752c57
child 2624 1ae5a9028dd4
equal deleted inserted replaced
1322:d038148778cc 1323:e14a3b3536cd
   100                                char **pclassname, int *pret, const char *jvmpath);
   100                                char **pclassname, int *pret, const char *jvmpath);
   101 static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv,
   101 static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv,
   102                               InvocationFunctions *ifn);
   102                               InvocationFunctions *ifn);
   103 static jstring NewPlatformString(JNIEnv *env, char *s);
   103 static jstring NewPlatformString(JNIEnv *env, char *s);
   104 static jobjectArray NewPlatformStringArray(JNIEnv *env, char **strv, int strc);
   104 static jobjectArray NewPlatformStringArray(JNIEnv *env, char **strv, int strc);
   105 static jclass LoadClass(JNIEnv *env, char *name);
   105 static jclass LoadMainClass(JNIEnv *env, jboolean isJar, char *name);
   106 static jstring GetMainClassName(JNIEnv *env, char *jarname);
       
   107 
   106 
   108 static void TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv);
   107 static void TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv);
   109 static jboolean AddApplicationOptions(int cpathc, const char **cpathv);
   108 static jboolean AddApplicationOptions(int cpathc, const char **cpathv);
   110 static void SetApplicationClassPath(const char**);
   109 static void SetApplicationClassPath(const char**);
   111 
   110 
   299 
   298 
   300     return ContinueInNewThread(&ifn, argc, argv, jarfile, classname, ret);
   299     return ContinueInNewThread(&ifn, argc, argv, jarfile, classname, ret);
   301 
   300 
   302 }
   301 }
   303 
   302 
       
   303 #define CHECK_EXCEPTION_NULL_LEAVE(e) \
       
   304     if ((*env)->ExceptionOccurred(env)) { \
       
   305         JLI_ReportExceptionDescription(env); \
       
   306         goto leave; \
       
   307     } \
       
   308     if ((e) == NULL) { \
       
   309         JLI_ReportErrorMessage(JNI_ERROR); \
       
   310         goto leave; \
       
   311     }
       
   312 
       
   313 #define CHECK_EXCEPTION_LEAVE(rv) \
       
   314     if ((*env)->ExceptionOccurred(env)) { \
       
   315         JLI_ReportExceptionDescription(env); \
       
   316         ret = (rv); \
       
   317         goto leave; \
       
   318     }
   304 
   319 
   305 int JNICALL
   320 int JNICALL
   306 JavaMain(void * _args)
   321 JavaMain(void * _args)
   307 {
   322 {
   308     JavaMainArgs *args = (JavaMainArgs *)_args;
   323     JavaMainArgs *args = (JavaMainArgs *)_args;
   319     jmethodID mainID;
   334     jmethodID mainID;
   320     jobjectArray mainArgs;
   335     jobjectArray mainArgs;
   321     int ret = 0;
   336     int ret = 0;
   322     jlong start, end;
   337     jlong start, end;
   323 
   338 
   324 
       
   325     /* Initialize the virtual machine */
   339     /* Initialize the virtual machine */
   326 
       
   327     start = CounterGet();
   340     start = CounterGet();
   328     if (!InitializeJVM(&vm, &env, &ifn)) {
   341     if (!InitializeJVM(&vm, &env, &ifn)) {
   329         JLI_ReportErrorMessage(JVM_ERROR1);
   342         JLI_ReportErrorMessage(JVM_ERROR1);
   330         exit(1);
   343         exit(1);
   331     }
   344     }
   332 
   345 
   333     if (printVersion || showVersion) {
   346     if (printVersion || showVersion) {
   334         PrintJavaVersion(env, showVersion);
   347         PrintJavaVersion(env, showVersion);
   335         if ((*env)->ExceptionOccurred(env)) {
   348         CHECK_EXCEPTION_LEAVE(0);
   336             JLI_ReportExceptionDescription(env);
       
   337             JLI_ReportErrorMessage(JNI_ERROR);
       
   338             goto leave;
       
   339         }
       
   340         if (printVersion) {
   349         if (printVersion) {
   341             ret = 0;
   350             ret = 0;
   342             goto leave;
   351             goto leave;
   343         }
   352         }
   344     }
   353     }
   345 
   354 
   346     /* If the user specified neither a class name nor a JAR file */
   355     /* If the user specified neither a class name nor a JAR file */
   347     if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) {
   356     if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) {
   348         PrintUsage(env, printXUsage);
   357         PrintUsage(env, printXUsage);
   349         if ((*env)->ExceptionOccurred(env)) {
   358         CHECK_EXCEPTION_LEAVE(1);
   350             JLI_ReportExceptionDescription(env);
       
   351             JLI_ReportErrorMessage(JNI_ERROR);
       
   352             ret=1;
       
   353         }
       
   354         goto leave;
   359         goto leave;
   355     }
   360     }
   356 
   361 
   357     FreeKnownVMs();  /* after last possible PrintUsage() */
   362     FreeKnownVMs();  /* after last possible PrintUsage() */
   358 
   363 
   393      *          all environments,
   398      *          all environments,
   394      *     2)   Remove the vestages of maintaining main_class through
   399      *     2)   Remove the vestages of maintaining main_class through
   395      *          the environment (and remove these comments).
   400      *          the environment (and remove these comments).
   396      */
   401      */
   397     if (jarfile != 0) {
   402     if (jarfile != 0) {
   398         mainClassName = GetMainClassName(env, jarfile);
   403         mainClass = LoadMainClass(env, JNI_TRUE, jarfile);
   399         if ((*env)->ExceptionOccurred(env)) {
       
   400             JLI_ReportExceptionDescription(env);
       
   401             JLI_ReportErrorMessage(JNI_ERROR);
       
   402             goto leave;
       
   403         }
       
   404         if (mainClassName == NULL) {
       
   405           JLI_ReportErrorMessage(JAR_ERROR1,jarfile, GEN_ERROR);
       
   406           goto leave;
       
   407         }
       
   408         classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
       
   409         if (classname == NULL) {
       
   410             JLI_ReportExceptionDescription(env);
       
   411             JLI_ReportErrorMessage(JNI_ERROR);
       
   412             goto leave;
       
   413         }
       
   414         mainClass = LoadClass(env, classname);
       
   415         if(mainClass == NULL) { /* exception occured */
       
   416             JLI_ReportExceptionDescription(env);
       
   417             JLI_ReportErrorMessage(CLS_ERROR1, classname);
       
   418             goto leave;
       
   419         }
       
   420         (*env)->ReleaseStringUTFChars(env, mainClassName, classname);
       
   421     } else {
   404     } else {
   422       mainClassName = NewPlatformString(env, classname);
   405         mainClass = LoadMainClass(env, JNI_FALSE, classname);
   423       if (mainClassName == NULL) {
   406     }
   424         JLI_ReportErrorMessage(CLS_ERROR2, classname, GEN_ERROR);
   407     CHECK_EXCEPTION_NULL_LEAVE(mainClass);
   425         goto leave;
   408 
   426       }
   409     /*
   427       classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
   410      * The LoadMainClass not only loads the main class, it will also ensure
   428       if (classname == NULL) {
   411      * that the main method's signature is correct, therefore further checking
   429         JLI_ReportExceptionDescription(env);
   412      * is not required. The main method is invoked here so that extraneous java
   430         JLI_ReportErrorMessage(JNI_ERROR);
   413      * stacks are not in the application stack trace.
   431         goto leave;
   414      */
   432       }
       
   433       mainClass = LoadClass(env, classname);
       
   434       if(mainClass == NULL) { /* exception occured */
       
   435         JLI_ReportExceptionDescription(env);
       
   436         JLI_ReportErrorMessage(CLS_ERROR1, classname);
       
   437         goto leave;
       
   438       }
       
   439       (*env)->ReleaseStringUTFChars(env, mainClassName, classname);
       
   440     }
       
   441 
       
   442     /* Get the application's main method */
       
   443     mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
   415     mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
   444                                        "([Ljava/lang/String;)V");
   416                                        "([Ljava/lang/String;)V");
   445     if (mainID == NULL) {
   417     CHECK_EXCEPTION_NULL_LEAVE(mainID);
   446         if ((*env)->ExceptionOccurred(env)) {
       
   447             JLI_ReportExceptionDescription(env);
       
   448             JLI_ReportErrorMessage(JNI_ERROR);
       
   449         } else {
       
   450           JLI_ReportErrorMessage(CLS_ERROR3);
       
   451         }
       
   452         goto leave;
       
   453     }
       
   454 
       
   455     {    /* Make sure the main method is public */
       
   456         jint mods;
       
   457         jmethodID mid;
       
   458         jobject obj = (*env)->ToReflectedMethod(env, mainClass,
       
   459                                                 mainID, JNI_TRUE);
       
   460 
       
   461         if( obj == NULL) { /* exception occurred */
       
   462             JLI_ReportExceptionDescription(env);
       
   463             JLI_ReportErrorMessage(JNI_ERROR);
       
   464             goto leave;
       
   465         }
       
   466 
       
   467         mid =
       
   468           (*env)->GetMethodID(env,
       
   469                               (*env)->GetObjectClass(env, obj),
       
   470                               "getModifiers", "()I");
       
   471         if ((*env)->ExceptionOccurred(env)) {
       
   472             JLI_ReportExceptionDescription(env);
       
   473             JLI_ReportErrorMessage(JNI_ERROR);
       
   474             goto leave;
       
   475         }
       
   476 
       
   477         mods = (*env)->CallIntMethod(env, obj, mid);
       
   478         if ((mods & 1) == 0) { /* if (!Modifier.isPublic(mods)) ... */
       
   479             JLI_ReportErrorMessage(CLS_ERROR4);
       
   480             goto leave;
       
   481         }
       
   482     }
       
   483 
   418 
   484     /* Build argument array */
   419     /* Build argument array */
   485     mainArgs = NewPlatformStringArray(env, argv, argc);
   420     mainArgs = NewPlatformStringArray(env, argv, argc);
   486     if (mainArgs == NULL) {
   421     CHECK_EXCEPTION_NULL_LEAVE(mainArgs);
   487         JLI_ReportExceptionDescription(env);
       
   488         JLI_ReportErrorMessage(JNI_ERROR);
       
   489         goto leave;
       
   490     }
       
   491 
   422 
   492     /* Invoke main method. */
   423     /* Invoke main method. */
   493     (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
   424     (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
   494 
   425 
   495     /*
   426     /*
   496      * The launcher's exit code (in the absence of calls to
   427      * The launcher's exit code (in the absence of calls to
   497      * System.exit) will be non-zero if main threw an exception.
   428      * System.exit) will be non-zero if main threw an exception.
   498      */
   429      */
   499     ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
   430     ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
   500 
   431 
   501     /*
   432 leave:
   502      * Detach the main thread so that it appears to have ended when
   433     /*
       
   434      * Always detach the main thread so that it appears to have ended when
   503      * the application's main method exits.  This will invoke the
   435      * the application's main method exits.  This will invoke the
   504      * uncaught exception handler machinery if main threw an
   436      * uncaught exception handler machinery if main threw an
   505      * exception.  An uncaught exception handler cannot change the
   437      * exception.  An uncaught exception handler cannot change the
   506      * launcher's return code except by calling System.exit.
   438      * launcher's return code except by calling System.exit.
   507      */
   439      */
   508     if ((*vm)->DetachCurrentThread(vm) != 0) {
   440     if ((*vm)->DetachCurrentThread(vm) != 0) {
   509         JLI_ReportErrorMessage(JVM_ERROR2);
   441         JLI_ReportErrorMessage(JVM_ERROR2);
   510         ret = 1;
   442         ret = 1;
   511         goto leave;
   443     }
   512     }
       
   513 
       
   514  leave:
       
   515     /*
   444     /*
   516      * Wait for all non-daemon threads to end, then destroy the VM.
   445      * Wait for all non-daemon threads to end, then destroy the VM.
   517      * This will actually create a trivial new Java waiter thread
   446      * This will actually create a trivial new Java waiter thread
   518      * named "DestroyJavaVM", but this will be seen as a different
   447      * named "DestroyJavaVM", but this will be seen as a different
   519      * thread from the one that executed main, even though they are
   448      * thread from the one that executed main, even though they are
   522      */
   451      */
   523     (*vm)->DestroyJavaVM(vm);
   452     (*vm)->DestroyJavaVM(vm);
   524 
   453 
   525     return ret;
   454     return ret;
   526 }
   455 }
   527 
       
   528 
   456 
   529 /*
   457 /*
   530  * Checks the command line options to find which JVM type was
   458  * Checks the command line options to find which JVM type was
   531  * specified.  If no command line option was given for the JVM type,
   459  * specified.  If no command line option was given for the JVM type,
   532  * the default type is used.  The environment variable
   460  * the default type is used.  The environment variable
  1157     if (platformEncoding == NULL) {
  1085     if (platformEncoding == NULL) {
  1158         jstring propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
  1086         jstring propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
  1159         if (propname) {
  1087         if (propname) {
  1160             jclass cls;
  1088             jclass cls;
  1161             jmethodID mid;
  1089             jmethodID mid;
  1162             NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System"));
  1090             NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
  1163             NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
  1091             NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
  1164                                    env, cls,
  1092                                    env, cls,
  1165                                    "getProperty",
  1093                                    "getProperty",
  1166                                    "(Ljava/lang/String;)Ljava/lang/String;"));
  1094                                    "(Ljava/lang/String;)Ljava/lang/String;"));
  1167             platformEncoding = (*env)->CallStaticObjectMethod (
  1095             platformEncoding = (*env)->CallStaticObjectMethod (
  1172 }
  1100 }
  1173 
  1101 
  1174 static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
  1102 static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
  1175     jclass cls;
  1103     jclass cls;
  1176     jmethodID mid;
  1104     jmethodID mid;
  1177     NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset"));
  1105     NULL_CHECK0 (cls = FindBootStrapClass(env, "java/nio/charset/Charset"));
  1178     NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
  1106     NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
  1179                            env, cls,
  1107                            env, cls,
  1180                            "isSupported",
  1108                            "isSupported",
  1181                            "(Ljava/lang/String;)Z"));
  1109                            "(Ljava/lang/String;)Z"));
  1182     return (*env)->CallStaticBooleanMethod(env, cls, mid, enc);
  1110     return (*env)->CallStaticBooleanMethod(env, cls, mid, enc);
  1201     ary = (*env)->NewByteArray(env, len);
  1129     ary = (*env)->NewByteArray(env, len);
  1202     if (ary != 0) {
  1130     if (ary != 0) {
  1203         jstring str = 0;
  1131         jstring str = 0;
  1204         (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s);
  1132         (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s);
  1205         if (!(*env)->ExceptionOccurred(env)) {
  1133         if (!(*env)->ExceptionOccurred(env)) {
       
  1134             NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
  1206             if (isEncodingSupported(env, enc) == JNI_TRUE) {
  1135             if (isEncodingSupported(env, enc) == JNI_TRUE) {
  1207                 NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
       
  1208                 NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
  1136                 NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
  1209                                           "([BLjava/lang/String;)V"));
  1137                                           "([BLjava/lang/String;)V"));
  1210                 str = (*env)->NewObject(env, cls, mid, ary, enc);
  1138                 str = (*env)->NewObject(env, cls, mid, ary, enc);
  1211             } else {
  1139             } else {
  1212                 /*If the encoding specified in sun.jnu.encoding is not
  1140                 /*If the encoding specified in sun.jnu.encoding is not
  1213                   endorsed by "Charset.isSupported" we have to fall back
  1141                   endorsed by "Charset.isSupported" we have to fall back
  1214                   to use String(byte[]) explicitly here without specifying
  1142                   to use String(byte[]) explicitly here without specifying
  1215                   the encoding name, in which the StringCoding class will
  1143                   the encoding name, in which the StringCoding class will
  1216                   pickup the iso-8859-1 as the fallback converter for us.
  1144                   pickup the iso-8859-1 as the fallback converter for us.
  1217                 */
  1145                 */
  1218                 NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
       
  1219                 NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
  1146                 NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
  1220                                           "([B)V"));
  1147                                           "([B)V"));
  1221                 str = (*env)->NewObject(env, cls, mid, ary);
  1148                 str = (*env)->NewObject(env, cls, mid, ary);
  1222             }
  1149             }
  1223             (*env)->DeleteLocalRef(env, ary);
  1150             (*env)->DeleteLocalRef(env, ary);
  1236 {
  1163 {
  1237     jarray cls;
  1164     jarray cls;
  1238     jarray ary;
  1165     jarray ary;
  1239     int i;
  1166     int i;
  1240 
  1167 
  1241     NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
  1168     NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
  1242     NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
  1169     NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
  1243     for (i = 0; i < strc; i++) {
  1170     for (i = 0; i < strc; i++) {
  1244         jstring str = NewPlatformString(env, *strv++);
  1171         jstring str = NewPlatformString(env, *strv++);
  1245         NULL_CHECK0(str);
  1172         NULL_CHECK0(str);
  1246         (*env)->SetObjectArrayElement(env, ary, i, str);
  1173         (*env)->SetObjectArrayElement(env, ary, i, str);
  1248     }
  1175     }
  1249     return ary;
  1176     return ary;
  1250 }
  1177 }
  1251 
  1178 
  1252 /*
  1179 /*
  1253  * Loads a class, convert the '.' to '/'.
  1180  * Loads a class and verifies that the main class is present and it is ok to
       
  1181  * call it for more details refer to the java implementation.
  1254  */
  1182  */
  1255 static jclass
  1183 static jclass
  1256 LoadClass(JNIEnv *env, char *name)
  1184 LoadMainClass(JNIEnv *env, jboolean isJar, char *name)
  1257 {
  1185 {
  1258     char *buf = JLI_MemAlloc(JLI_StrLen(name) + 1);
       
  1259     char *s = buf, *t = name, c;
       
  1260     jclass cls;
  1186     jclass cls;
       
  1187     jmethodID mid;
       
  1188     jstring str;
       
  1189     jobject result;
  1261     jlong start, end;
  1190     jlong start, end;
  1262 
  1191 
  1263     if (JLI_IsTraceLauncher())
  1192     if (JLI_IsTraceLauncher()) {
  1264         start = CounterGet();
  1193         start = CounterGet();
  1265 
  1194     }
  1266     do {
  1195     NULL_CHECK0(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper"));
  1267         c = *t++;
  1196     NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls, "checkAndLoadMain",
  1268         *s++ = (c == '.') ? '/' : c;
  1197                                           "(ZZLjava/lang/String;)Ljava/lang/Object;"));
  1269     } while (c != '\0');
  1198     str = (*env)->NewStringUTF(env, name);
  1270     cls = (*env)->FindClass(env, buf);
  1199     result = (*env)->CallStaticObjectMethod(env, cls, mid, JNI_TRUE, isJar, str);
  1271     JLI_MemFree(buf);
       
  1272 
  1200 
  1273     if (JLI_IsTraceLauncher()) {
  1201     if (JLI_IsTraceLauncher()) {
  1274         end   = CounterGet();
  1202         end   = CounterGet();
  1275         printf("%ld micro seconds to load main class\n",
  1203         printf("%ld micro seconds to load main class\n",
  1276                (long)(jint)Counter2Micros(end-start));
  1204                (long)(jint)Counter2Micros(end-start));
  1277         printf("----_JAVA_LAUNCHER_DEBUG----\n");
  1205         printf("----_JAVA_LAUNCHER_DEBUG----\n");
  1278     }
  1206     }
  1279 
  1207 
  1280     return cls;
  1208     return (jclass)result;
  1281 }
  1209 }
  1282 
       
  1283 
       
  1284 /*
       
  1285  * Returns the main class name for the specified jar file.
       
  1286  */
       
  1287 static jstring
       
  1288 GetMainClassName(JNIEnv *env, char *jarname)
       
  1289 {
       
  1290 #define MAIN_CLASS "Main-Class"
       
  1291     jclass cls;
       
  1292     jmethodID mid;
       
  1293     jobject jar, man, attr;
       
  1294     jstring str, result = 0;
       
  1295 
       
  1296     NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile"));
       
  1297     NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
       
  1298                                           "(Ljava/lang/String;)V"));
       
  1299     NULL_CHECK0(str = NewPlatformString(env, jarname));
       
  1300     NULL_CHECK0(jar = (*env)->NewObject(env, cls, mid, str));
       
  1301     NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "getManifest",
       
  1302                                           "()Ljava/util/jar/Manifest;"));
       
  1303     man = (*env)->CallObjectMethod(env, jar, mid);
       
  1304     if (man != 0) {
       
  1305         NULL_CHECK0(mid = (*env)->GetMethodID(env,
       
  1306                                     (*env)->GetObjectClass(env, man),
       
  1307                                     "getMainAttributes",
       
  1308                                     "()Ljava/util/jar/Attributes;"));
       
  1309         attr = (*env)->CallObjectMethod(env, man, mid);
       
  1310         if (attr != 0) {
       
  1311             NULL_CHECK0(mid = (*env)->GetMethodID(env,
       
  1312                                     (*env)->GetObjectClass(env, attr),
       
  1313                                     "getValue",
       
  1314                                     "(Ljava/lang/String;)Ljava/lang/String;"));
       
  1315             NULL_CHECK0(str = NewPlatformString(env, MAIN_CLASS));
       
  1316             result = (*env)->CallObjectMethod(env, attr, mid, str);
       
  1317         }
       
  1318     }
       
  1319     return result;
       
  1320 }
       
  1321 
       
  1322 
  1210 
  1323 /*
  1211 /*
  1324  * For tools, convert command line args thus:
  1212  * For tools, convert command line args thus:
  1325  *   javac -cp foo:foo/"*" -J-ms32m ...
  1213  *   javac -cp foo:foo/"*" -J-ms32m ...
  1326  *   java -ms32m -cp JLI_WildcardExpandClasspath(foo:foo/"*") ...
  1214  *   java -ms32m -cp JLI_WildcardExpandClasspath(foo:foo/"*") ...
  1520 PrintJavaVersion(JNIEnv *env, jboolean extraLF)
  1408 PrintJavaVersion(JNIEnv *env, jboolean extraLF)
  1521 {
  1409 {
  1522     jclass ver;
  1410     jclass ver;
  1523     jmethodID print;
  1411     jmethodID print;
  1524 
  1412 
  1525     NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version"));
  1413     NULL_CHECK(ver = FindBootStrapClass(env, "sun/misc/Version"));
  1526     NULL_CHECK(print = (*env)->GetStaticMethodID(env,
  1414     NULL_CHECK(print = (*env)->GetStaticMethodID(env,
  1527                                                  ver,
  1415                                                  ver,
  1528                                                  (extraLF == JNI_TRUE) ? "println" : "print",
  1416                                                  (extraLF == JNI_TRUE) ? "println" : "print",
  1529                                                  "()V"
  1417                                                  "()V"
  1530                                                  )
  1418                                                  )
  1532 
  1420 
  1533     (*env)->CallStaticVoidMethod(env, ver, print);
  1421     (*env)->CallStaticVoidMethod(env, ver, print);
  1534 }
  1422 }
  1535 
  1423 
  1536 /*
  1424 /*
  1537  * Prints default usage or the Xusage message, see sun.launcher.LauncherHelp.java
  1425  * Prints default usage or the Xusage message, see sun.launcher.LauncherHelper.java
  1538  */
  1426  */
  1539 static void
  1427 static void
  1540 PrintUsage(JNIEnv* env, jboolean doXUsage)
  1428 PrintUsage(JNIEnv* env, jboolean doXUsage)
  1541 {
  1429 {
  1542   jclass cls;
  1430   jclass cls;
  1543   jmethodID initHelp, vmSelect, vmSynonym, vmErgo, printHelp, printXUsageMessage;
  1431   jmethodID initHelp, vmSelect, vmSynonym, vmErgo, printHelp, printXUsageMessage;
  1544   jstring jprogname, vm1, vm2;
  1432   jstring jprogname, vm1, vm2;
  1545   int i;
  1433   int i;
  1546 
  1434 
  1547   NULL_CHECK(cls = (*env)->FindClass(env, "sun/launcher/LauncherHelp"));
  1435   NULL_CHECK(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper"));
  1548 
  1436 
  1549 
  1437 
  1550   if (doXUsage) {
  1438   if (doXUsage) {
  1551     NULL_CHECK(printXUsageMessage = (*env)->GetStaticMethodID(env, cls,
  1439     NULL_CHECK(printXUsageMessage = (*env)->GetStaticMethodID(env, cls,
  1552                                         "printXUsageMessage", "(Z)V"));
  1440                                         "printXUsageMessage", "(Z)V"));