java.c revision 4632
2976N/A * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. 2976N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2976N/A * This code is free software; you can redistribute it and/or modify it 2976N/A * under the terms of the GNU General Public License version 2 only, as 2976N/A * published by the Free Software Foundation. Oracle designates this 2976N/A * particular file as subject to the "Classpath" exception as provided 2976N/A * by Oracle in the LICENSE file that accompanied this code. 2976N/A * This code is distributed in the hope that it will be useful, but WITHOUT 2976N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2976N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2976N/A * version 2 for more details (a copy is included in the LICENSE file that 2976N/A * You should have received a copy of the GNU General Public License version 2976N/A * 2 along with this work; if not, write to the Free Software Foundation, 2976N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2976N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5728N/A * Shared source for 'java' command line tool. 2976N/A * If JAVA_ARGS is defined, then acts as a launcher for applications. For 2976N/A * instance, the JDK command line tools such as javac and javadoc (see 2976N/A * makefiles for more details) are built with this program. Any arguments 2976N/A * prefixed with '-J' will be passed directly to the 'java' command. 3824N/A * One job of the launcher is to remove command line options which the 6606N/A * vm does not understand and will not process. These options include 6606N/A * options which select which style of vm is run (e.g. -client and 6606N/A * -server) as well as options which select the data model to use. 6606N/A * Additionally, for tools which invoke an underlying vm "-J-foo" 3824N/A * options are turned into "-foo" options to the vm. This option 5728N/A * filtering is handled in a number of places in the launcher, some of 3842N/A * it in machine-dependent code. In this file, the function 3842N/A * CheckJvmType removes vm style options and TranslateApplicationArgs 3824N/A * removes "-J" prefixes. The CreateExecutionEnvironment function processes 3842N/A * and removes -d<n> options. On unix, there is a possibility that the running 2976N/A * data model may not match to the desired data model, in this case an exec is 5636N/A * required to start the desired model. If the data models match, then 2976N/A * ParseArguments will remove the -d<n> flags. If the data models do not match 2976N/A * the CreateExecutionEnviroment will remove the -d<n> flags. 3262N/A * A NOTE TO DEVELOPERS: For performance reasons it is important that 2976N/A * the program image remain relatively small until after SelectVersion 5173N/A * CreateExecutionEnvironment have finished their possibly recursive 2976N/A * processing. Watch everything, but resist all temptations to use Java 2976N/A/* we always print to stderr */ 5636N/A * Entries for splash screen environment variables. 5636N/A * putenv is performed in SelectVersion. We need 3262N/A * them in memory until UnsetEnv, so they are made static 2976N/A * global instead of auto local. 2976N/A * List of VM options to be specified when the VM is created. * Prototypes for functions internal to launcher. /* Maximum supported entries from jvm.cfg. */ /* Values for vmdesc.flag */ * Running Java code in primordial thread caused many problems. We will * create a new thread to invoke JVM. See 6316197 for more information. enum LaunchMode {
// cf. sun.launcher.LauncherHelper = {
"Unknown",
"Main class",
"JAR file" };
const char*
pname,
/* program name */ const char*
lname,
/* launcher name */ * Make sure the specified version of the JRE is running. * There are three things to note about the SelectVersion() routine: * 1) If the version running isn't correct, this routine doesn't * return (either the correct version has been exec'd or an error * 2) Argc and Argv in this scope are *not* altered by this routine. * It is the responsibility of subsequent code to ignore the * arguments handled by this routine. * 3) As a side-effect, the variable "main_class" is guaranteed to * be set (if it should ever be set). This isn't exactly the * poster child for structured programming, but it is a small * price to pay for not processing a jar file operand twice. * (Note: This side effect has been disabled. See comment on printf(
"Command line args:\n");
for (i = 0; i <
argc ; i++) {
/* Preprocess wrapper arguments */ /* Set default CLASSPATH */ /* Parse command line options; if the return value of * ParseArguments is false, the program should exit. /* Override class path if -jar flag was specified */ /* Set the -Dsun.java.launcher pseudo property */ /* set the -Dsun.java.launcher.* platform properties */ /* Show the splash screen if needed */ // need to block this thread against the main thread // so signals get caught correctly * Always detach the main thread so that it appears to have ended when * the application's main method exits. This will invoke the * uncaught exception handler machinery if main threw an * exception. An uncaught exception handler cannot change the * launcher's return code except by calling System.exit. * Wait for all non-daemon threads to end, then destroy the VM. * This will actually create a trivial new Java waiter thread * named "DestroyJavaVM", but this will be seen as a different * thread from the one that executed main, even though they are * the same C thread. This allows mainThread.join() and * mainThread.isAlive() to work as expected. /* Initialize the virtual machine */ /* If the user specified neither a class name nor a JAR file */ /* At this stage, argc/argv have the application's arguments */ for (i=0; i <
argc; i++) {
* Get the application's main class. * See bugid 5030265. The Main-Class name has already been parsed * from the manifest, but not parsed properly for UTF-8 support. * Hence the code here ignores the value previously extracted and * uses the pre-existing code to reextract the value. This is * possibly an end of release cycle expedient. However, it has * also been discovered that passing some character sets through * the environment has "strange" behavior on some variants of * Windows. Hence, maybe the manifest parsing code local to the * launcher should never be enhanced. * Hence, future work should either: * 1) Correct the local parsing code and verify that the * Main-Class attribute gets properly passed through * 2) Remove the vestages of maintaining main_class through * the environment (and remove these comments). // if we got here, we know that "what" is a main class, and it has been loaded * The LoadMainClass not only loads the main class, it will also ensure * that the main method's signature is correct, therefore further checking * is not required. The main method is invoked here so that extraneous java * stacks are not in the application stack trace. /* Build argument array */ /* Invoke main method. */ * The launcher's exit code (in the absence of calls to * System.exit) will be non-zero if main threw an exception. * Checks the command line options to find which JVM type was * specified. If no command line option was given for the JVM type, * the default type is used. The environment variable * JDK_ALTERNATE_VM and the command line option -XXaltjvm= are also * checked as ways of specifying which JVM type to invoke. /* To make things simpler we always copy the argv array */ /* The program name is always present */ if (
arg[0] !=
'-')
break;
/* Did the user pass an explicit VM type? */ /* Did the user specify an "alternate" VM? */ * Finish copying the arguments if we aborted the above loop. * NOTE that if we aborted via "break" then we did NOT copy the * last argument above, and in addition argi will be less than /* argv is null-terminated */ /* use the default VM type if not specified (no alias processing) */ /* Use a different VM type if we are on a server class machine? */ /* if using an alternate VM, no alias processing */ /* Resolve aliases first */ /* copied from HotSpot function "atomll()" */ while (*s !=
'\0' && *s >=
'0' && *s <=
'9') {
// 4705540: illegal if more characters are found after the first non-digit /* Create JVM with default stack and let VM handle malformed -Xss string*/ * Adds a new VM option with the given given name and value. * Expand options array if needed to accommodate at least one more * The SelectVersion() routine ensures that an appropriate version of * the JRE is running. The specification for the appropriate version * is obtained from either the manifest of a jar file (preferred) or * from command line options. * The routine also parses splash screen command line options and * passes on their values in private environment variables. * If the version has already been selected, set *main_class * with the value passed through the environment (if any) and * Scan through the arguments for options relevant to multiple JRE * support. For reference, the command line syntax is defined as: * java [options] class [argument...] * java [options] -jar file.jar [argument...] * As the scan is performed, make a copy of the argument list with * the version specification options (new to 1.5) removed, so that * a version less than 1.5 can be exec'd. * Note that due to the syntax of the native Windows interface * CreateProcess(), processing similar to the following exists in * the Windows platform specific routine ExecJRE (in java_md.c). * Changes here should be reproduced there. /* deal with "unfortunate" classpath syntax */ * Checking for headless toolkit option in the some way as AWT does: * "true" means true and any other value means false if (
argc <= 0) {
/* No operand? Possibly legit with -[full]version */ while (
argc-- > 0)
/* Copy over [argument...] */ * If there is a jar file, read the manifest. If the jarfile can't be * read, the manifest can't be read from the jar file, or the manifest * is corrupt, issue the appropriate error messages and exit. * Even if there isn't a jar file, construct a manifest_info structure * containing the command line information. It's a convenient way to carry * Command line splash screen option should have precedence * over the manifest, so the manifest data is used only if * splash_file_name has not been initialized above during command * Passing on splash screen info in environment variables * The JRE-Version and JRE-Restrict-Search values (if any) from the * manifest are overwritten by any specified on the command line. * "Valid" returns (other than unrecoverable errors) follow. Set * main_class as a side-effect of this routine. * If no version selection information is found either on the command * line or in the manifest, simply return. * Check for correct syntax of the version specification (JSR 56). * Find the appropriate JVM on the system. Just to be as forgiving as * possible, if the standard algorithms don't locate an appropriate * jre, check to see if the one running will satisfy the requirements. * This can happen on systems which haven't been set-up for multiple * If I'm not the chosen one, exec the chosen one. Returning from * ExecJRE indicates that I am indeed the chosen one. * The private environment variable _JAVA_VERSION_SET is used to * prevent the chosen one from re-reading the manifest file and * using the values found within to override the (potential) command * line flags stripped from argv (because the target may not * understand them). Passing the MainClass value is an optimization * to avoid locating, expanding and parsing the manifest extra * Parses command line arguments. Returns JNI_FALSE if launcher * should exit without starting vm, returns JNI_TRUE if vm needs * to be started to process given options. *pret (the launcher * process return value) is set to 0 for a normal exit. * The following case checks for -XshowSettings OR -XshowSetting:SUBOPT. * In the latter case, any SUBOPT value not recognized will default to "all" * The following case provide backward compatibility with old-style sprintf(
tmp,
"-Xrunhprof:cpu=old,file=%s", p +
1);
sprintf(
tmp,
"-Xrunhprof:cpu=old,file=java.prof");
/* No longer supported */ ;
/* Ignore machine independent options already handled */ ;
/* Do not pass option to vm. */ /* default to LM_CLASS if -jar and -cp option are * Initializes the Java Virtual Machine. Also frees options array when printf(
"ignoreUnrecognized is %s, ",
printf(
" option[%2d] = '%s'\n",
* Returns a new Java string object for the specified platform string. * Returns a new array of Java string objects for the specified * array of platform strings. for (i = 0; i <
strc; i++) {
* Loads a class and verifies that the main class is present and it is ok to * call it for more details refer to the java implementation. printf(
"%ld micro seconds to load main class\n",
printf(
"----_JAVA_LAUNCHER_DEBUG----\n");
* For tools, convert command line args thus: * javac -cp foo:foo/"*" -J-ms32m ... * java -ms32m -cp JLI_WildcardExpandClasspath(foo:foo/"*") ... * Takes 4 parameters, and returns the populated arguments /* Copy the VM arguments (i.e. prefixed with -J) */ for (i = 0; i <
jargc; i++) {
if (
arg[0] ==
'-' &&
arg[
1] ==
'J') {
for (i = 0; i <
argc; i++) {
if (
arg[0] ==
'-' &&
arg[
1] ==
'J') {
/* Copy the rest of the arguments */ for (i = 0; i <
jargc ; i++) {
if (
arg[0] !=
'-' ||
arg[
1] !=
'J') {
for (i = 0; i <
argc; i++) {
* For our tools, we try to add 3 VM options: * <envcp> is the user's setting of CLASSPATH -- for instance the user * tells javac where to find binary classes through this environment * variable. Notice that users will be able to compile against our * tools.jar to CLASSPATH. * <apphome> is the directory where the application is installed. * <appcp> is the classpath to where our apps' classfiles are. const char *s =
getenv(
"CLASSPATH");
/* 40 for -Denv.class.path= */ /* How big is the application's classpath? */ for (i = 0; i <
cpathc; i++) {
for (i = 0; i <
cpathc; i++) {
* inject the -Dsun.java.command pseudo property into the args structure * this pseudo property is used in the HotSpot VM to expose the * Java class name and arguments to the main method to the VM. The * HotSpot VM uses this pseudo property to store the Java class name * (or jar file name) and the arguments to the class's main method * to the instrumentation memory region. The sun.java.command pseudo * property is not exported by HotSpot to the Java layer. /* unexpected, one of these should be set. just return without /* determine the amount of memory to allocate assuming * the individual components will be space separated for (i = 0; i <
argc; i++) {
/* allocate the memory */ /* build the -D string */ for (i = 0; i <
argc; i++) {
/* the components of the string are space separated. In * the case of embedded white space, the relationship of * the white space separated components to their true * positional arguments will be ambiguous. This issue may * be addressed in a future release. * JVM would like to know if it's created by a standard Sun launcher, or by * user native application, the following property indicates the former. * Prints the version information from the java.version and other properties. * Prints all the Java settings, see the java implementation for more details. "printXUsageMessage",
"(Z)V"));
"appendVmSynonymMessage",
"printHelpMessage",
"(Z)V"));
/* Initialize the usage message with the usual preamble */ /* Assemble the other variant part of the usage */ /* The first known VM is the default */ /* Complete the usage message and print to stderr*/ * Read the jvm.cfg file and fill the knownJVMs[] array. * The functionality of the jvm.cfg file is subject to change without * notice and the mechanism will be removed in the future. * The lexical structure of the jvm.cfg file is as follows: * knownLine := flag "KNOWN" EOL * warnLine := flag "WARN" EOL * ignoreLine := flag "IGNORE" EOL * errorLine := flag "ERROR" EOL * aliasLine := flag "ALIASED_TO" flag EOL * predicateLine := flag "IF_SERVER_CLASS" flag EOL * commentLine := "#" text EOL * The semantics are that when someone specifies a flag on the command line: * - if the flag appears on a knownLine, then the identifier is used as * the name of the directory holding the JVM library (the name of the JVM). * - if the flag appears as the first flag on an aliasLine, the identifier * of the second flag is used as the name of the JVM. * - if the flag appears on a warnLine, the identifier is used as the * name of the JVM, but a warning is generated. * - if the flag appears on an ignoreLine, the identifier is recognized as the * name of a JVM, but the identifier is ignored and the default vm used * - if the flag appears on an errorLine, an error is generated. * - if the flag appears as the first flag on a predicateLine, and * the machine on which you are running passes the predicate indicated, * then the identifier of the second flag is used as the name of the JVM, * otherwise the identifier of the first flag is used as the name of the JVM. * If no flag is given on the command line, the first vmLine of the jvm.cfg * file determines the name of the JVM. * PredicateLines are only interpreted on first vmLine of a jvm.cfg file, * since they only make sense if someone hasn't specified the name of the * JVM on the command line. * The intent of the jvm.cfg file is to allow several JVM libraries to * be installed in different subdirectories of a single JRE installation, * for space-savings and convenience in testing. * The intent is explicitly not to provide a full aliasing or predicate /* Null-terminate this string for JLI_StringDup below */ /* Null terminate altVMName */ /* Null terminate server class VM name */ /* Returns index of VM or -1 if not found */ * Displays the splash screen according to the jar file name * and image file names stored in environment variables * Done with all command line processing and potential re-execs so * clean up the environment. * If user doesn't specify stack size, check if VM has a preference. * Note that HotSpot no longer supports JNI_VERSION_1_1 but it will * return its default stack size through the init args structure. {
/* Create a new thread to create JVM and invoke main method */ /* If the caller has deemed there is an error we * simply return that, otherwise we return the value of // need a way to get AWT/Swing apps launched when spawned from Eclipse, // which currently has no UI to not pass the -XstartOnFirstThread option if (
getenv(
"HACK_IGNORE_START_ON_FIRST_THREAD") !=
NULL)
return;
// Set a variable that tells us we started on the main thread. // This is used by the AWT during startup. (See awt.m) printf(
"NEVER_ACT_AS_A_SERVER_CLASS_MACHINE\n");
printf(
"ALWAYS_ACT_AS_A_SERVER_CLASS_MACHINE\n");
printf(
"DEFAULT_ERGONOMICS_POLICY\n");
* Return JNI_TRUE for an option string that has no effect but should * _not_ be passed on to the vm; return JNI_FALSE otherwise. On * Solaris SPARC, this screening needs to be done if: * -d32 or -d64 is passed to a binary with an unmatched data model * (the exec in CreateExecutionEnvironment removes -d<n> options and points the * exec to the proper binary). In the case of when the data model and the * requested version is matched, an exec would not occur, and these options * were erroneously passed to the vm. * Unconditionally remove both -d32 and -d64 options since only * the last such options has an effect; e.g. * java -d32 -d64 -d32 -version * A utility procedure to always print to stderr