< prev index next >

jdk/src/java.base/share/native/libjli/java.c

Print this page




  82 
  83 /*
  84  * Entries for splash screen environment variables.
  85  * putenv is performed in SelectVersion. We need
  86  * them in memory until UnsetEnv, so they are made static
  87  * global instead of auto local.
  88  */
  89 static char* splash_file_entry = NULL;
  90 static char* splash_jar_entry = NULL;
  91 
  92 /*
  93  * List of VM options to be specified when the VM is created.
  94  */
  95 static JavaVMOption *options;
  96 static int numOptions, maxOptions;
  97 
  98 /*
  99  * Prototypes for functions internal to launcher.
 100  */
 101 static void SetClassPath(const char *s);
 102 static void SetModulePath(const char *s);
 103 static void SetUpgradeModulePath(const char *s);
 104 static void SetMainModule(const char *s);
 105 static void SetAddModulesProp(const char *mods);
 106 static void SetLimitModulesProp(const char *mods);
 107 static void SetAddReadsProp(const jint n, const char *s);
 108 static void SetAddExportsProp(const jint n, const char *s);
 109 static void SetPatchProp(const jint n, const char *s);
 110 static void SelectVersion(int argc, char **argv, char **main_class);
 111 static void SetJvmEnvironment(int argc, char **argv);
 112 static jboolean IsWhiteSpaceOptionArgument(const char* name);
 113 static jboolean ParseArguments(int *pargc, char ***pargv,
 114                                int *pmode, char **pwhat,
 115                                int *pret, const char *jrepath);
 116 static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv,
 117                               InvocationFunctions *ifn);
 118 static jstring NewPlatformString(JNIEnv *env, char *s);
 119 static jclass LoadMainClass(JNIEnv *env, int mode, char *name);
 120 static jclass GetApplicationClass(JNIEnv *env);
 121 
 122 static void TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv);
 123 static jboolean AddApplicationOptions(int cpathc, const char **cpathv);
 124 static void SetApplicationClassPath(const char**);
 125 
 126 static void PrintJavaVersion(JNIEnv *env, jboolean extraLF);
 127 static void PrintUsage(JNIEnv* env, jboolean doXUsage);
 128 static void ShowSettings(JNIEnv* env, char *optString);
 129 static void ListModules(JNIEnv* env, char *optString);
 130 
 131 static void SetPaths(int argc, char **argv);
 132 
 133 static void DumpState();
 134 static jboolean RemovableOption(char *option);
 135 












 136 /* Maximum supported entries from jvm.cfg. */
 137 #define INIT_MAX_KNOWN_VMS      10
 138 
 139 /* Values for vmdesc.flag */
 140 enum vmdesc_flag {
 141     VM_UNKNOWN = -1,
 142     VM_KNOWN,
 143     VM_ALIASED_TO,
 144     VM_WARN,
 145     VM_ERROR,
 146     VM_IF_SERVER_CLASS,
 147     VM_IGNORE
 148 };
 149 
 150 struct vmdesc {
 151     char *name;
 152     int flag;
 153     char *alias;
 154     char *server_class;
 155 };
 156 static struct vmdesc *knownVMs = NULL;
 157 static int knownVMsCount = 0;
 158 static int knownVMsLimit = 0;
 159 
 160 static void GrowKnownVMs(int minimum);
 161 static int  KnownVMIndex(const char* name);
 162 static void FreeKnownVMs();
 163 static jboolean IsWildCardEnabled();
 164 













 165 #define ARG_CHECK(AC_arg_count, AC_failure_message, AC_questionable_arg) \
 166     do { \
 167         if (AC_arg_count < 1) { \
 168             JLI_ReportErrorMessage(AC_failure_message, AC_questionable_arg); \
 169             printUsage = JNI_TRUE; \
 170             *pret = 1; \
 171             return JNI_TRUE; \
 172         } \
 173     } while (JNI_FALSE)
 174 
 175 /*
 176  * Running Java code in primordial thread caused many problems. We will
 177  * create a new thread to invoke JVM. See 6316197 for more information.
 178  */
 179 static jlong threadStackSize    = 0;  /* stack size of the new thread */
 180 static jlong maxHeapSize        = 0;  /* max heap size */
 181 static jlong initialHeapSize    = 0;  /* inital heap size */
 182 
 183 /*
 184  * A minimum -Xss stack size suitable for all platforms.


 494      * is not required. The main method is invoked here so that extraneous java
 495      * stacks are not in the application stack trace.
 496      */
 497     mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
 498                                        "([Ljava/lang/String;)V");
 499     CHECK_EXCEPTION_NULL_LEAVE(mainID);
 500 
 501     /* Invoke main method. */
 502     (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
 503 
 504     /*
 505      * The launcher's exit code (in the absence of calls to
 506      * System.exit) will be non-zero if main threw an exception.
 507      */
 508     ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
 509 
 510     LEAVE();
 511 }
 512 
 513 /*
 514  * Test if the given option name has a whitespace separated argument.
 515  */
 516 jboolean
 517 IsWhiteSpaceOptionArgument(const char* name) {
 518     return JLI_StrCmp(name, "-classpath") == 0 ||
 519            JLI_StrCmp(name, "-cp") == 0 ||
 520            JLI_StrCmp(name, "-modulepath") == 0 ||




























 521            JLI_StrCmp(name, "-mp") == 0 ||
 522            JLI_StrCmp(name, "-upgrademodulepath") == 0 ||
 523            JLI_StrCmp(name, "-addmods") == 0 ||
 524            JLI_StrCmp(name, "-limitmods") == 0;
 525 }




























 526 
 527 /*
 528  * Checks the command line options to find which JVM type was
 529  * specified.  If no command line option was given for the JVM type,
 530  * the default type is used.  The environment variable
 531  * JDK_ALTERNATE_VM and the command line option -XXaltjvm= are also
 532  * checked as ways of specifying which JVM type to invoke.
 533  */
 534 char *
 535 CheckJvmType(int *pargc, char ***argv, jboolean speculative) {
 536     int i, argi;
 537     int argc;
 538     char **newArgv;
 539     int newArgvIdx = 0;
 540     int isVMType;
 541     int jvmidx = -1;
 542     char *jvmtype = getenv("JDK_ALTERNATE_VM");
 543 
 544     argc = *pargc;
 545 
 546     /* To make things simpler we always copy the argv array */
 547     newArgv = JLI_MemAlloc((argc + 1) * sizeof(char *));
 548 
 549     /* The program name is always present */
 550     newArgv[newArgvIdx++] = (*argv)[0];
 551 
 552     for (argi = 1; argi < argc; argi++) {
 553         char *arg = (*argv)[argi];
 554         isVMType = 0;
 555 
 556         if (IsJavaArgs()) {
 557             if (arg[0] != '-') {
 558                 newArgv[newArgvIdx++] = arg;
 559                 continue;
 560             }
 561         } else {
 562             if (IsWhiteSpaceOptionArgument(arg)) {
 563                 newArgv[newArgvIdx++] = arg;
 564                 argi++;
 565                 if (argi < argc) {
 566                     newArgv[newArgvIdx++] = (*argv)[argi];
 567                 }
 568                 continue;
 569             }
 570             if (arg[0] != '-') break;
 571         }
 572 
 573         /* Did the user pass an explicit VM type? */
 574         i = KnownVMIndex(arg);
 575         if (i >= 0) {
 576             jvmtype = knownVMs[jvmidx = i].name + 1; /* skip the - */
 577             isVMType = 1;
 578             *pargc = *pargc - 1;
 579         }
 580 
 581         /* Did the user specify an "alternate" VM? */
 582         else if (JLI_StrCCmp(arg, "-XXaltjvm=") == 0 || JLI_StrCCmp(arg, "-J-XXaltjvm=") == 0) {


 684  *   leaving the arg list intact.  The first use is for the JVM flag
 685  *   -XX:NativeMemoryTracking=value.
 686  */
 687 static void
 688 SetJvmEnvironment(int argc, char **argv) {
 689 
 690     static const char*  NMT_Env_Name    = "NMT_LEVEL_";
 691     int i;
 692     for (i = 0; i < argc; i++) {
 693         char *arg = argv[i];
 694         /*
 695          * Since this must be a VM flag we stop processing once we see
 696          * an argument the launcher would not have processed beyond (such
 697          * as -version or -h), or an argument that indicates the following
 698          * arguments are for the application (i.e. the main class name, or
 699          * the -jar argument).
 700          */
 701         if (i > 0) {
 702             char *prev = argv[i - 1];
 703             // skip non-dash arg preceded by class path specifiers
 704             if (*arg != '-' && IsWhiteSpaceOptionArgument(prev)) {
 705                 continue;
 706             }
 707 
 708             if (*arg != '-'
 709                     || JLI_StrCmp(arg, "-version") == 0
 710                     || JLI_StrCmp(arg, "-fullversion") == 0
 711                     || JLI_StrCmp(arg, "-help") == 0

 712                     || JLI_StrCmp(arg, "-?") == 0
 713                     || JLI_StrCmp(arg, "-jar") == 0
 714                     || JLI_StrCmp(arg, "-X") == 0) {
 715                 return;
 716             }
 717         }
 718         /*
 719          * The following case checks for "-XX:NativeMemoryTracking=value".
 720          * If value is non null, an environmental variable set to this value
 721          * will be created to be used by the JVM.
 722          * The argument is passed to the JVM, which will check validity.
 723          * The JVM is responsible for removing the env variable.
 724          */
 725         if (JLI_StrCCmp(arg, "-XX:NativeMemoryTracking=") == 0) {
 726             int retval;
 727             // get what follows this parameter, include "="
 728             size_t pnlen = JLI_StrLen("-XX:NativeMemoryTracking=");
 729             if (JLI_StrLen(arg) > pnlen) {
 730                 char* value = arg + pnlen;
 731                 size_t pbuflen = pnlen + JLI_StrLen(value) + 10; // 10 max pid digits


 865      * we might just get one, in which case we simply ignore it, and let the
 866      * caller deal with it
 867      */
 868     if (s == NULL)
 869         return;
 870     s = JLI_WildcardExpandClasspath(s);
 871     if (sizeof(format) - 2 + JLI_StrLen(s) < JLI_StrLen(s))
 872         // s is became corrupted after expanding wildcards
 873         return;
 874     def = JLI_MemAlloc(sizeof(format)
 875                        - 2 /* strlen("%s") */
 876                        + JLI_StrLen(s));
 877     sprintf(def, format, s);
 878     AddOption(def, NULL);
 879     if (s != orig)
 880         JLI_MemFree((char *) s);
 881     _have_classpath = JNI_TRUE;
 882 }
 883 
 884 static void
 885 SetModulePath(const char *s)
 886 {

 887     char *def;
 888     const char *orig = s;
 889     static const char format[] = "-Djdk.module.path=%s";
 890     if (s == NULL)
 891         return;
 892     s = JLI_WildcardExpandClasspath(s);
 893     def = JLI_MemAlloc(sizeof(format)
 894                        - 2 /* strlen("%s") */
 895                        + JLI_StrLen(s));
 896     sprintf(def, format, s);
 897     AddOption(def, NULL);
 898     if (s != orig)
 899         JLI_MemFree((char *) s);
 900 }
 901 
 902 static void
 903 SetUpgradeModulePath(const char *s)
 904 {
 905     char *def;
 906     const char *orig = s;
 907     static const char format[] = "-Djdk.upgrade.module.path=%s";
 908     if (s == NULL)
 909         return;
 910     s = JLI_WildcardExpandClasspath(s);
 911     def = JLI_MemAlloc(sizeof(format)
 912                        - 2 /* strlen("%s") */
 913                        + JLI_StrLen(s));
 914     sprintf(def, format, s);
 915     AddOption(def, NULL);
 916     if (s != orig)
 917         JLI_MemFree((char *) s);
 918 }
 919 
 920 static void
 921 SetMainModule(const char *s)
 922 {
 923     static const char format[] = "-Djdk.module.main=%s";
 924     char* slash = JLI_StrChr(s, '/');
 925     size_t s_len, def_len;
 926     char *def;
 927 
 928     /* value may be <module> or <module>/<mainclass> */
 929     if (slash == NULL) {
 930         s_len = JLI_StrLen(s);
 931     } else {
 932         s_len = (size_t) (slash - s);
 933     }
 934     def_len = sizeof(format)
 935                - 2 /* strlen("%s") */
 936                + s_len;
 937     def = JLI_MemAlloc(def_len);
 938     JLI_Snprintf(def, def_len, format, s);
 939     AddOption(def, NULL);
 940 }
 941 
 942 static void
 943 SetAddModulesProp(const char *mods) {
 944     size_t buflen = JLI_StrLen(mods) + 40;
 945     char *prop = (char *)JLI_MemAlloc(buflen);
 946     JLI_Snprintf(prop, buflen, "-Djdk.launcher.addmods=%s", mods);
 947     AddOption(prop, NULL);
 948 }
 949 
 950 static void
 951 SetLimitModulesProp(const char *mods) {
 952     size_t buflen = JLI_StrLen(mods) + 40;
 953     char *prop = (char *)JLI_MemAlloc(buflen);
 954     JLI_Snprintf(prop, buflen, "-Djdk.launcher.limitmods=%s", mods);
 955     AddOption(prop, NULL);
 956 }
 957 
 958 static void
 959 SetAddReadsProp(const jint n, const char *s) {
 960     size_t buflen = JLI_StrLen(s) + 40;
 961     char *prop = (char *)JLI_MemAlloc(buflen);
 962     JLI_Snprintf(prop, buflen, "-Djdk.launcher.addreads.%d=%s", n, s);
 963     AddOption(prop, NULL);
 964 }
 965 
 966 static void
 967 SetAddExportsProp(const jint n, const char *s) {
 968     size_t buflen = JLI_StrLen(s) + 40;
 969     char *prop = (char *)JLI_MemAlloc(buflen);
 970     JLI_Snprintf(prop, buflen, "-Djdk.launcher.addexports.%d=%s", n, s);
 971     AddOption(prop, NULL);
 972 }
 973 
 974 static void
 975 SetPatchProp(const jint n, const char *s) {
 976     size_t buflen = JLI_StrLen(s) + 40;
 977     char *prop = (char *)JLI_MemAlloc(buflen);
 978     JLI_Snprintf(prop, buflen, "-Djdk.launcher.patch.%d=%s", n, s);
 979     AddOption(prop, NULL);
 980 }
 981 
 982 /*
 983  * The SelectVersion() routine ensures that an appropriate version of
 984  * the JRE is running.  The specification for the appropriate version
 985  * is obtained from either the manifest of a jar file (preferred) or
 986  * from command line options.
 987  * The routine also parses splash screen command line options and
 988  * passes on their values in private environment variables.
 989  */
 990 static void
 991 SelectVersion(int argc, char **argv, char **main_class)
 992 {
 993     char    *arg;
 994     char    *operand;
 995     char    *version = NULL;
 996     char    *jre = NULL;
 997     int     jarflag = 0;
 998     int     headlessflag = 0;
 999     int     restrict_search = -1;               /* -1 implies not known */
1000     manifest_info info;
1001     char    env_entry[MAXNAMELEN + 24] = ENV_ENTRY "=";
1002     char    *splash_file_name = NULL;
1003     char    *splash_jar_name = NULL;
1004     char    *env_in;
1005     int     res;

1006 
1007     /*
1008      * If the version has already been selected, set *main_class
1009      * with the value passed through the environment (if any) and
1010      * simply return.
1011      */
1012 
1013     /*
1014      * This environmental variable can be set by mJRE capable JREs
1015      * [ 1.5 thru 1.8 ].  All other aspects of mJRE processing have been
1016      * stripped by those JREs.  This environmental variable allows 1.9+
1017      * JREs to be started by these mJRE capable JREs.
1018      * Note that mJRE directives in the jar manifest file would have been
1019      * ignored for a JRE started by another JRE...
1020      * .. skipped for JRE 1.5 and beyond.
1021      * .. not even checked for pre 1.5.
1022      */
1023     if ((env_in = getenv(ENV_ENTRY)) != NULL) {
1024         if (*env_in != '\0')
1025             *main_class = JLI_StringDup(env_in);
1026         return;
1027     }
1028 
1029     /*
1030      * Scan through the arguments for options relevant to multiple JRE
1031      * support.  Multiple JRE support existed in JRE versions 1.5 thru 1.8.
1032      *
1033      * This capability is no longer available with JRE versions 1.9 and later.
1034      * These command line options are reported as errors.
1035      */

1036     argc--;
1037     argv++;
1038     while ((arg = *argv) != 0 && *arg == '-') {

1039         if (JLI_StrCCmp(arg, "-version:") == 0) {
1040             JLI_ReportErrorMessage(SPC_ERROR1);
1041         } else if (JLI_StrCmp(arg, "-jre-restrict-search") == 0) {
1042             JLI_ReportErrorMessage(SPC_ERROR2);
1043         } else if (JLI_StrCmp(arg, "-jre-no-restrict-search") == 0) {
1044             JLI_ReportErrorMessage(SPC_ERROR2);
1045         } else {
1046             if (JLI_StrCmp(arg, "-jar") == 0)
1047                 jarflag = 1;
1048             if (IsWhiteSpaceOptionArgument(arg) && (argc >= 2)) {

1049                 argc--;
1050                 argv++;
1051                 arg = *argv;
1052             }

1053 
1054             /*
1055              * Checking for headless toolkit option in the some way as AWT does:
1056              * "true" means true and any other value means false
1057              */
1058             if (JLI_StrCmp(arg, "-Djava.awt.headless=true") == 0) {
1059                 headlessflag = 1;
1060             } else if (JLI_StrCCmp(arg, "-Djava.awt.headless=") == 0) {
1061                 headlessflag = 0;
1062             } else if (JLI_StrCCmp(arg, "-splash:") == 0) {
1063                 splash_file_name = arg+8;
1064             }
1065         }
1066         argc--;
1067         argv++;
1068     }
1069     if (argc <= 0) {    /* No operand? Possibly legit with -[full]version */
1070         operand = NULL;
1071     } else {
1072         argc--;


1123         JLI_StrCat(splash_jar_entry, splash_jar_name);
1124         putenv(splash_jar_entry);
1125     }
1126 
1127 
1128     /*
1129      * "Valid" returns (other than unrecoverable errors) follow.  Set
1130      * main_class as a side-effect of this routine.
1131      */
1132     if (info.main_class != NULL)
1133         *main_class = JLI_StringDup(info.main_class);
1134 
1135     if (info.jre_version == NULL) {
1136         JLI_FreeManifest();
1137         return;
1138     }
1139 
1140 }
1141 
1142 /*









































































































1143  * Parses command line arguments.  Returns JNI_FALSE if launcher
1144  * should exit without starting vm, returns JNI_TRUE if vm needs
1145  * to be started to process given options.  *pret (the launcher
1146  * process return value) is set to 0 for a normal exit.
1147  */
1148 static jboolean
1149 ParseArguments(int *pargc, char ***pargv,
1150                int *pmode, char **pwhat,
1151                int *pret, const char *jrepath)
1152 {
1153     int argc = *pargc;
1154     char **argv = *pargv;
1155     int mode = LM_UNKNOWN;
1156     char *arg;
1157 
1158     *pret = 0;
1159 
1160     while ((arg = *argv) != 0 && *arg == '-') {
1161         argv++; --argc;
1162         if (JLI_StrCmp(arg, "-classpath") == 0 || JLI_StrCmp(arg, "-cp") == 0) {
1163             ARG_CHECK (argc, ARG_ERROR1, arg);
1164             SetClassPath(*argv);
1165             mode = LM_CLASS;
1166             argv++; --argc;
1167         } else if (JLI_StrCmp(arg, "-modulepath") == 0 || JLI_StrCmp(arg, "-mp") == 0) {
1168             ARG_CHECK (argc, ARG_ERROR4, arg);
1169             SetModulePath(*argv);
1170             argv++; --argc;
1171         } else if (JLI_StrCmp(arg, "-upgrademodulepath") == 0) {
1172             ARG_CHECK (argc, ARG_ERROR4, arg);
1173             SetUpgradeModulePath(*argv);
1174             argv++; --argc;
1175         } else if (JLI_StrCmp(arg, "-jar") == 0) {
1176             ARG_CHECK (argc, ARG_ERROR2, arg);
1177             mode = LM_JAR;
1178         } else if (JLI_StrCmp(arg, "-m") == 0) {
1179             ARG_CHECK (argc, ARG_ERROR5, arg);
1180             SetMainModule(*argv);


1181             mode = LM_MODULE;
1182         } else if (JLI_StrCmp(arg, "-addmods") == 0) {
1183             ARG_CHECK (argc, ARG_ERROR6, arg);
1184             SetAddModulesProp(*argv);
1185             argv++; --argc;
1186         } else if (JLI_StrCmp(arg, "-limitmods") == 0) {
1187             ARG_CHECK (argc, ARG_ERROR6, arg);
1188             SetLimitModulesProp(*argv);
1189             argv++; --argc;
1190         } else if (JLI_StrCmp(arg, "-listmods") == 0 ||
1191                    JLI_StrCCmp(arg, "-listmods:") == 0) {



1192             listModules = arg;








1193             return JNI_TRUE;
1194         } else if (JLI_StrCCmp(arg, "-XaddReads:") == 0) {
1195             static jint n;
1196             char *value = arg + 11;
1197             SetAddReadsProp(n++, value);
1198         } else if (JLI_StrCCmp(arg, "-XaddExports:") == 0) {
1199             static jint n;
1200             char *value = arg + 13;
1201             SetAddExportsProp(n++, value);
1202         } else if (JLI_StrCCmp(arg, "-Xpatch:") == 0) {
1203             static jint n;
1204             char *value = arg + 8;
1205             SetPatchProp(n++, value);
1206         } else if (JLI_StrCmp(arg, "-help") == 0 ||


























1207                    JLI_StrCmp(arg, "-h") == 0 ||
1208                    JLI_StrCmp(arg, "-?") == 0) {
1209             printUsage = JNI_TRUE;
1210             return JNI_TRUE;
1211         } else if (JLI_StrCmp(arg, "-version") == 0) {
1212             printVersion = JNI_TRUE;
1213             return JNI_TRUE;
1214         } else if (JLI_StrCmp(arg, "-showversion") == 0) {
1215             showVersion = JNI_TRUE;
1216         } else if (JLI_StrCmp(arg, "--dry-run") == 0) {
1217             dryRun = JNI_TRUE;
1218         } else if (JLI_StrCmp(arg, "-X") == 0) {
1219             printXUsage = JNI_TRUE;
1220             return JNI_TRUE;
1221 /*
1222  * The following case checks for -XshowSettings OR -XshowSetting:SUBOPT.
1223  * In the latter case, any SUBOPT value not recognized will default to "all"
1224  */
1225         } else if (JLI_StrCmp(arg, "-XshowSettings") == 0 ||
1226                    JLI_StrCCmp(arg, "-XshowSettings:") == 0) {


1265         } else if (JLI_StrCmp(arg, "-checksource") == 0 ||
1266                    JLI_StrCmp(arg, "-cs") == 0 ||
1267                    JLI_StrCmp(arg, "-noasyncgc") == 0) {
1268             /* No longer supported */
1269             JLI_ReportErrorMessage(ARG_WARN, arg);
1270         } else if (JLI_StrCCmp(arg, "-splash:") == 0) {
1271             ; /* Ignore machine independent options already handled */
1272         } else if (ProcessPlatformOption(arg)) {
1273             ; /* Processing of platform dependent options */
1274         } else if (RemovableOption(arg)) {
1275             ; /* Do not pass option to vm. */
1276         } else {
1277             /* java.class.path set on the command line */
1278             if (JLI_StrCCmp(arg, "-Djava.class.path=") == 0) {
1279                 _have_classpath = JNI_TRUE;
1280             }
1281             AddOption(arg, NULL);
1282         }
1283     }
1284 
1285     if (--argc >= 0) {
1286         *pwhat = *argv++;
1287     }
1288 
1289     if (*pwhat == NULL) {
1290         *pret = 1;
1291     } else if (mode == LM_UNKNOWN) {
1292         /* default to LM_CLASS if -m, -jar and -cp options are
1293          * not specified */
1294         if (!_have_classpath) {
1295             SetClassPath(".");
1296         }
1297         mode = LM_CLASS;
1298     }
1299 
1300     if (argc >= 0) {
1301         *pargc = argc;
1302         *pargv = argv;
1303     }
1304 
1305     *pmode = mode;


1675     NULL_CHECK(cls);
1676     NULL_CHECK(showSettingsID = (*env)->GetStaticMethodID(env, cls,
1677             "showSettings", "(ZLjava/lang/String;JJJZ)V"));
1678     NULL_CHECK(joptString = (*env)->NewStringUTF(env, optString));
1679     (*env)->CallStaticVoidMethod(env, cls, showSettingsID,
1680                                  USE_STDERR,
1681                                  joptString,
1682                                  (jlong)initialHeapSize,
1683                                  (jlong)maxHeapSize,
1684                                  (jlong)threadStackSize,
1685                                  ServerClassMachine());
1686 }
1687 
1688 /**
1689  * List modules supported by the runtime
1690  */
1691 static void
1692 ListModules(JNIEnv *env, char *optString)
1693 {
1694     jmethodID listModulesID;
1695     jstring joptString;
1696     jclass cls = GetLauncherHelperClass(env);
1697     NULL_CHECK(cls);
1698     NULL_CHECK(listModulesID = (*env)->GetStaticMethodID(env, cls,
1699             "listModules", "(ZLjava/lang/String;)V"));
1700     NULL_CHECK(joptString = (*env)->NewStringUTF(env, optString));
1701     (*env)->CallStaticVoidMethod(env, cls, listModulesID,
1702                                  USE_STDERR,
1703                                  joptString);
1704 }
1705 
1706 /*
1707  * Prints default usage or the Xusage message, see sun.launcher.LauncherHelper.java
1708  */
1709 static void
1710 PrintUsage(JNIEnv* env, jboolean doXUsage)
1711 {
1712   jmethodID initHelp, vmSelect, vmSynonym, vmErgo, printHelp, printXUsageMessage;
1713   jstring jprogname, vm1, vm2;
1714   int i;
1715   jclass cls = GetLauncherHelperClass(env);




  82 
  83 /*
  84  * Entries for splash screen environment variables.
  85  * putenv is performed in SelectVersion. We need
  86  * them in memory until UnsetEnv, so they are made static
  87  * global instead of auto local.
  88  */
  89 static char* splash_file_entry = NULL;
  90 static char* splash_jar_entry = NULL;
  91 
  92 /*
  93  * List of VM options to be specified when the VM is created.
  94  */
  95 static JavaVMOption *options;
  96 static int numOptions, maxOptions;
  97 
  98 /*
  99  * Prototypes for functions internal to launcher.
 100  */
 101 static void SetClassPath(const char *s);


 102 static void SetMainModule(const char *s);





 103 static void SelectVersion(int argc, char **argv, char **main_class);
 104 static void SetJvmEnvironment(int argc, char **argv);

 105 static jboolean ParseArguments(int *pargc, char ***pargv,
 106                                int *pmode, char **pwhat,
 107                                int *pret, const char *jrepath);
 108 static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv,
 109                               InvocationFunctions *ifn);
 110 static jstring NewPlatformString(JNIEnv *env, char *s);
 111 static jclass LoadMainClass(JNIEnv *env, int mode, char *name);
 112 static jclass GetApplicationClass(JNIEnv *env);
 113 
 114 static void TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv);
 115 static jboolean AddApplicationOptions(int cpathc, const char **cpathv);
 116 static void SetApplicationClassPath(const char**);
 117 
 118 static void PrintJavaVersion(JNIEnv *env, jboolean extraLF);
 119 static void PrintUsage(JNIEnv* env, jboolean doXUsage);
 120 static void ShowSettings(JNIEnv* env, char *optString);
 121 static void ListModules(JNIEnv* env, char *optString);
 122 
 123 static void SetPaths(int argc, char **argv);
 124 
 125 static void DumpState();
 126 static jboolean RemovableOption(char *option);
 127 
 128 enum OptionKind {
 129     LAUNCHER_OPTION = 0,
 130     LAUNCHER_OPTION_WITH_ARGUMENT,
 131     LAUNCHER_MAIN_OPTION,
 132     VM_LONG_OPTION,
 133     VM_LONG_OPTION_WITH_ARGUMENT,
 134     VM_OPTION
 135 };
 136 
 137 static int GetOpt(int *pargc, char ***pargv, char **poption, char **pvalue);
 138 static jboolean IsOptionWithArgument(int argc, char **argv);
 139 
 140 /* Maximum supported entries from jvm.cfg. */
 141 #define INIT_MAX_KNOWN_VMS      10
 142 
 143 /* Values for vmdesc.flag */
 144 enum vmdesc_flag {
 145     VM_UNKNOWN = -1,
 146     VM_KNOWN,
 147     VM_ALIASED_TO,
 148     VM_WARN,
 149     VM_ERROR,
 150     VM_IF_SERVER_CLASS,
 151     VM_IGNORE
 152 };
 153 
 154 struct vmdesc {
 155     char *name;
 156     int flag;
 157     char *alias;
 158     char *server_class;
 159 };
 160 static struct vmdesc *knownVMs = NULL;
 161 static int knownVMsCount = 0;
 162 static int knownVMsLimit = 0;
 163 
 164 static void GrowKnownVMs(int minimum);
 165 static int  KnownVMIndex(const char* name);
 166 static void FreeKnownVMs();
 167 static jboolean IsWildCardEnabled();
 168 
 169 /*
 170  * This reports error.  VM will not be created and no usage is printed.
 171  */
 172 #define REPORT_ERROR(AC_ok, AC_failure_message, AC_questionable_arg) \
 173     do { \
 174         if (!AC_ok) { \
 175             JLI_ReportErrorMessage(AC_failure_message, AC_questionable_arg); \
 176             printUsage = JNI_FALSE; \
 177             *pret = 1; \
 178             return JNI_FALSE; \
 179         } \
 180     } while (JNI_FALSE)
 181 
 182 #define ARG_CHECK(AC_arg_count, AC_failure_message, AC_questionable_arg) \
 183     do { \
 184         if (AC_arg_count < 1) { \
 185             JLI_ReportErrorMessage(AC_failure_message, AC_questionable_arg); \
 186             printUsage = JNI_TRUE; \
 187             *pret = 1; \
 188             return JNI_TRUE; \
 189         } \
 190     } while (JNI_FALSE)
 191 
 192 /*
 193  * Running Java code in primordial thread caused many problems. We will
 194  * create a new thread to invoke JVM. See 6316197 for more information.
 195  */
 196 static jlong threadStackSize    = 0;  /* stack size of the new thread */
 197 static jlong maxHeapSize        = 0;  /* max heap size */
 198 static jlong initialHeapSize    = 0;  /* inital heap size */
 199 
 200 /*
 201  * A minimum -Xss stack size suitable for all platforms.


 511      * is not required. The main method is invoked here so that extraneous java
 512      * stacks are not in the application stack trace.
 513      */
 514     mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
 515                                        "([Ljava/lang/String;)V");
 516     CHECK_EXCEPTION_NULL_LEAVE(mainID);
 517 
 518     /* Invoke main method. */
 519     (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
 520 
 521     /*
 522      * The launcher's exit code (in the absence of calls to
 523      * System.exit) will be non-zero if main threw an exception.
 524      */
 525     ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
 526 
 527     LEAVE();
 528 }
 529 
 530 /*
 531  * Test if the given name is one of the class path options.
 532  */
 533 static jboolean
 534 IsClassPathOption(const char* name) {
 535     return JLI_StrCmp(name, "-classpath") == 0 ||
 536            JLI_StrCmp(name, "-cp") == 0 ||
 537            JLI_StrCmp(name, "--class-path") == 0;
 538 }
 539 
 540 /*
 541  * Test if the given name is a launcher option taking the main entry point.
 542  */
 543 static jboolean
 544 IsLauncherMainOption(const char* name) {
 545     return JLI_StrCmp(name, "--module") == 0 ||
 546            JLI_StrCmp(name, "-m") == 0;
 547 }
 548 
 549 /*
 550  * Test if the given name is a white-space launcher option.
 551  */
 552 static jboolean
 553 IsLauncherOption(const char* name) {
 554     return IsClassPathOption(name) ||
 555            IsLauncherMainOption(name) ||
 556            JLI_StrCmp(name, "--list-modules") == 0;
 557 }
 558 
 559 #ifndef OLD_MODULE_OPTIONS
 560 /*
 561  * Old module options for transition
 562  */
 563 static jboolean
 564 IsOldModuleOption(const char* name) {
 565     return JLI_StrCmp(name, "-modulepath") == 0 ||
 566     JLI_StrCmp(name, "-mp") == 0 ||
 567     JLI_StrCmp(name, "-upgrademodulepath") == 0 ||
 568     JLI_StrCmp(name, "-addmods") == 0 ||
 569     JLI_StrCmp(name, "-limitmods") == 0;
 570 }
 571 #endif
 572 
 573 /*
 574  * Test if the given name is a module-system white-space option that
 575  * will be passed to the VM with its corresponding long-form option
 576  * name and "=" delimiter.
 577  */
 578 static jboolean
 579 IsModuleOption(const char* name) {
 580     return JLI_StrCmp(name, "--module-path") == 0 ||
 581            JLI_StrCmp(name, "-p") == 0 ||
 582            JLI_StrCmp(name, "--upgrade-module-path") == 0 ||
 583            JLI_StrCmp(name, "--add-modules") == 0 ||
 584            JLI_StrCmp(name, "--limit-modules") == 0 ||
 585            JLI_StrCmp(name, "--add-exports") == 0 ||
 586            JLI_StrCmp(name, "--add-reads") == 0 ||
 587            JLI_StrCmp(name, "--patch-module") == 0 ||
 588            IsOldModuleOption(name);
 589 }
 590 
 591 /*
 592  * Test if the given name has a white space option.
 593  */
 594 jboolean
 595 IsWhiteSpaceOption(const char* name) {
 596     return IsModuleOption(name) ||
 597            IsLauncherOption(name);
 598 }
 599 
 600 /*
 601  * Checks the command line options to find which JVM type was
 602  * specified.  If no command line option was given for the JVM type,
 603  * the default type is used.  The environment variable
 604  * JDK_ALTERNATE_VM and the command line option -XXaltjvm= are also
 605  * checked as ways of specifying which JVM type to invoke.
 606  */
 607 char *
 608 CheckJvmType(int *pargc, char ***argv, jboolean speculative) {
 609     int i, argi;
 610     int argc;
 611     char **newArgv;
 612     int newArgvIdx = 0;
 613     int isVMType;
 614     int jvmidx = -1;
 615     char *jvmtype = getenv("JDK_ALTERNATE_VM");
 616 
 617     argc = *pargc;
 618 
 619     /* To make things simpler we always copy the argv array */
 620     newArgv = JLI_MemAlloc((argc + 1) * sizeof(char *));
 621 
 622     /* The program name is always present */
 623     newArgv[newArgvIdx++] = (*argv)[0];
 624 
 625     for (argi = 1; argi < argc; argi++) {
 626         char *arg = (*argv)[argi];
 627         isVMType = 0;
 628 
 629         if (IsJavaArgs()) {
 630             if (arg[0] != '-') {
 631                 newArgv[newArgvIdx++] = arg;
 632                 continue;
 633             }
 634         } else {
 635             if (IsWhiteSpaceOption(arg)) {
 636                 newArgv[newArgvIdx++] = arg;
 637                 argi++;
 638                 if (argi < argc) {
 639                     newArgv[newArgvIdx++] = (*argv)[argi];
 640                 }
 641                 continue;
 642             }
 643             if (arg[0] != '-') break;
 644         }
 645 
 646         /* Did the user pass an explicit VM type? */
 647         i = KnownVMIndex(arg);
 648         if (i >= 0) {
 649             jvmtype = knownVMs[jvmidx = i].name + 1; /* skip the - */
 650             isVMType = 1;
 651             *pargc = *pargc - 1;
 652         }
 653 
 654         /* Did the user specify an "alternate" VM? */
 655         else if (JLI_StrCCmp(arg, "-XXaltjvm=") == 0 || JLI_StrCCmp(arg, "-J-XXaltjvm=") == 0) {


 757  *   leaving the arg list intact.  The first use is for the JVM flag
 758  *   -XX:NativeMemoryTracking=value.
 759  */
 760 static void
 761 SetJvmEnvironment(int argc, char **argv) {
 762 
 763     static const char*  NMT_Env_Name    = "NMT_LEVEL_";
 764     int i;
 765     for (i = 0; i < argc; i++) {
 766         char *arg = argv[i];
 767         /*
 768          * Since this must be a VM flag we stop processing once we see
 769          * an argument the launcher would not have processed beyond (such
 770          * as -version or -h), or an argument that indicates the following
 771          * arguments are for the application (i.e. the main class name, or
 772          * the -jar argument).
 773          */
 774         if (i > 0) {
 775             char *prev = argv[i - 1];
 776             // skip non-dash arg preceded by class path specifiers
 777             if (*arg != '-' && IsWhiteSpaceOption(prev)) {
 778                 continue;
 779             }
 780 
 781             if (*arg != '-'
 782                     || JLI_StrCmp(arg, "-version") == 0
 783                     || JLI_StrCmp(arg, "-fullversion") == 0
 784                     || JLI_StrCmp(arg, "-help") == 0
 785                     || JLI_StrCmp(arg, "--help") == 0
 786                     || JLI_StrCmp(arg, "-?") == 0
 787                     || JLI_StrCmp(arg, "-jar") == 0
 788                     || JLI_StrCmp(arg, "-X") == 0) {
 789                 return;
 790             }
 791         }
 792         /*
 793          * The following case checks for "-XX:NativeMemoryTracking=value".
 794          * If value is non null, an environmental variable set to this value
 795          * will be created to be used by the JVM.
 796          * The argument is passed to the JVM, which will check validity.
 797          * The JVM is responsible for removing the env variable.
 798          */
 799         if (JLI_StrCCmp(arg, "-XX:NativeMemoryTracking=") == 0) {
 800             int retval;
 801             // get what follows this parameter, include "="
 802             size_t pnlen = JLI_StrLen("-XX:NativeMemoryTracking=");
 803             if (JLI_StrLen(arg) > pnlen) {
 804                 char* value = arg + pnlen;
 805                 size_t pbuflen = pnlen + JLI_StrLen(value) + 10; // 10 max pid digits


 939      * we might just get one, in which case we simply ignore it, and let the
 940      * caller deal with it
 941      */
 942     if (s == NULL)
 943         return;
 944     s = JLI_WildcardExpandClasspath(s);
 945     if (sizeof(format) - 2 + JLI_StrLen(s) < JLI_StrLen(s))
 946         // s is became corrupted after expanding wildcards
 947         return;
 948     def = JLI_MemAlloc(sizeof(format)
 949                        - 2 /* strlen("%s") */
 950                        + JLI_StrLen(s));
 951     sprintf(def, format, s);
 952     AddOption(def, NULL);
 953     if (s != orig)
 954         JLI_MemFree((char *) s);
 955     _have_classpath = JNI_TRUE;
 956 }
 957 
 958 static void
 959 AddLongFormOption(const char *option, const char *arg)
 960 {
 961     static const char format[] = "%s=%s";
 962     char *def;
 963     size_t def_len;












 964 
 965     def_len = JLI_StrLen(option)+1+JLI_StrLen(arg)+1;
 966     def = JLI_MemAlloc(def_len);
 967     JLI_Snprintf(def, def_len, format, option, arg);










 968     AddOption(def, NULL);


 969 }
 970 
 971 static void
 972 SetMainModule(const char *s)
 973 {
 974     static const char format[] = "-Djdk.module.main=%s";
 975     char* slash = JLI_StrChr(s, '/');
 976     size_t s_len, def_len;
 977     char *def;
 978 
 979     /* value may be <module> or <module>/<mainclass> */
 980     if (slash == NULL) {
 981         s_len = JLI_StrLen(s);
 982     } else {
 983         s_len = (size_t) (slash - s);
 984     }
 985     def_len = sizeof(format)
 986                - 2 /* strlen("%s") */
 987                + s_len;
 988     def = JLI_MemAlloc(def_len);
 989     JLI_Snprintf(def, def_len, format, s);
 990     AddOption(def, NULL);
 991 }
 992 








































 993 /*
 994  * The SelectVersion() routine ensures that an appropriate version of
 995  * the JRE is running.  The specification for the appropriate version
 996  * is obtained from either the manifest of a jar file (preferred) or
 997  * from command line options.
 998  * The routine also parses splash screen command line options and
 999  * passes on their values in private environment variables.
1000  */
1001 static void
1002 SelectVersion(int argc, char **argv, char **main_class)
1003 {
1004     char    *arg;
1005     char    *operand;
1006     char    *version = NULL;
1007     char    *jre = NULL;
1008     int     jarflag = 0;
1009     int     headlessflag = 0;
1010     int     restrict_search = -1;               /* -1 implies not known */
1011     manifest_info info;
1012     char    env_entry[MAXNAMELEN + 24] = ENV_ENTRY "=";
1013     char    *splash_file_name = NULL;
1014     char    *splash_jar_name = NULL;
1015     char    *env_in;
1016     int     res;
1017     jboolean has_arg;
1018 
1019     /*
1020      * If the version has already been selected, set *main_class
1021      * with the value passed through the environment (if any) and
1022      * simply return.
1023      */
1024 
1025     /*
1026      * This environmental variable can be set by mJRE capable JREs
1027      * [ 1.5 thru 1.8 ].  All other aspects of mJRE processing have been
1028      * stripped by those JREs.  This environmental variable allows 1.9+
1029      * JREs to be started by these mJRE capable JREs.
1030      * Note that mJRE directives in the jar manifest file would have been
1031      * ignored for a JRE started by another JRE...
1032      * .. skipped for JRE 1.5 and beyond.
1033      * .. not even checked for pre 1.5.
1034      */
1035     if ((env_in = getenv(ENV_ENTRY)) != NULL) {
1036         if (*env_in != '\0')
1037             *main_class = JLI_StringDup(env_in);
1038         return;
1039     }
1040 
1041     /*
1042      * Scan through the arguments for options relevant to multiple JRE
1043      * support.  Multiple JRE support existed in JRE versions 1.5 thru 1.8.
1044      *
1045      * This capability is no longer available with JRE versions 1.9 and later.
1046      * These command line options are reported as errors.
1047      */
1048 
1049     argc--;
1050     argv++;
1051     while ((arg = *argv) != 0 && *arg == '-') {
1052         has_arg = IsOptionWithArgument(argc, argv);
1053         if (JLI_StrCCmp(arg, "-version:") == 0) {
1054             JLI_ReportErrorMessage(SPC_ERROR1);
1055         } else if (JLI_StrCmp(arg, "-jre-restrict-search") == 0) {
1056             JLI_ReportErrorMessage(SPC_ERROR2);
1057         } else if (JLI_StrCmp(arg, "-jre-no-restrict-search") == 0) {
1058             JLI_ReportErrorMessage(SPC_ERROR2);
1059         } else {
1060             if (JLI_StrCmp(arg, "-jar") == 0)
1061                 jarflag = 1;
1062             if (IsWhiteSpaceOption(arg)) {
1063                 if (has_arg) {
1064                     argc--;
1065                     argv++;
1066                     arg = *argv;
1067                 }
1068             }
1069 
1070             /*
1071              * Checking for headless toolkit option in the some way as AWT does:
1072              * "true" means true and any other value means false
1073              */
1074             if (JLI_StrCmp(arg, "-Djava.awt.headless=true") == 0) {
1075                 headlessflag = 1;
1076             } else if (JLI_StrCCmp(arg, "-Djava.awt.headless=") == 0) {
1077                 headlessflag = 0;
1078             } else if (JLI_StrCCmp(arg, "-splash:") == 0) {
1079                 splash_file_name = arg+8;
1080             }
1081         }
1082         argc--;
1083         argv++;
1084     }
1085     if (argc <= 0) {    /* No operand? Possibly legit with -[full]version */
1086         operand = NULL;
1087     } else {
1088         argc--;


1139         JLI_StrCat(splash_jar_entry, splash_jar_name);
1140         putenv(splash_jar_entry);
1141     }
1142 
1143 
1144     /*
1145      * "Valid" returns (other than unrecoverable errors) follow.  Set
1146      * main_class as a side-effect of this routine.
1147      */
1148     if (info.main_class != NULL)
1149         *main_class = JLI_StringDup(info.main_class);
1150 
1151     if (info.jre_version == NULL) {
1152         JLI_FreeManifest();
1153         return;
1154     }
1155 
1156 }
1157 
1158 /*
1159  * Test if the current argv is an option, i.e. with a leading `-`
1160  * and followed with an argument without a leading `-`.
1161  */
1162 static jboolean
1163 IsOptionWithArgument(int argc, char** argv) {
1164     char* option;
1165     char* arg;
1166 
1167     if (argc <= 1)
1168         return JNI_FALSE;
1169 
1170     option = *argv;
1171     arg = *(argv+1);
1172     return *option == '-' && *arg != '-';
1173 }
1174 
1175 /*
1176  * Gets the option, and its argument if the option has an argument.
1177  * It will update *pargc, **pargv to the next option.
1178  */
1179 static int
1180 GetOpt(int *pargc, char ***pargv, char **poption, char **pvalue) {
1181     int argc = *pargc;
1182     char** argv = *pargv;
1183     char* arg = *argv;
1184 
1185     char* option = arg;
1186     char* value = NULL;
1187     char* equals = NULL;
1188     int kind = LAUNCHER_OPTION;
1189     jboolean has_arg = JNI_FALSE;
1190 
1191     // check if this option may be a white-space option with an argument
1192     has_arg = IsOptionWithArgument(argc, argv);
1193 
1194     argv++; --argc;
1195     if (IsLauncherOption(arg)) {
1196         if (has_arg) {
1197             value = *argv;
1198             argv++; --argc;
1199         }
1200         if (IsLauncherMainOption(arg)) {
1201             kind = LAUNCHER_MAIN_OPTION;
1202         } else {
1203             kind = LAUNCHER_OPTION_WITH_ARGUMENT;
1204         }
1205     } else if (IsModuleOption(arg)) {
1206         kind = VM_LONG_OPTION_WITH_ARGUMENT;
1207         if (has_arg) {
1208             value = *argv;
1209             argv++; --argc;
1210         }
1211 
1212         /*
1213          * Support short form alias
1214          */
1215         if (JLI_StrCmp(arg, "-p") == 0) {
1216             option = "--module-path";
1217         }
1218 
1219     } else if (JLI_StrCCmp(arg, "--") == 0 && (equals = JLI_StrChr(arg, '=')) != NULL) {
1220         value = equals+1;
1221         if (JLI_StrCCmp(arg, "--list-modules=") == 0 ||
1222             JLI_StrCCmp(arg, "--module=") == 0 ||
1223             JLI_StrCCmp(arg, "--class-path=") == 0) {
1224             kind = LAUNCHER_OPTION_WITH_ARGUMENT;
1225         } else {
1226             kind = VM_LONG_OPTION;
1227         }
1228     }
1229 
1230 #ifndef OLD_MODULE_OPTIONS
1231     // for transition to support both old and new syntax
1232     if (JLI_StrCmp(arg, "-modulepath") == 0 ||
1233         JLI_StrCmp(arg, "-mp") == 0) {
1234         option = "--module-path";
1235     } else if (JLI_StrCmp(arg, "-upgrademodulepath") == 0) {
1236         option = "--upgrade-module-path";
1237     } else if (JLI_StrCmp(arg, "-addmods") == 0) {
1238         option = "--add-modules";
1239     } else if (JLI_StrCmp(arg, "-limitmods") == 0) {
1240         option = "--limit-modules";
1241     } else if (JLI_StrCCmp(arg, "-XaddExports:") == 0) {
1242         option = "--add-exports";
1243         value = arg + 13;
1244         kind = VM_LONG_OPTION_WITH_ARGUMENT;
1245     } else if (JLI_StrCCmp(arg, "-XaddReads:") == 0) {
1246         option = "--add-reads";
1247         value = arg + 11;
1248         kind = VM_LONG_OPTION_WITH_ARGUMENT;
1249     } else if (JLI_StrCCmp(arg, "-Xpatch:") == 0) {
1250         option = "--patch-module";
1251         value = arg + 8;
1252         kind = VM_LONG_OPTION_WITH_ARGUMENT;
1253     }
1254 #endif
1255 
1256     *pargc = argc;
1257     *pargv = argv;
1258     *poption = option;
1259     *pvalue = value;
1260     return kind;
1261 }
1262 
1263 /*
1264  * Parses command line arguments.  Returns JNI_FALSE if launcher
1265  * should exit without starting vm, returns JNI_TRUE if vm needs
1266  * to be started to process given options.  *pret (the launcher
1267  * process return value) is set to 0 for a normal exit.
1268  */
1269 static jboolean
1270 ParseArguments(int *pargc, char ***pargv,
1271                int *pmode, char **pwhat,
1272                int *pret, const char *jrepath)
1273 {
1274     int argc = *pargc;
1275     char **argv = *pargv;
1276     int mode = LM_UNKNOWN;
1277     char *arg;
1278 
1279     *pret = 0;
1280 
1281     while ((arg = *argv) != 0 && *arg == '-') {
1282         char *option = NULL;
1283         char *value = NULL;
1284         int kind = GetOpt(&argc, &argv, &option, &value);
1285         jboolean has_arg = value != NULL;
1286 
1287 /*
1288  * Option to set main entry point
1289  */
1290         if (JLI_StrCmp(arg, "-jar") == 0) {
1291             ARG_CHECK(argc, ARG_ERROR2, arg);






1292             mode = LM_JAR;
1293         } else if (JLI_StrCmp(arg, "--module") == 0 ||
1294                    JLI_StrCCmp(arg, "--module=") == 0 ||
1295                    JLI_StrCmp(arg, "-m") == 0) {
1296             REPORT_ERROR (has_arg, ARG_ERROR5, arg);
1297             SetMainModule(value);
1298             mode = LM_MODULE;
1299             if (has_arg) {
1300                *pwhat = value;
1301                 break;
1302             }
1303         } else if (JLI_StrCmp(arg, "--class-path") == 0 ||
1304                    JLI_StrCCmp(arg, "--class-path=") == 0 ||
1305                    JLI_StrCmp(arg, "-classpath") == 0 ||
1306                    JLI_StrCmp(arg, "-cp") == 0) {
1307             REPORT_ERROR (has_arg, ARG_ERROR1, arg);
1308             SetClassPath(value);
1309             mode = LM_CLASS;
1310         } else if (JLI_StrCmp(arg, "--list-modules") == 0 ||
1311                    JLI_StrCCmp(arg, "--list-modules=") == 0) {
1312             listModules = arg;
1313 
1314             // set listModules to --list-modules=<module-names> if argument is specified
1315             if (JLI_StrCmp(arg, "--list-modules") == 0 && has_arg) {
1316                 static const char format[] = "%s=%s";
1317                 size_t buflen = JLI_StrLen(option)+2+JLI_StrLen(value);
1318                 listModules = JLI_MemAlloc(buflen);
1319                 JLI_Snprintf(listModules, buflen, format, option, value);
1320             }
1321             return JNI_TRUE;
1322 /*
1323  * Parse white-space options
1324  */
1325         } else if (has_arg) {
1326             if (kind == VM_LONG_OPTION) {
1327                 AddOption(option, NULL);
1328             } else if (kind == VM_LONG_OPTION_WITH_ARGUMENT) {
1329                 AddLongFormOption(option, value);
1330             }
1331 /*
1332  * Error missing argument
1333  */
1334         } else if (!has_arg && IsWhiteSpaceOption(arg)) {
1335             if (JLI_StrCmp(arg, "--module-path") == 0 ||
1336                 JLI_StrCmp(arg, "-p") == 0 ||
1337                 JLI_StrCmp(arg, "--upgrade-module-path") == 0) {
1338                 REPORT_ERROR (has_arg, ARG_ERROR4, arg);
1339             } else if (JLI_StrCmp(arg, "--add-modules") == 0 ||
1340                        JLI_StrCmp(arg, "--limit-modules") == 0 ||
1341                        JLI_StrCmp(arg, "--add-exports") == 0 ||
1342                        JLI_StrCmp(arg, "--add-reads") == 0 ||
1343                        JLI_StrCmp(arg, "--patch-module") == 0) {
1344                 REPORT_ERROR (has_arg, ARG_ERROR6, arg);
1345             }
1346 #ifndef OLD_MODULE_OPTIONS
1347             else if (JLI_StrCmp(arg, "-modulepath") == 0 ||
1348                      JLI_StrCmp(arg, "-mp") == 0 ||
1349                      JLI_StrCmp(arg, "-upgrademodulepath") == 0) {
1350                 REPORT_ERROR (has_arg, ARG_ERROR4, arg);
1351             } else if (JLI_StrCmp(arg, "-addmods") == 0 ||
1352                        JLI_StrCmp(arg, "-limitmods") == 0) {
1353                 REPORT_ERROR (has_arg, ARG_ERROR6, arg);
1354             }
1355 #endif
1356 /*
1357  * The following cases will cause the argument parsing to stop
1358  */
1359         } else if (JLI_StrCmp(arg, "--help") == 0 ||
1360                    JLI_StrCmp(arg, "-help") == 0 ||
1361                    JLI_StrCmp(arg, "-h") == 0 ||
1362                    JLI_StrCmp(arg, "-?") == 0) {
1363             printUsage = JNI_TRUE;
1364             return JNI_TRUE;
1365         } else if (JLI_StrCmp(arg, "-version") == 0) {
1366             printVersion = JNI_TRUE;
1367             return JNI_TRUE;
1368         } else if (JLI_StrCmp(arg, "-showversion") == 0) {
1369             showVersion = JNI_TRUE;
1370         } else if (JLI_StrCmp(arg, "--dry-run") == 0) {
1371             dryRun = JNI_TRUE;
1372         } else if (JLI_StrCmp(arg, "-X") == 0) {
1373             printXUsage = JNI_TRUE;
1374             return JNI_TRUE;
1375 /*
1376  * The following case checks for -XshowSettings OR -XshowSetting:SUBOPT.
1377  * In the latter case, any SUBOPT value not recognized will default to "all"
1378  */
1379         } else if (JLI_StrCmp(arg, "-XshowSettings") == 0 ||
1380                    JLI_StrCCmp(arg, "-XshowSettings:") == 0) {


1419         } else if (JLI_StrCmp(arg, "-checksource") == 0 ||
1420                    JLI_StrCmp(arg, "-cs") == 0 ||
1421                    JLI_StrCmp(arg, "-noasyncgc") == 0) {
1422             /* No longer supported */
1423             JLI_ReportErrorMessage(ARG_WARN, arg);
1424         } else if (JLI_StrCCmp(arg, "-splash:") == 0) {
1425             ; /* Ignore machine independent options already handled */
1426         } else if (ProcessPlatformOption(arg)) {
1427             ; /* Processing of platform dependent options */
1428         } else if (RemovableOption(arg)) {
1429             ; /* Do not pass option to vm. */
1430         } else {
1431             /* java.class.path set on the command line */
1432             if (JLI_StrCCmp(arg, "-Djava.class.path=") == 0) {
1433                 _have_classpath = JNI_TRUE;
1434             }
1435             AddOption(arg, NULL);
1436         }
1437     }
1438 
1439     if (*pwhat == NULL && --argc >= 0) {
1440         *pwhat = *argv++;
1441     }
1442 
1443     if (*pwhat == NULL) {
1444         *pret = 1;
1445     } else if (mode == LM_UNKNOWN) {
1446         /* default to LM_CLASS if -m, -jar and -cp options are
1447          * not specified */
1448         if (!_have_classpath) {
1449             SetClassPath(".");
1450         }
1451         mode = LM_CLASS;
1452     }
1453 
1454     if (argc >= 0) {
1455         *pargc = argc;
1456         *pargv = argv;
1457     }
1458 
1459     *pmode = mode;


1829     NULL_CHECK(cls);
1830     NULL_CHECK(showSettingsID = (*env)->GetStaticMethodID(env, cls,
1831             "showSettings", "(ZLjava/lang/String;JJJZ)V"));
1832     NULL_CHECK(joptString = (*env)->NewStringUTF(env, optString));
1833     (*env)->CallStaticVoidMethod(env, cls, showSettingsID,
1834                                  USE_STDERR,
1835                                  joptString,
1836                                  (jlong)initialHeapSize,
1837                                  (jlong)maxHeapSize,
1838                                  (jlong)threadStackSize,
1839                                  ServerClassMachine());
1840 }
1841 
1842 /**
1843  * List modules supported by the runtime
1844  */
1845 static void
1846 ListModules(JNIEnv *env, char *optString)
1847 {
1848     jmethodID listModulesID;
1849     jstring joptString = NULL;
1850     jclass cls = GetLauncherHelperClass(env);
1851     NULL_CHECK(cls);
1852     NULL_CHECK(listModulesID = (*env)->GetStaticMethodID(env, cls,
1853             "listModules", "(ZLjava/lang/String;)V"));
1854     NULL_CHECK(joptString = (*env)->NewStringUTF(env, optString));
1855     (*env)->CallStaticVoidMethod(env, cls, listModulesID,
1856                                  USE_STDERR,
1857                                  joptString);
1858 }
1859 
1860 /*
1861  * Prints default usage or the Xusage message, see sun.launcher.LauncherHelper.java
1862  */
1863 static void
1864 PrintUsage(JNIEnv* env, jboolean doXUsage)
1865 {
1866   jmethodID initHelp, vmSelect, vmSynonym, vmErgo, printHelp, printXUsageMessage;
1867   jstring jprogname, vm1, vm2;
1868   int i;
1869   jclass cls = GetLauncherHelperClass(env);


< prev index next >