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