File: | jdk/src/java.base/share/native/libjli/java.c |
Warning: | line 646, column 44 Null pointer passed to 1st parameter expecting 'nonnull' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. | |||
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
4 | * | |||
5 | * This code is free software; you can redistribute it and/or modify it | |||
6 | * under the terms of the GNU General Public License version 2 only, as | |||
7 | * published by the Free Software Foundation. Oracle designates this | |||
8 | * particular file as subject to the "Classpath" exception as provided | |||
9 | * by Oracle in the LICENSE file that accompanied this code. | |||
10 | * | |||
11 | * This code is distributed in the hope that it will be useful, but WITHOUT | |||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
14 | * version 2 for more details (a copy is included in the LICENSE file that | |||
15 | * accompanied this code). | |||
16 | * | |||
17 | * You should have received a copy of the GNU General Public License version | |||
18 | * 2 along with this work; if not, write to the Free Software Foundation, | |||
19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
20 | * | |||
21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
22 | * or visit www.oracle.com if you need additional information or have any | |||
23 | * questions. | |||
24 | */ | |||
25 | ||||
26 | /* | |||
27 | * Shared source for 'java' command line tool. | |||
28 | * | |||
29 | * If JAVA_ARGS is defined, then acts as a launcher for applications. For | |||
30 | * instance, the JDK command line tools such as javac and javadoc (see | |||
31 | * makefiles for more details) are built with this program. Any arguments | |||
32 | * prefixed with '-J' will be passed directly to the 'java' command. | |||
33 | */ | |||
34 | ||||
35 | /* | |||
36 | * One job of the launcher is to remove command line options which the | |||
37 | * vm does not understand and will not process. These options include | |||
38 | * options which select which style of vm is run (e.g. -client and | |||
39 | * -server) as well as options which select the data model to use. | |||
40 | * Additionally, for tools which invoke an underlying vm "-J-foo" | |||
41 | * options are turned into "-foo" options to the vm. This option | |||
42 | * filtering is handled in a number of places in the launcher, some of | |||
43 | * it in machine-dependent code. In this file, the function | |||
44 | * CheckJvmType removes vm style options and TranslateApplicationArgs | |||
45 | * removes "-J" prefixes. The CreateExecutionEnvironment function processes | |||
46 | * and removes -d<n> options. On unix, there is a possibility that the running | |||
47 | * data model may not match to the desired data model, in this case an exec is | |||
48 | * required to start the desired model. If the data models match, then | |||
49 | * ParseArguments will remove the -d<n> flags. If the data models do not match | |||
50 | * the CreateExecutionEnviroment will remove the -d<n> flags. | |||
51 | */ | |||
52 | ||||
53 | ||||
54 | #include "java.h" | |||
55 | #include "jni.h" | |||
56 | ||||
57 | /* | |||
58 | * A NOTE TO DEVELOPERS: For performance reasons it is important that | |||
59 | * the program image remain relatively small until after SelectVersion | |||
60 | * CreateExecutionEnvironment have finished their possibly recursive | |||
61 | * processing. Watch everything, but resist all temptations to use Java | |||
62 | * interfaces. | |||
63 | */ | |||
64 | ||||
65 | #define USE_STDERR1 JNI_TRUE1 /* we usually print to stderr */ | |||
66 | #define USE_STDOUT0 JNI_FALSE0 | |||
67 | ||||
68 | static jboolean printVersion = JNI_FALSE0; /* print and exit */ | |||
69 | static jboolean showVersion = JNI_FALSE0; /* print but continue */ | |||
70 | static jboolean printUsage = JNI_FALSE0; /* print and exit*/ | |||
71 | static jboolean printTo = USE_STDERR1; /* where to print version/usage */ | |||
72 | static jboolean printXUsage = JNI_FALSE0; /* print and exit*/ | |||
73 | static jboolean dryRun = JNI_FALSE0; /* initialize VM and exit */ | |||
74 | static char *showSettings = NULL((void*)0); /* print but continue */ | |||
75 | static jboolean showResolvedModules = JNI_FALSE0; | |||
76 | static jboolean listModules = JNI_FALSE0; | |||
77 | static char *describeModule = NULL((void*)0); | |||
78 | static jboolean validateModules = JNI_FALSE0; | |||
79 | ||||
80 | static const char *_program_name; | |||
81 | static const char *_launcher_name; | |||
82 | static jboolean _is_java_args = JNI_FALSE0; | |||
83 | static jboolean _have_classpath = JNI_FALSE0; | |||
84 | static const char *_fVersion; | |||
85 | static jboolean _wc_enabled = JNI_FALSE0; | |||
86 | ||||
87 | /* | |||
88 | * Entries for splash screen environment variables. | |||
89 | * putenv is performed in SelectVersion. We need | |||
90 | * them in memory until UnsetEnv, so they are made static | |||
91 | * global instead of auto local. | |||
92 | */ | |||
93 | static char* splash_file_entry = NULL((void*)0); | |||
94 | static char* splash_jar_entry = NULL((void*)0); | |||
95 | ||||
96 | /* | |||
97 | * List of VM options to be specified when the VM is created. | |||
98 | */ | |||
99 | static JavaVMOption *options; | |||
100 | static int numOptions, maxOptions; | |||
101 | ||||
102 | /* | |||
103 | * Prototypes for functions internal to launcher. | |||
104 | */ | |||
105 | static const char* GetFullVersion(); | |||
106 | static jboolean IsJavaArgs(); | |||
107 | static void SetJavaLauncherProp(); | |||
108 | static void SetClassPath(const char *s); | |||
109 | static void SetMainModule(const char *s); | |||
110 | static void SelectVersion(int argc, char **argv, char **main_class); | |||
111 | static jboolean ParseArguments(int *pargc, char ***pargv, | |||
112 | int *pmode, char **pwhat, | |||
113 | int *pret, const char *jrepath); | |||
114 | static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv, | |||
115 | InvocationFunctions *ifn); | |||
116 | static jstring NewPlatformString(JNIEnv *env, char *s); | |||
117 | static jclass LoadMainClass(JNIEnv *env, int mode, char *name); | |||
118 | static jclass GetApplicationClass(JNIEnv *env); | |||
119 | ||||
120 | static void TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv); | |||
121 | static jboolean AddApplicationOptions(int cpathc, const char **cpathv); | |||
122 | static void SetApplicationClassPath(const char**); | |||
123 | ||||
124 | static void PrintJavaVersion(JNIEnv *env, jboolean extraLF); | |||
125 | static void PrintUsage(JNIEnv* env, jboolean doXUsage); | |||
126 | static void ShowSettings(JNIEnv* env, char *optString); | |||
127 | static void ShowResolvedModules(JNIEnv* env); | |||
128 | static void ListModules(JNIEnv* env); | |||
129 | static void DescribeModule(JNIEnv* env, char* optString); | |||
130 | static jboolean ValidateModules(JNIEnv* env); | |||
131 | ||||
132 | static void SetPaths(int argc, char **argv); | |||
133 | ||||
134 | static void DumpState(); | |||
135 | ||||
136 | enum OptionKind { | |||
137 | LAUNCHER_OPTION = 0, | |||
138 | LAUNCHER_OPTION_WITH_ARGUMENT, | |||
139 | LAUNCHER_MAIN_OPTION, | |||
140 | VM_LONG_OPTION, | |||
141 | VM_LONG_OPTION_WITH_ARGUMENT, | |||
142 | VM_OPTION | |||
143 | }; | |||
144 | ||||
145 | static int GetOpt(int *pargc, char ***pargv, char **poption, char **pvalue); | |||
146 | static jboolean IsOptionWithArgument(int argc, char **argv); | |||
147 | ||||
148 | /* Maximum supported entries from jvm.cfg. */ | |||
149 | #define INIT_MAX_KNOWN_VMS10 10 | |||
150 | ||||
151 | /* Values for vmdesc.flag */ | |||
152 | enum vmdesc_flag { | |||
153 | VM_UNKNOWN = -1, | |||
154 | VM_KNOWN, | |||
155 | VM_ALIASED_TO, | |||
156 | VM_WARN, | |||
157 | VM_ERROR, | |||
158 | VM_IF_SERVER_CLASS, | |||
159 | VM_IGNORE | |||
160 | }; | |||
161 | ||||
162 | struct vmdesc { | |||
163 | char *name; | |||
164 | int flag; | |||
165 | char *alias; | |||
166 | char *server_class; | |||
167 | }; | |||
168 | static struct vmdesc *knownVMs = NULL((void*)0); | |||
169 | static int knownVMsCount = 0; | |||
170 | static int knownVMsLimit = 0; | |||
171 | ||||
172 | static void GrowKnownVMs(int minimum); | |||
173 | static int KnownVMIndex(const char* name); | |||
174 | static void FreeKnownVMs(); | |||
175 | static jboolean IsWildCardEnabled(); | |||
176 | ||||
177 | ||||
178 | #define SOURCE_LAUNCHER_MAIN_ENTRY"jdk.compiler/com.sun.tools.javac.launcher.Main" "jdk.compiler/com.sun.tools.javac.launcher.Main" | |||
179 | ||||
180 | /* | |||
181 | * This reports error. VM will not be created and no usage is printed. | |||
182 | */ | |||
183 | #define REPORT_ERROR(AC_ok, AC_failure_message, AC_questionable_arg)do { if (!AC_ok) { JLI_ReportErrorMessage(AC_failure_message, AC_questionable_arg); printUsage = 0; *pret = 1; return 0; } } while (0) \ | |||
184 | do { \ | |||
185 | if (!AC_ok) { \ | |||
186 | JLI_ReportErrorMessage(AC_failure_message, AC_questionable_arg); \ | |||
187 | printUsage = JNI_FALSE0; \ | |||
188 | *pret = 1; \ | |||
189 | return JNI_FALSE0; \ | |||
190 | } \ | |||
191 | } while (JNI_FALSE0) | |||
192 | ||||
193 | #define ARG_CHECK(AC_arg_count, AC_failure_message, AC_questionable_arg)do { if (AC_arg_count < 1) { JLI_ReportErrorMessage(AC_failure_message , AC_questionable_arg); printUsage = 1; *pret = 1; return 1; } } while (0) \ | |||
194 | do { \ | |||
195 | if (AC_arg_count < 1) { \ | |||
196 | JLI_ReportErrorMessage(AC_failure_message, AC_questionable_arg); \ | |||
197 | printUsage = JNI_TRUE1; \ | |||
198 | *pret = 1; \ | |||
199 | return JNI_TRUE1; \ | |||
200 | } \ | |||
201 | } while (JNI_FALSE0) | |||
202 | ||||
203 | /* | |||
204 | * Running Java code in primordial thread caused many problems. We will | |||
205 | * create a new thread to invoke JVM. See 6316197 for more information. | |||
206 | */ | |||
207 | static jlong threadStackSize = 0; /* stack size of the new thread */ | |||
208 | static jlong maxHeapSize = 0; /* max heap size */ | |||
209 | static jlong initialHeapSize = 0; /* initial heap size */ | |||
210 | ||||
211 | /* | |||
212 | * A minimum initial-thread stack size suitable for most platforms. | |||
213 | * This is the minimum amount of stack needed to load the JVM such | |||
214 | * that it can reject a too small -Xss value. If this is too small | |||
215 | * JVM initialization would cause a StackOverflowError. | |||
216 | */ | |||
217 | #ifndef STACK_SIZE_MINIMUM(64 * (1024UL)) | |||
218 | #define STACK_SIZE_MINIMUM(64 * (1024UL)) (64 * KB(1024UL)) | |||
219 | #endif | |||
220 | ||||
221 | /* | |||
222 | * Entry point. | |||
223 | */ | |||
224 | JNIEXPORT__attribute__((visibility("default"))) int JNICALL | |||
225 | JLI_Launch(int argc, char ** argv, /* main argc, argv */ | |||
226 | int jargc, const char** jargv, /* java args */ | |||
227 | int appclassc, const char** appclassv, /* app classpath */ | |||
228 | const char* fullversion, /* full version defined */ | |||
229 | const char* dotversion, /* UNUSED dot version defined */ | |||
230 | const char* pname, /* program name */ | |||
231 | const char* lname, /* launcher name */ | |||
232 | jboolean javaargs, /* JAVA_ARGS */ | |||
233 | jboolean cpwildcard, /* classpath wildcard*/ | |||
234 | jboolean javaw, /* windows-only javaw */ | |||
235 | jint ergo /* unused */ | |||
236 | ) | |||
237 | { | |||
238 | int mode = LM_UNKNOWN; | |||
239 | char *what = NULL((void*)0); | |||
240 | char *main_class = NULL((void*)0); | |||
241 | int ret; | |||
242 | InvocationFunctions ifn; | |||
243 | jlong start = 0, end = 0; | |||
244 | char jvmpath[MAXPATHLEN4096]; | |||
245 | char jrepath[MAXPATHLEN4096]; | |||
246 | char jvmcfg[MAXPATHLEN4096]; | |||
247 | ||||
248 | _fVersion = fullversion; | |||
249 | _launcher_name = lname; | |||
250 | _program_name = pname; | |||
251 | _is_java_args = javaargs; | |||
252 | _wc_enabled = cpwildcard; | |||
253 | ||||
254 | InitLauncher(javaw); | |||
255 | DumpState(); | |||
256 | if (JLI_IsTraceLauncher()) { | |||
257 | int i; | |||
258 | printf("Java args:\n")__printf_chk (2 - 1, "Java args:\n"); | |||
259 | for (i = 0; i < jargc ; i++) { | |||
260 | printf("jargv[%d] = %s\n", i, jargv[i])__printf_chk (2 - 1, "jargv[%d] = %s\n", i, jargv[i]); | |||
261 | } | |||
262 | printf("Command line args:\n")__printf_chk (2 - 1, "Command line args:\n"); | |||
263 | for (i = 0; i < argc ; i++) { | |||
264 | printf("argv[%d] = %s\n", i, argv[i])__printf_chk (2 - 1, "argv[%d] = %s\n", i, argv[i]); | |||
265 | } | |||
266 | AddOption("-Dsun.java.launcher.diag=true", NULL((void*)0)); | |||
267 | } | |||
268 | ||||
269 | /* | |||
270 | * SelectVersion() has several responsibilities: | |||
271 | * | |||
272 | * 1) Disallow specification of another JRE. With 1.9, another | |||
273 | * version of the JRE cannot be invoked. | |||
274 | * 2) Allow for a JRE version to invoke JDK 1.9 or later. Since | |||
275 | * all mJRE directives have been stripped from the request but | |||
276 | * the pre 1.9 JRE [ 1.6 thru 1.8 ], it is as if 1.9+ has been | |||
277 | * invoked from the command line. | |||
278 | */ | |||
279 | SelectVersion(argc, argv, &main_class); | |||
280 | ||||
281 | CreateExecutionEnvironment(&argc, &argv, | |||
282 | jrepath, sizeof(jrepath), | |||
283 | jvmpath, sizeof(jvmpath), | |||
284 | jvmcfg, sizeof(jvmcfg)); | |||
285 | ||||
286 | ifn.CreateJavaVM = 0; | |||
287 | ifn.GetDefaultJavaVMInitArgs = 0; | |||
288 | ||||
289 | if (JLI_IsTraceLauncher()) { | |||
290 | start = CurrentTimeMicros(); | |||
291 | } | |||
292 | ||||
293 | if (!LoadJavaVM(jvmpath, &ifn)) { | |||
294 | return(6); | |||
295 | } | |||
296 | ||||
297 | if (JLI_IsTraceLauncher()) { | |||
298 | end = CurrentTimeMicros(); | |||
299 | } | |||
300 | ||||
301 | JLI_TraceLauncher("%ld micro seconds to LoadJavaVM\n", (long)(end-start)); | |||
302 | ||||
303 | ++argv; | |||
304 | --argc; | |||
305 | ||||
306 | if (IsJavaArgs()) { | |||
307 | /* Preprocess wrapper arguments */ | |||
308 | TranslateApplicationArgs(jargc, jargv, &argc, &argv); | |||
309 | if (!AddApplicationOptions(appclassc, appclassv)) { | |||
310 | return(1); | |||
311 | } | |||
312 | } else { | |||
313 | /* Set default CLASSPATH */ | |||
314 | char* cpath = getenv("CLASSPATH"); | |||
315 | if (cpath != NULL((void*)0)) { | |||
316 | SetClassPath(cpath); | |||
317 | } | |||
318 | } | |||
319 | ||||
320 | /* Parse command line options; if the return value of | |||
321 | * ParseArguments is false, the program should exit. | |||
322 | */ | |||
323 | if (!ParseArguments(&argc, &argv, &mode, &what, &ret, jrepath)) { | |||
324 | return(ret); | |||
325 | } | |||
326 | ||||
327 | /* Override class path if -jar flag was specified */ | |||
328 | if (mode == LM_JAR) { | |||
329 | SetClassPath(what); /* Override class path */ | |||
330 | } | |||
331 | ||||
332 | /* set the -Dsun.java.command pseudo property */ | |||
333 | SetJavaCommandLineProp(what, argc, argv); | |||
334 | ||||
335 | /* Set the -Dsun.java.launcher pseudo property */ | |||
336 | SetJavaLauncherProp(); | |||
337 | ||||
338 | return JVMInit(&ifn, threadStackSize, argc, argv, mode, what, ret); | |||
339 | } | |||
340 | /* | |||
341 | * Always detach the main thread so that it appears to have ended when | |||
342 | * the application's main method exits. This will invoke the | |||
343 | * uncaught exception handler machinery if main threw an | |||
344 | * exception. An uncaught exception handler cannot change the | |||
345 | * launcher's return code except by calling System.exit. | |||
346 | * | |||
347 | * Wait for all non-daemon threads to end, then destroy the VM. | |||
348 | * This will actually create a trivial new Java waiter thread | |||
349 | * named "DestroyJavaVM", but this will be seen as a different | |||
350 | * thread from the one that executed main, even though they are | |||
351 | * the same C thread. This allows mainThread.join() and | |||
352 | * mainThread.isAlive() to work as expected. | |||
353 | */ | |||
354 | #define LEAVE()do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0) \ | |||
355 | do { \ | |||
356 | if ((*vm)->DetachCurrentThread(vm) != JNI_OK0) { \ | |||
357 | JLI_ReportErrorMessage(JVM_ERROR2"Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again"); \ | |||
358 | ret = 1; \ | |||
359 | } \ | |||
360 | if (JNI_TRUE1) { \ | |||
361 | (*vm)->DestroyJavaVM(vm); \ | |||
362 | return ret; \ | |||
363 | } \ | |||
364 | } while (JNI_FALSE0) | |||
365 | ||||
366 | #define CHECK_EXCEPTION_NULL_LEAVE(CENL_exception)do { if ((*env)->ExceptionOccurred(env)) { JLI_ReportExceptionDescription (env); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } if ((CENL_exception) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } } while (0) \ | |||
367 | do { \ | |||
368 | if ((*env)->ExceptionOccurred(env)) { \ | |||
369 | JLI_ReportExceptionDescription(env); \ | |||
370 | LEAVE()do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); \ | |||
371 | } \ | |||
372 | if ((CENL_exception) == NULL((void*)0)) { \ | |||
373 | JLI_ReportErrorMessage(JNI_ERROR"Error: A JNI error has occurred, please check your installation and try again"); \ | |||
374 | LEAVE()do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); \ | |||
375 | } \ | |||
376 | } while (JNI_FALSE0) | |||
377 | ||||
378 | #define CHECK_EXCEPTION_LEAVE(CEL_return_value)do { if ((*env)->ExceptionOccurred(env)) { JLI_ReportExceptionDescription (env); ret = (CEL_return_value); do { if ((*vm)->DetachCurrentThread (vm) != 0) { JLI_ReportErrorMessage("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } } while (0) \ | |||
379 | do { \ | |||
380 | if ((*env)->ExceptionOccurred(env)) { \ | |||
381 | JLI_ReportExceptionDescription(env); \ | |||
382 | ret = (CEL_return_value); \ | |||
383 | LEAVE()do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); \ | |||
384 | } \ | |||
385 | } while (JNI_FALSE0) | |||
386 | ||||
387 | ||||
388 | int | |||
389 | JavaMain(void* _args) | |||
390 | { | |||
391 | JavaMainArgs *args = (JavaMainArgs *)_args; | |||
392 | int argc = args->argc; | |||
393 | char **argv = args->argv; | |||
394 | int mode = args->mode; | |||
395 | char *what = args->what; | |||
396 | InvocationFunctions ifn = args->ifn; | |||
397 | ||||
398 | JavaVM *vm = 0; | |||
399 | JNIEnv *env = 0; | |||
400 | jclass mainClass = NULL((void*)0); | |||
401 | jclass appClass = NULL((void*)0); // actual application class being launched | |||
402 | jmethodID mainID; | |||
403 | jobjectArray mainArgs; | |||
404 | int ret = 0; | |||
405 | jlong start = 0, end = 0; | |||
406 | ||||
407 | RegisterThread(); | |||
408 | ||||
409 | /* Initialize the virtual machine */ | |||
410 | start = CurrentTimeMicros(); | |||
411 | if (!InitializeJVM(&vm, &env, &ifn)) { | |||
412 | JLI_ReportErrorMessage(JVM_ERROR1"Error: Could not create the Java Virtual Machine.\n" "Error: A fatal exception has occurred. Program will exit."); | |||
413 | exit(1); | |||
414 | } | |||
415 | ||||
416 | if (showSettings != NULL((void*)0)) { | |||
417 | ShowSettings(env, showSettings); | |||
418 | CHECK_EXCEPTION_LEAVE(1)do { if ((*env)->ExceptionOccurred(env)) { JLI_ReportExceptionDescription (env); ret = (1); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } } while (0); | |||
419 | } | |||
420 | ||||
421 | // show resolved modules and continue | |||
422 | if (showResolvedModules) { | |||
423 | ShowResolvedModules(env); | |||
424 | CHECK_EXCEPTION_LEAVE(1)do { if ((*env)->ExceptionOccurred(env)) { JLI_ReportExceptionDescription (env); ret = (1); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } } while (0); | |||
425 | } | |||
426 | ||||
427 | // list observable modules, then exit | |||
428 | if (listModules) { | |||
429 | ListModules(env); | |||
430 | CHECK_EXCEPTION_LEAVE(1)do { if ((*env)->ExceptionOccurred(env)) { JLI_ReportExceptionDescription (env); ret = (1); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } } while (0); | |||
431 | LEAVE()do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); | |||
432 | } | |||
433 | ||||
434 | // describe a module, then exit | |||
435 | if (describeModule != NULL((void*)0)) { | |||
436 | DescribeModule(env, describeModule); | |||
437 | CHECK_EXCEPTION_LEAVE(1)do { if ((*env)->ExceptionOccurred(env)) { JLI_ReportExceptionDescription (env); ret = (1); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } } while (0); | |||
438 | LEAVE()do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); | |||
439 | } | |||
440 | ||||
441 | if (printVersion || showVersion) { | |||
442 | PrintJavaVersion(env, showVersion); | |||
443 | CHECK_EXCEPTION_LEAVE(0)do { if ((*env)->ExceptionOccurred(env)) { JLI_ReportExceptionDescription (env); ret = (0); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } } while (0); | |||
444 | if (printVersion) { | |||
445 | LEAVE()do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); | |||
446 | } | |||
447 | } | |||
448 | ||||
449 | // modules have been validated at startup so exit | |||
450 | if (validateModules) { | |||
451 | LEAVE()do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); | |||
452 | } | |||
453 | ||||
454 | /* If the user specified neither a class name nor a JAR file */ | |||
455 | if (printXUsage || printUsage || what == 0 || mode == LM_UNKNOWN) { | |||
456 | PrintUsage(env, printXUsage); | |||
457 | CHECK_EXCEPTION_LEAVE(1)do { if ((*env)->ExceptionOccurred(env)) { JLI_ReportExceptionDescription (env); ret = (1); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } } while (0); | |||
458 | LEAVE()do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); | |||
459 | } | |||
460 | ||||
461 | FreeKnownVMs(); /* after last possible PrintUsage */ | |||
462 | ||||
463 | if (JLI_IsTraceLauncher()) { | |||
464 | end = CurrentTimeMicros(); | |||
465 | JLI_TraceLauncher("%ld micro seconds to InitializeJVM\n", (long)(end-start)); | |||
466 | } | |||
467 | ||||
468 | /* At this stage, argc/argv have the application's arguments */ | |||
469 | if (JLI_IsTraceLauncher()){ | |||
470 | int i; | |||
471 | printf("%s is '%s'\n", launchModeNames[mode], what)__printf_chk (2 - 1, "%s is '%s'\n", launchModeNames[mode], what ); | |||
472 | printf("App's argc is %d\n", argc)__printf_chk (2 - 1, "App's argc is %d\n", argc); | |||
473 | for (i=0; i < argc; i++) { | |||
474 | printf(" argv[%2d] = '%s'\n", i, argv[i])__printf_chk (2 - 1, " argv[%2d] = '%s'\n", i, argv[i]); | |||
475 | } | |||
476 | } | |||
477 | ||||
478 | ret = 1; | |||
479 | ||||
480 | /* | |||
481 | * Get the application's main class. It also checks if the main | |||
482 | * method exists. | |||
483 | * | |||
484 | * See bugid 5030265. The Main-Class name has already been parsed | |||
485 | * from the manifest, but not parsed properly for UTF-8 support. | |||
486 | * Hence the code here ignores the value previously extracted and | |||
487 | * uses the pre-existing code to reextract the value. This is | |||
488 | * possibly an end of release cycle expedient. However, it has | |||
489 | * also been discovered that passing some character sets through | |||
490 | * the environment has "strange" behavior on some variants of | |||
491 | * Windows. Hence, maybe the manifest parsing code local to the | |||
492 | * launcher should never be enhanced. | |||
493 | * | |||
494 | * Hence, future work should either: | |||
495 | * 1) Correct the local parsing code and verify that the | |||
496 | * Main-Class attribute gets properly passed through | |||
497 | * all environments, | |||
498 | * 2) Remove the vestages of maintaining main_class through | |||
499 | * the environment (and remove these comments). | |||
500 | * | |||
501 | * This method also correctly handles launching existing JavaFX | |||
502 | * applications that may or may not have a Main-Class manifest entry. | |||
503 | */ | |||
504 | mainClass = LoadMainClass(env, mode, what); | |||
505 | CHECK_EXCEPTION_NULL_LEAVE(mainClass)do { if ((*env)->ExceptionOccurred(env)) { JLI_ReportExceptionDescription (env); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } if ((mainClass) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } } while (0); | |||
506 | /* | |||
507 | * In some cases when launching an application that needs a helper, e.g., a | |||
508 | * JavaFX application with no main method, the mainClass will not be the | |||
509 | * applications own main class but rather a helper class. To keep things | |||
510 | * consistent in the UI we need to track and report the application main class. | |||
511 | */ | |||
512 | appClass = GetApplicationClass(env); | |||
513 | NULL_CHECK_RETURN_VALUE(appClass, -1)do { if ((appClass) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return -1; } } while (0); | |||
514 | ||||
515 | /* Build platform specific argument array */ | |||
516 | mainArgs = CreateApplicationArgs(env, argv, argc); | |||
517 | CHECK_EXCEPTION_NULL_LEAVE(mainArgs)do { if ((*env)->ExceptionOccurred(env)) { JLI_ReportExceptionDescription (env); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } if ((mainArgs) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } } while (0); | |||
518 | ||||
519 | if (dryRun) { | |||
520 | ret = 0; | |||
521 | LEAVE()do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); | |||
522 | } | |||
523 | ||||
524 | /* | |||
525 | * PostJVMInit uses the class name as the application name for GUI purposes, | |||
526 | * for example, on OSX this sets the application name in the menu bar for | |||
527 | * both SWT and JavaFX. So we'll pass the actual application class here | |||
528 | * instead of mainClass as that may be a launcher or helper class instead | |||
529 | * of the application class. | |||
530 | */ | |||
531 | PostJVMInit(env, appClass, vm); | |||
532 | CHECK_EXCEPTION_LEAVE(1)do { if ((*env)->ExceptionOccurred(env)) { JLI_ReportExceptionDescription (env); ret = (1); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } } while (0); | |||
533 | ||||
534 | /* | |||
535 | * The LoadMainClass not only loads the main class, it will also ensure | |||
536 | * that the main method's signature is correct, therefore further checking | |||
537 | * is not required. The main method is invoked here so that extraneous java | |||
538 | * stacks are not in the application stack trace. | |||
539 | */ | |||
540 | mainID = (*env)->GetStaticMethodID(env, mainClass, "main", | |||
541 | "([Ljava/lang/String;)V"); | |||
542 | CHECK_EXCEPTION_NULL_LEAVE(mainID)do { if ((*env)->ExceptionOccurred(env)) { JLI_ReportExceptionDescription (env); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } if ((mainID) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); } } while (0); | |||
543 | ||||
544 | /* Invoke main method. */ | |||
545 | (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); | |||
546 | ||||
547 | /* | |||
548 | * The launcher's exit code (in the absence of calls to | |||
549 | * System.exit) will be non-zero if main threw an exception. | |||
550 | */ | |||
551 | ret = (*env)->ExceptionOccurred(env) == NULL((void*)0) ? 0 : 1; | |||
552 | ||||
553 | LEAVE()do { if ((*vm)->DetachCurrentThread(vm) != 0) { JLI_ReportErrorMessage ("Error: Could not detach main thread.\n" "Error: A JNI error has occurred, please check your installation and try again" ); ret = 1; } if (1) { (*vm)->DestroyJavaVM(vm); return ret ; } } while (0); | |||
554 | } | |||
555 | ||||
556 | /* | |||
557 | * Test if the given name is one of the class path options. | |||
558 | */ | |||
559 | static jboolean | |||
560 | IsClassPathOption(const char* name) { | |||
561 | return JLI_StrCmp(name, "-classpath")strcmp((name), ("-classpath")) == 0 || | |||
562 | JLI_StrCmp(name, "-cp")strcmp((name), ("-cp")) == 0 || | |||
563 | JLI_StrCmp(name, "--class-path")strcmp((name), ("--class-path")) == 0; | |||
564 | } | |||
565 | ||||
566 | /* | |||
567 | * Test if the given name is a launcher option taking the main entry point. | |||
568 | */ | |||
569 | static jboolean | |||
570 | IsLauncherMainOption(const char* name) { | |||
571 | return JLI_StrCmp(name, "--module")strcmp((name), ("--module")) == 0 || | |||
572 | JLI_StrCmp(name, "-m")strcmp((name), ("-m")) == 0; | |||
573 | } | |||
574 | ||||
575 | /* | |||
576 | * Test if the given name is a white-space launcher option. | |||
577 | */ | |||
578 | static jboolean | |||
579 | IsLauncherOption(const char* name) { | |||
580 | return IsClassPathOption(name) || | |||
581 | IsLauncherMainOption(name) || | |||
582 | JLI_StrCmp(name, "--describe-module")strcmp((name), ("--describe-module")) == 0 || | |||
583 | JLI_StrCmp(name, "-d")strcmp((name), ("-d")) == 0 || | |||
584 | JLI_StrCmp(name, "--source")strcmp((name), ("--source")) == 0; | |||
585 | } | |||
586 | ||||
587 | /* | |||
588 | * Test if the given name is a module-system white-space option that | |||
589 | * will be passed to the VM with its corresponding long-form option | |||
590 | * name and "=" delimiter. | |||
591 | */ | |||
592 | static jboolean | |||
593 | IsModuleOption(const char* name) { | |||
594 | return JLI_StrCmp(name, "--module-path")strcmp((name), ("--module-path")) == 0 || | |||
595 | JLI_StrCmp(name, "-p")strcmp((name), ("-p")) == 0 || | |||
596 | JLI_StrCmp(name, "--upgrade-module-path")strcmp((name), ("--upgrade-module-path")) == 0 || | |||
597 | JLI_StrCmp(name, "--add-modules")strcmp((name), ("--add-modules")) == 0 || | |||
598 | JLI_StrCmp(name, "--enable-native-access")strcmp((name), ("--enable-native-access")) == 0 || | |||
599 | JLI_StrCmp(name, "--limit-modules")strcmp((name), ("--limit-modules")) == 0 || | |||
600 | JLI_StrCmp(name, "--add-exports")strcmp((name), ("--add-exports")) == 0 || | |||
601 | JLI_StrCmp(name, "--add-opens")strcmp((name), ("--add-opens")) == 0 || | |||
602 | JLI_StrCmp(name, "--add-reads")strcmp((name), ("--add-reads")) == 0 || | |||
603 | JLI_StrCmp(name, "--patch-module")strcmp((name), ("--patch-module")) == 0; | |||
604 | } | |||
605 | ||||
606 | static jboolean | |||
607 | IsLongFormModuleOption(const char* name) { | |||
608 | return JLI_StrCCmp(name, "--module-path=") == 0 || | |||
609 | JLI_StrCCmp(name, "--upgrade-module-path=") == 0 || | |||
610 | JLI_StrCCmp(name, "--add-modules=") == 0 || | |||
611 | JLI_StrCCmp(name, "--enable-native-access=") == 0 || | |||
612 | JLI_StrCCmp(name, "--limit-modules=") == 0 || | |||
613 | JLI_StrCCmp(name, "--add-exports=") == 0 || | |||
614 | JLI_StrCCmp(name, "--add-reads=") == 0 || | |||
615 | JLI_StrCCmp(name, "--patch-module=") == 0; | |||
616 | } | |||
617 | ||||
618 | /* | |||
619 | * Test if the given name has a white space option. | |||
620 | */ | |||
621 | jboolean | |||
622 | IsWhiteSpaceOption(const char* name) { | |||
623 | return IsModuleOption(name) || | |||
624 | IsLauncherOption(name); | |||
625 | } | |||
626 | ||||
627 | /* | |||
628 | * Check if it is OK to set the mode. | |||
629 | * If the mode was previously set, and should not be changed, | |||
630 | * a fatal error is reported. | |||
631 | */ | |||
632 | static int | |||
633 | checkMode(int mode, int newMode, const char *arg) { | |||
634 | if (mode == LM_SOURCE) { | |||
635 | JLI_ReportErrorMessage(ARG_ERROR14"Error: Option %s is not allowed with --source", arg); | |||
636 | exit(1); | |||
637 | } | |||
638 | return newMode; | |||
639 | } | |||
640 | ||||
641 | /* | |||
642 | * Test if an arg identifies a source file. | |||
643 | */ | |||
644 | static jboolean IsSourceFile(const char *arg) { | |||
645 | struct stat st; | |||
646 | return (JLI_HasSuffix(arg, ".java") && stat(arg, &st) == 0); | |||
| ||||
647 | } | |||
648 | ||||
649 | /* | |||
650 | * Checks the command line options to find which JVM type was | |||
651 | * specified. If no command line option was given for the JVM type, | |||
652 | * the default type is used. The environment variable | |||
653 | * JDK_ALTERNATE_VM and the command line option -XXaltjvm= are also | |||
654 | * checked as ways of specifying which JVM type to invoke. | |||
655 | */ | |||
656 | char * | |||
657 | CheckJvmType(int *pargc, char ***argv, jboolean speculative) { | |||
658 | int i, argi; | |||
659 | int argc; | |||
660 | char **newArgv; | |||
661 | int newArgvIdx = 0; | |||
662 | int isVMType; | |||
663 | int jvmidx = -1; | |||
664 | char *jvmtype = getenv("JDK_ALTERNATE_VM"); | |||
665 | ||||
666 | argc = *pargc; | |||
667 | ||||
668 | /* To make things simpler we always copy the argv array */ | |||
669 | newArgv = JLI_MemAlloc((argc + 1) * sizeof(char *)); | |||
670 | ||||
671 | /* The program name is always present */ | |||
672 | newArgv[newArgvIdx++] = (*argv)[0]; | |||
673 | ||||
674 | for (argi = 1; argi < argc; argi++) { | |||
675 | char *arg = (*argv)[argi]; | |||
676 | isVMType = 0; | |||
677 | ||||
678 | if (IsJavaArgs()) { | |||
679 | if (arg[0] != '-') { | |||
680 | newArgv[newArgvIdx++] = arg; | |||
681 | continue; | |||
682 | } | |||
683 | } else { | |||
684 | if (IsWhiteSpaceOption(arg)) { | |||
685 | newArgv[newArgvIdx++] = arg; | |||
686 | argi++; | |||
687 | if (argi < argc) { | |||
688 | newArgv[newArgvIdx++] = (*argv)[argi]; | |||
689 | } | |||
690 | continue; | |||
691 | } | |||
692 | if (arg[0] != '-') break; | |||
693 | } | |||
694 | ||||
695 | /* Did the user pass an explicit VM type? */ | |||
696 | i = KnownVMIndex(arg); | |||
697 | if (i >= 0) { | |||
698 | jvmtype = knownVMs[jvmidx = i].name + 1; /* skip the - */ | |||
699 | isVMType = 1; | |||
700 | *pargc = *pargc - 1; | |||
701 | } | |||
702 | ||||
703 | /* Did the user specify an "alternate" VM? */ | |||
704 | else if (JLI_StrCCmp(arg, "-XXaltjvm=") == 0 || JLI_StrCCmp(arg, "-J-XXaltjvm=") == 0) { | |||
705 | isVMType = 1; | |||
706 | jvmtype = arg+((arg[1]=='X')? 10 : 12); | |||
707 | jvmidx = -1; | |||
708 | } | |||
709 | ||||
710 | if (!isVMType) { | |||
711 | newArgv[newArgvIdx++] = arg; | |||
712 | } | |||
713 | } | |||
714 | ||||
715 | /* | |||
716 | * Finish copying the arguments if we aborted the above loop. | |||
717 | * NOTE that if we aborted via "break" then we did NOT copy the | |||
718 | * last argument above, and in addition argi will be less than | |||
719 | * argc. | |||
720 | */ | |||
721 | while (argi < argc) { | |||
722 | newArgv[newArgvIdx++] = (*argv)[argi]; | |||
723 | argi++; | |||
724 | } | |||
725 | ||||
726 | /* argv is null-terminated */ | |||
727 | newArgv[newArgvIdx] = 0; | |||
728 | ||||
729 | /* Copy back argv */ | |||
730 | *argv = newArgv; | |||
731 | *pargc = newArgvIdx; | |||
732 | ||||
733 | /* use the default VM type if not specified (no alias processing) */ | |||
734 | if (jvmtype == NULL((void*)0)) { | |||
735 | char* result = knownVMs[0].name+1; | |||
736 | JLI_TraceLauncher("Default VM: %s\n", result); | |||
737 | return result; | |||
738 | } | |||
739 | ||||
740 | /* if using an alternate VM, no alias processing */ | |||
741 | if (jvmidx < 0) | |||
742 | return jvmtype; | |||
743 | ||||
744 | /* Resolve aliases first */ | |||
745 | { | |||
746 | int loopCount = 0; | |||
747 | while (knownVMs[jvmidx].flag == VM_ALIASED_TO) { | |||
748 | int nextIdx = KnownVMIndex(knownVMs[jvmidx].alias); | |||
749 | ||||
750 | if (loopCount > knownVMsCount) { | |||
751 | if (!speculative) { | |||
752 | JLI_ReportErrorMessage(CFG_ERROR1"Error: Corrupt jvm.cfg file; cycle in alias list."); | |||
753 | exit(1); | |||
754 | } else { | |||
755 | return "ERROR"; | |||
756 | /* break; */ | |||
757 | } | |||
758 | } | |||
759 | ||||
760 | if (nextIdx < 0) { | |||
761 | if (!speculative) { | |||
762 | JLI_ReportErrorMessage(CFG_ERROR2"Error: Unable to resolve VM alias %s", knownVMs[jvmidx].alias); | |||
763 | exit(1); | |||
764 | } else { | |||
765 | return "ERROR"; | |||
766 | } | |||
767 | } | |||
768 | jvmidx = nextIdx; | |||
769 | jvmtype = knownVMs[jvmidx].name+1; | |||
770 | loopCount++; | |||
771 | } | |||
772 | } | |||
773 | ||||
774 | switch (knownVMs[jvmidx].flag) { | |||
775 | case VM_WARN: | |||
776 | if (!speculative) { | |||
777 | JLI_ReportErrorMessage(CFG_WARN1"Warning: %s VM not supported; %s VM will be used", jvmtype, knownVMs[0].name + 1); | |||
778 | } | |||
779 | /* fall through */ | |||
780 | case VM_IGNORE: | |||
781 | jvmtype = knownVMs[jvmidx=0].name + 1; | |||
782 | /* fall through */ | |||
783 | case VM_KNOWN: | |||
784 | break; | |||
785 | case VM_ERROR: | |||
786 | if (!speculative) { | |||
787 | JLI_ReportErrorMessage(CFG_ERROR3"Error: %s VM not supported", jvmtype); | |||
788 | exit(1); | |||
789 | } else { | |||
790 | return "ERROR"; | |||
791 | } | |||
792 | } | |||
793 | ||||
794 | return jvmtype; | |||
795 | } | |||
796 | ||||
797 | /* copied from HotSpot function "atomll()" */ | |||
798 | static int | |||
799 | parse_size(const char *s, jlong *result) { | |||
800 | jlong n = 0; | |||
801 | int args_read = sscanf(s, JLONG_FORMAT_SPECIFIER"%ld", &n); | |||
802 | if (args_read != 1) { | |||
803 | return 0; | |||
804 | } | |||
805 | while (*s != '\0' && *s >= '0' && *s <= '9') { | |||
806 | s++; | |||
807 | } | |||
808 | // 4705540: illegal if more characters are found after the first non-digit | |||
809 | if (JLI_StrLen(s)strlen((s)) > 1) { | |||
810 | return 0; | |||
811 | } | |||
812 | switch (*s) { | |||
813 | case 'T': case 't': | |||
814 | *result = n * GB(1024UL * (1024UL * (1024UL))) * KB(1024UL); | |||
815 | return 1; | |||
816 | case 'G': case 'g': | |||
817 | *result = n * GB(1024UL * (1024UL * (1024UL))); | |||
818 | return 1; | |||
819 | case 'M': case 'm': | |||
820 | *result = n * MB(1024UL * (1024UL)); | |||
821 | return 1; | |||
822 | case 'K': case 'k': | |||
823 | *result = n * KB(1024UL); | |||
824 | return 1; | |||
825 | case '\0': | |||
826 | *result = n; | |||
827 | return 1; | |||
828 | default: | |||
829 | /* Create JVM with default stack and let VM handle malformed -Xss string*/ | |||
830 | return 0; | |||
831 | } | |||
832 | } | |||
833 | ||||
834 | /* | |||
835 | * Adds a new VM option with the given name and value. | |||
836 | */ | |||
837 | void | |||
838 | AddOption(char *str, void *info) | |||
839 | { | |||
840 | /* | |||
841 | * Expand options array if needed to accommodate at least one more | |||
842 | * VM option. | |||
843 | */ | |||
844 | if (numOptions >= maxOptions) { | |||
845 | if (options == 0) { | |||
846 | maxOptions = 4; | |||
847 | options = JLI_MemAlloc(maxOptions * sizeof(JavaVMOption)); | |||
848 | } else { | |||
849 | JavaVMOption *tmp; | |||
850 | maxOptions *= 2; | |||
851 | tmp = JLI_MemAlloc(maxOptions * sizeof(JavaVMOption)); | |||
852 | memcpy(tmp, options, numOptions * sizeof(JavaVMOption)); | |||
853 | JLI_MemFree(options); | |||
854 | options = tmp; | |||
855 | } | |||
856 | } | |||
857 | options[numOptions].optionString = str; | |||
858 | options[numOptions++].extraInfo = info; | |||
859 | ||||
860 | /* | |||
861 | * -Xss is used both by the JVM and here to establish the stack size of the thread | |||
862 | * created to launch the JVM. In the latter case we need to ensure we don't go | |||
863 | * below the minimum stack size allowed. If -Xss is zero that tells the JVM to use | |||
864 | * 'default' sizes (either from JVM or system configuration, e.g. 'ulimit -s' on linux), | |||
865 | * and is not itself a small stack size that will be rejected. So we ignore -Xss0 here. | |||
866 | */ | |||
867 | if (JLI_StrCCmp(str, "-Xss") == 0) { | |||
868 | jlong tmp; | |||
869 | if (parse_size(str + 4, &tmp)) { | |||
870 | threadStackSize = tmp; | |||
871 | if (threadStackSize > 0 && threadStackSize < (jlong)STACK_SIZE_MINIMUM(64 * (1024UL))) { | |||
872 | threadStackSize = STACK_SIZE_MINIMUM(64 * (1024UL)); | |||
873 | } | |||
874 | } | |||
875 | } | |||
876 | ||||
877 | if (JLI_StrCCmp(str, "-Xmx") == 0) { | |||
878 | jlong tmp; | |||
879 | if (parse_size(str + 4, &tmp)) { | |||
880 | maxHeapSize = tmp; | |||
881 | } | |||
882 | } | |||
883 | ||||
884 | if (JLI_StrCCmp(str, "-Xms") == 0) { | |||
885 | jlong tmp; | |||
886 | if (parse_size(str + 4, &tmp)) { | |||
887 | initialHeapSize = tmp; | |||
888 | } | |||
889 | } | |||
890 | } | |||
891 | ||||
892 | static void | |||
893 | SetClassPath(const char *s) | |||
894 | { | |||
895 | char *def; | |||
896 | const char *orig = s; | |||
897 | static const char format[] = "-Djava.class.path=%s"; | |||
898 | /* | |||
899 | * usually we should not get a null pointer, but there are cases where | |||
900 | * we might just get one, in which case we simply ignore it, and let the | |||
901 | * caller deal with it | |||
902 | */ | |||
903 | if (s == NULL((void*)0)) | |||
904 | return; | |||
905 | s = JLI_WildcardExpandClasspath(s); | |||
906 | if (sizeof(format) - 2 + JLI_StrLen(s)strlen((s)) < JLI_StrLen(s)strlen((s))) | |||
907 | // s is became corrupted after expanding wildcards | |||
908 | return; | |||
909 | def = JLI_MemAlloc(sizeof(format) | |||
910 | - 2 /* strlen("%s") */ | |||
911 | + JLI_StrLen(s)strlen((s))); | |||
912 | sprintf(def, format, s)__builtin___sprintf_chk (def, 2 - 1, __builtin_object_size (def , 2 > 1), format, s); | |||
913 | AddOption(def, NULL((void*)0)); | |||
914 | if (s != orig) | |||
915 | JLI_MemFree((char *) s); | |||
916 | _have_classpath = JNI_TRUE1; | |||
917 | } | |||
918 | ||||
919 | static void | |||
920 | AddLongFormOption(const char *option, const char *arg) | |||
921 | { | |||
922 | static const char format[] = "%s=%s"; | |||
923 | char *def; | |||
924 | size_t def_len; | |||
925 | ||||
926 | def_len = JLI_StrLen(option)strlen((option)) + 1 + JLI_StrLen(arg)strlen((arg)) + 1; | |||
927 | def = JLI_MemAlloc(def_len); | |||
928 | JLI_Snprintf(def, def_len, format, option, arg)__builtin___snprintf_chk (def, def_len, 2 - 1, __builtin_object_size (def, 2 > 1), format, option, arg); | |||
929 | AddOption(def, NULL((void*)0)); | |||
930 | } | |||
931 | ||||
932 | static void | |||
933 | SetMainModule(const char *s) | |||
934 | { | |||
935 | static const char format[] = "-Djdk.module.main=%s"; | |||
936 | char* slash = JLI_StrChr(s, '/')strchr((s), ('/')); | |||
937 | size_t s_len, def_len; | |||
938 | char *def; | |||
939 | ||||
940 | /* value may be <module> or <module>/<mainclass> */ | |||
941 | if (slash == NULL((void*)0)) { | |||
942 | s_len = JLI_StrLen(s)strlen((s)); | |||
943 | } else { | |||
944 | s_len = (size_t) (slash - s); | |||
945 | } | |||
946 | def_len = sizeof(format) | |||
947 | - 2 /* strlen("%s") */ | |||
948 | + s_len; | |||
949 | def = JLI_MemAlloc(def_len); | |||
950 | JLI_Snprintf(def, def_len, format, s)__builtin___snprintf_chk (def, def_len, 2 - 1, __builtin_object_size (def, 2 > 1), format, s); | |||
951 | AddOption(def, NULL((void*)0)); | |||
952 | } | |||
953 | ||||
954 | /* | |||
955 | * The SelectVersion() routine ensures that an appropriate version of | |||
956 | * the JRE is running. The specification for the appropriate version | |||
957 | * is obtained from either the manifest of a jar file (preferred) or | |||
958 | * from command line options. | |||
959 | * The routine also parses splash screen command line options and | |||
960 | * passes on their values in private environment variables. | |||
961 | */ | |||
962 | static void | |||
963 | SelectVersion(int argc, char **argv, char **main_class) | |||
964 | { | |||
965 | char *arg; | |||
966 | char *operand; | |||
967 | char *version = NULL((void*)0); | |||
968 | char *jre = NULL((void*)0); | |||
969 | int jarflag = 0; | |||
970 | int headlessflag = 0; | |||
971 | int restrict_search = -1; /* -1 implies not known */ | |||
972 | manifest_info info; | |||
973 | char env_entry[MAXNAMELEN4096 + 24] = ENV_ENTRY"_JAVA_VERSION_SET" "="; | |||
974 | char *splash_file_name = NULL((void*)0); | |||
975 | char *splash_jar_name = NULL((void*)0); | |||
976 | char *env_in; | |||
977 | int res; | |||
978 | jboolean has_arg; | |||
979 | ||||
980 | /* | |||
981 | * If the version has already been selected, set *main_class | |||
982 | * with the value passed through the environment (if any) and | |||
983 | * simply return. | |||
984 | */ | |||
985 | ||||
986 | /* | |||
987 | * This environmental variable can be set by mJRE capable JREs | |||
988 | * [ 1.5 thru 1.8 ]. All other aspects of mJRE processing have been | |||
989 | * stripped by those JREs. This environmental variable allows 1.9+ | |||
990 | * JREs to be started by these mJRE capable JREs. | |||
991 | * Note that mJRE directives in the jar manifest file would have been | |||
992 | * ignored for a JRE started by another JRE... | |||
993 | * .. skipped for JRE 1.5 and beyond. | |||
994 | * .. not even checked for pre 1.5. | |||
995 | */ | |||
996 | if ((env_in = getenv(ENV_ENTRY"_JAVA_VERSION_SET")) != NULL((void*)0)) { | |||
997 | if (*env_in != '\0') | |||
998 | *main_class = JLI_StringDup(env_in); | |||
999 | return; | |||
1000 | } | |||
1001 | ||||
1002 | /* | |||
1003 | * Scan through the arguments for options relevant to multiple JRE | |||
1004 | * support. Multiple JRE support existed in JRE versions 1.5 thru 1.8. | |||
1005 | * | |||
1006 | * This capability is no longer available with JRE versions 1.9 and later. | |||
1007 | * These command line options are reported as errors. | |||
1008 | */ | |||
1009 | ||||
1010 | argc--; | |||
1011 | argv++; | |||
1012 | while ((arg = *argv) != 0 && *arg == '-') { | |||
1013 | has_arg = IsOptionWithArgument(argc, argv); | |||
1014 | if (JLI_StrCCmp(arg, "-version:") == 0) { | |||
1015 | JLI_ReportErrorMessage(SPC_ERROR1"Error: Specifying an alternate JDK/JRE version is no longer supported.\n The use of the flag '-version:' is no longer valid.\n Please download and execute the appropriate version."); | |||
1016 | } else if (JLI_StrCmp(arg, "-jre-restrict-search")strcmp((arg), ("-jre-restrict-search")) == 0) { | |||
1017 | JLI_ReportErrorMessage(SPC_ERROR2"Error: Specifying an alternate JDK/JRE is no longer supported.\n The related flags -jre-restrict-search | -jre-no-restrict-search are also no longer valid."); | |||
1018 | } else if (JLI_StrCmp(arg, "-jre-no-restrict-search")strcmp((arg), ("-jre-no-restrict-search")) == 0) { | |||
1019 | JLI_ReportErrorMessage(SPC_ERROR2"Error: Specifying an alternate JDK/JRE is no longer supported.\n The related flags -jre-restrict-search | -jre-no-restrict-search are also no longer valid."); | |||
1020 | } else { | |||
1021 | if (JLI_StrCmp(arg, "-jar")strcmp((arg), ("-jar")) == 0) | |||
1022 | jarflag = 1; | |||
1023 | if (IsWhiteSpaceOption(arg)) { | |||
1024 | if (has_arg) { | |||
1025 | argc--; | |||
1026 | argv++; | |||
1027 | arg = *argv; | |||
1028 | } | |||
1029 | } | |||
1030 | ||||
1031 | /* | |||
1032 | * Checking for headless toolkit option in the some way as AWT does: | |||
1033 | * "true" means true and any other value means false | |||
1034 | */ | |||
1035 | if (JLI_StrCmp(arg, "-Djava.awt.headless=true")strcmp((arg), ("-Djava.awt.headless=true")) == 0) { | |||
1036 | headlessflag = 1; | |||
1037 | } else if (JLI_StrCCmp(arg, "-Djava.awt.headless=") == 0) { | |||
1038 | headlessflag = 0; | |||
1039 | } else if (JLI_StrCCmp(arg, "-splash:") == 0) { | |||
1040 | splash_file_name = arg+8; | |||
1041 | } | |||
1042 | } | |||
1043 | argc--; | |||
1044 | argv++; | |||
1045 | } | |||
1046 | if (argc <= 0) { /* No operand? Possibly legit with -[full]version */ | |||
1047 | operand = NULL((void*)0); | |||
1048 | } else { | |||
1049 | argc--; | |||
1050 | operand = *argv++; | |||
1051 | } | |||
1052 | ||||
1053 | /* | |||
1054 | * If there is a jar file, read the manifest. If the jarfile can't be | |||
1055 | * read, the manifest can't be read from the jar file, or the manifest | |||
1056 | * is corrupt, issue the appropriate error messages and exit. | |||
1057 | * | |||
1058 | * Even if there isn't a jar file, construct a manifest_info structure | |||
1059 | * containing the command line information. It's a convenient way to carry | |||
1060 | * this data around. | |||
1061 | */ | |||
1062 | if (jarflag && operand) { | |||
1063 | if ((res = JLI_ParseManifest(operand, &info)) != 0) { | |||
1064 | if (res == -1) | |||
1065 | JLI_ReportErrorMessage(JAR_ERROR2"Error: Unable to access jarfile %s", operand); | |||
1066 | else | |||
1067 | JLI_ReportErrorMessage(JAR_ERROR3"Error: Invalid or corrupt jarfile %s", operand); | |||
1068 | exit(1); | |||
1069 | } | |||
1070 | ||||
1071 | /* | |||
1072 | * Command line splash screen option should have precedence | |||
1073 | * over the manifest, so the manifest data is used only if | |||
1074 | * splash_file_name has not been initialized above during command | |||
1075 | * line parsing | |||
1076 | */ | |||
1077 | if (!headlessflag && !splash_file_name && info.splashscreen_image_file_name) { | |||
1078 | splash_file_name = info.splashscreen_image_file_name; | |||
1079 | splash_jar_name = operand; | |||
1080 | } | |||
1081 | } else { | |||
1082 | info.manifest_version = NULL((void*)0); | |||
1083 | info.main_class = NULL((void*)0); | |||
1084 | info.jre_version = NULL((void*)0); | |||
1085 | info.jre_restrict_search = 0; | |||
1086 | } | |||
1087 | ||||
1088 | /* | |||
1089 | * Passing on splash screen info in environment variables | |||
1090 | */ | |||
1091 | if (splash_file_name && !headlessflag) { | |||
1092 | splash_file_entry = JLI_MemAlloc(JLI_StrLen(SPLASH_FILE_ENV_ENTRY "=")strlen(("_JAVA_SPLASH_FILE" "="))+JLI_StrLen(splash_file_name)strlen((splash_file_name))+1); | |||
1093 | JLI_StrCpy(splash_file_entry, SPLASH_FILE_ENV_ENTRY "=")strcpy((splash_file_entry), ("_JAVA_SPLASH_FILE" "=")); | |||
1094 | JLI_StrCat(splash_file_entry, splash_file_name)strcat((splash_file_entry), (splash_file_name)); | |||
1095 | putenv(splash_file_entry); | |||
1096 | } | |||
1097 | if (splash_jar_name && !headlessflag) { | |||
1098 | splash_jar_entry = JLI_MemAlloc(JLI_StrLen(SPLASH_JAR_ENV_ENTRY "=")strlen(("_JAVA_SPLASH_JAR" "="))+JLI_StrLen(splash_jar_name)strlen((splash_jar_name))+1); | |||
1099 | JLI_StrCpy(splash_jar_entry, SPLASH_JAR_ENV_ENTRY "=")strcpy((splash_jar_entry), ("_JAVA_SPLASH_JAR" "=")); | |||
1100 | JLI_StrCat(splash_jar_entry, splash_jar_name)strcat((splash_jar_entry), (splash_jar_name)); | |||
1101 | putenv(splash_jar_entry); | |||
1102 | } | |||
1103 | ||||
1104 | ||||
1105 | /* | |||
1106 | * "Valid" returns (other than unrecoverable errors) follow. Set | |||
1107 | * main_class as a side-effect of this routine. | |||
1108 | */ | |||
1109 | if (info.main_class != NULL((void*)0)) | |||
1110 | *main_class = JLI_StringDup(info.main_class); | |||
1111 | ||||
1112 | if (info.jre_version == NULL((void*)0)) { | |||
1113 | JLI_FreeManifest(); | |||
1114 | return; | |||
1115 | } | |||
1116 | ||||
1117 | } | |||
1118 | ||||
1119 | /* | |||
1120 | * Test if the current argv is an option, i.e. with a leading `-` | |||
1121 | * and followed with an argument without a leading `-`. | |||
1122 | */ | |||
1123 | static jboolean | |||
1124 | IsOptionWithArgument(int argc, char** argv) { | |||
1125 | char* option; | |||
1126 | char* arg; | |||
1127 | ||||
1128 | if (argc <= 1) | |||
1129 | return JNI_FALSE0; | |||
1130 | ||||
1131 | option = *argv; | |||
1132 | arg = *(argv+1); | |||
1133 | return *option == '-' && *arg != '-'; | |||
1134 | } | |||
1135 | ||||
1136 | /* | |||
1137 | * Gets the option, and its argument if the option has an argument. | |||
1138 | * It will update *pargc, **pargv to the next option. | |||
1139 | */ | |||
1140 | static int | |||
1141 | GetOpt(int *pargc, char ***pargv, char **poption, char **pvalue) { | |||
1142 | int argc = *pargc; | |||
1143 | char** argv = *pargv; | |||
1144 | char* arg = *argv; | |||
1145 | ||||
1146 | char* option = arg; | |||
1147 | char* value = NULL((void*)0); | |||
1148 | char* equals = NULL((void*)0); | |||
1149 | int kind = LAUNCHER_OPTION; | |||
1150 | jboolean has_arg = JNI_FALSE0; | |||
1151 | ||||
1152 | // check if this option may be a white-space option with an argument | |||
1153 | has_arg = IsOptionWithArgument(argc, argv); | |||
1154 | ||||
1155 | argv++; --argc; | |||
1156 | if (IsLauncherOption(arg)) { | |||
1157 | if (has_arg) { | |||
1158 | value = *argv; | |||
1159 | argv++; --argc; | |||
1160 | } | |||
1161 | kind = IsLauncherMainOption(arg) ? LAUNCHER_MAIN_OPTION | |||
1162 | : LAUNCHER_OPTION_WITH_ARGUMENT; | |||
1163 | } else if (IsModuleOption(arg)) { | |||
1164 | kind = VM_LONG_OPTION_WITH_ARGUMENT; | |||
1165 | if (has_arg) { | |||
1166 | value = *argv; | |||
1167 | argv++; --argc; | |||
1168 | } | |||
1169 | ||||
1170 | /* | |||
1171 | * Support short form alias | |||
1172 | */ | |||
1173 | if (JLI_StrCmp(arg, "-p")strcmp((arg), ("-p")) == 0) { | |||
1174 | option = "--module-path"; | |||
1175 | } | |||
1176 | ||||
1177 | } else if (JLI_StrCCmp(arg, "--") == 0 && (equals = JLI_StrChr(arg, '=')strchr((arg), ('='))) != NULL((void*)0)) { | |||
1178 | value = equals+1; | |||
1179 | if (JLI_StrCCmp(arg, "--describe-module=") == 0 || | |||
1180 | JLI_StrCCmp(arg, "--module=") == 0 || | |||
1181 | JLI_StrCCmp(arg, "--class-path=") == 0|| | |||
1182 | JLI_StrCCmp(arg, "--source=") == 0) { | |||
1183 | kind = LAUNCHER_OPTION_WITH_ARGUMENT; | |||
1184 | } else { | |||
1185 | kind = VM_LONG_OPTION; | |||
1186 | } | |||
1187 | } | |||
1188 | ||||
1189 | *pargc = argc; | |||
1190 | *pargv = argv; | |||
1191 | *poption = option; | |||
1192 | *pvalue = value; | |||
1193 | return kind; | |||
1194 | } | |||
1195 | ||||
1196 | /* | |||
1197 | * Parses command line arguments. Returns JNI_FALSE if launcher | |||
1198 | * should exit without starting vm, returns JNI_TRUE if vm needs | |||
1199 | * to be started to process given options. *pret (the launcher | |||
1200 | * process return value) is set to 0 for a normal exit. | |||
1201 | */ | |||
1202 | static jboolean | |||
1203 | ParseArguments(int *pargc, char ***pargv, | |||
1204 | int *pmode, char **pwhat, | |||
1205 | int *pret, const char *jrepath) | |||
1206 | { | |||
1207 | int argc = *pargc; | |||
1208 | char **argv = *pargv; | |||
1209 | int mode = LM_UNKNOWN; | |||
1210 | char *arg; | |||
1211 | ||||
1212 | *pret = 0; | |||
1213 | ||||
1214 | while ((arg = *argv) != 0 && *arg == '-') { | |||
| ||||
1215 | char *option = NULL((void*)0); | |||
1216 | char *value = NULL((void*)0); | |||
1217 | int kind = GetOpt(&argc, &argv, &option, &value); | |||
1218 | jboolean has_arg = value != NULL((void*)0) && JLI_StrLen(value)strlen((value)) > 0; | |||
1219 | jboolean has_arg_any_len = value != NULL((void*)0); | |||
1220 | ||||
1221 | /* | |||
1222 | * Option to set main entry point | |||
1223 | */ | |||
1224 | if (JLI_StrCmp(arg, "-jar")strcmp((arg), ("-jar")) == 0) { | |||
1225 | ARG_CHECK(argc, ARG_ERROR2, arg)do { if (argc < 1) { JLI_ReportErrorMessage("Error: %s requires jar file specification" , arg); printUsage = 1; *pret = 1; return 1; } } while (0); | |||
1226 | mode = checkMode(mode, LM_JAR, arg); | |||
1227 | } else if (JLI_StrCmp(arg, "--module")strcmp((arg), ("--module")) == 0 || | |||
1228 | JLI_StrCCmp(arg, "--module=") == 0 || | |||
1229 | JLI_StrCmp(arg, "-m")strcmp((arg), ("-m")) == 0) { | |||
1230 | REPORT_ERROR (has_arg, ARG_ERROR5, arg)do { if (!has_arg) { JLI_ReportErrorMessage("Error: %s requires module name" , arg); printUsage = 0; *pret = 1; return 0; } } while (0); | |||
1231 | SetMainModule(value); | |||
1232 | mode = checkMode(mode, LM_MODULE, arg); | |||
1233 | if (has_arg) { | |||
1234 | *pwhat = value; | |||
1235 | break; | |||
1236 | } | |||
1237 | } else if (JLI_StrCmp(arg, "--source")strcmp((arg), ("--source")) == 0 || | |||
1238 | JLI_StrCCmp(arg, "--source=") == 0) { | |||
1239 | REPORT_ERROR (has_arg, ARG_ERROR13, arg)do { if (!has_arg) { JLI_ReportErrorMessage("Error: %s requires source version" , arg); printUsage = 0; *pret = 1; return 0; } } while (0); | |||
1240 | mode = LM_SOURCE; | |||
1241 | if (has_arg) { | |||
1242 | const char *prop = "-Djdk.internal.javac.source="; | |||
1243 | size_t size = JLI_StrLen(prop)strlen((prop)) + JLI_StrLen(value)strlen((value)) + 1; | |||
1244 | char *propValue = (char *)JLI_MemAlloc(size); | |||
1245 | JLI_Snprintf(propValue, size, "%s%s", prop, value)__builtin___snprintf_chk (propValue, size, 2 - 1, __builtin_object_size (propValue, 2 > 1), "%s%s", prop, value); | |||
1246 | AddOption(propValue, NULL((void*)0)); | |||
1247 | } | |||
1248 | } else if (JLI_StrCmp(arg, "--class-path")strcmp((arg), ("--class-path")) == 0 || | |||
1249 | JLI_StrCCmp(arg, "--class-path=") == 0 || | |||
1250 | JLI_StrCmp(arg, "-classpath")strcmp((arg), ("-classpath")) == 0 || | |||
1251 | JLI_StrCmp(arg, "-cp")strcmp((arg), ("-cp")) == 0) { | |||
1252 | REPORT_ERROR (has_arg_any_len, ARG_ERROR1, arg)do { if (!has_arg_any_len) { JLI_ReportErrorMessage("Error: %s requires class path specification" , arg); printUsage = 0; *pret = 1; return 0; } } while (0); | |||
1253 | SetClassPath(value); | |||
1254 | if (mode != LM_SOURCE) { | |||
1255 | mode = LM_CLASS; | |||
1256 | } | |||
1257 | } else if (JLI_StrCmp(arg, "--list-modules")strcmp((arg), ("--list-modules")) == 0) { | |||
1258 | listModules = JNI_TRUE1; | |||
1259 | } else if (JLI_StrCmp(arg, "--show-resolved-modules")strcmp((arg), ("--show-resolved-modules")) == 0) { | |||
1260 | showResolvedModules = JNI_TRUE1; | |||
1261 | } else if (JLI_StrCmp(arg, "--validate-modules")strcmp((arg), ("--validate-modules")) == 0) { | |||
1262 | AddOption("-Djdk.module.validation=true", NULL((void*)0)); | |||
1263 | validateModules = JNI_TRUE1; | |||
1264 | } else if (JLI_StrCmp(arg, "--describe-module")strcmp((arg), ("--describe-module")) == 0 || | |||
1265 | JLI_StrCCmp(arg, "--describe-module=") == 0 || | |||
1266 | JLI_StrCmp(arg, "-d")strcmp((arg), ("-d")) == 0) { | |||
1267 | REPORT_ERROR (has_arg_any_len, ARG_ERROR12, arg)do { if (!has_arg_any_len) { JLI_ReportErrorMessage("Error: %s requires module name" , arg); printUsage = 0; *pret = 1; return 0; } } while (0); | |||
1268 | describeModule = value; | |||
1269 | /* | |||
1270 | * Parse white-space options | |||
1271 | */ | |||
1272 | } else if (has_arg) { | |||
1273 | if (kind == VM_LONG_OPTION) { | |||
1274 | AddOption(option, NULL((void*)0)); | |||
1275 | } else if (kind == VM_LONG_OPTION_WITH_ARGUMENT) { | |||
1276 | AddLongFormOption(option, value); | |||
1277 | } | |||
1278 | /* | |||
1279 | * Error missing argument | |||
1280 | */ | |||
1281 | } else if (!has_arg && (JLI_StrCmp(arg, "--module-path")strcmp((arg), ("--module-path")) == 0 || | |||
1282 | JLI_StrCmp(arg, "-p")strcmp((arg), ("-p")) == 0 || | |||
1283 | JLI_StrCmp(arg, "--upgrade-module-path")strcmp((arg), ("--upgrade-module-path")) == 0)) { | |||
1284 | REPORT_ERROR (has_arg, ARG_ERROR4, arg)do { if (!has_arg) { JLI_ReportErrorMessage("Error: %s requires module path specification" , arg); printUsage = 0; *pret = 1; return 0; } } while (0); | |||
1285 | ||||
1286 | } else if (!has_arg && (IsModuleOption(arg) || IsLongFormModuleOption(arg))) { | |||
1287 | REPORT_ERROR (has_arg, ARG_ERROR6, arg)do { if (!has_arg) { JLI_ReportErrorMessage("Error: %s requires modules to be specified" , arg); printUsage = 0; *pret = 1; return 0; } } while (0); | |||
1288 | /* | |||
1289 | * The following cases will cause the argument parsing to stop | |||
1290 | */ | |||
1291 | } else if (JLI_StrCmp(arg, "-help")strcmp((arg), ("-help")) == 0 || | |||
1292 | JLI_StrCmp(arg, "-h")strcmp((arg), ("-h")) == 0 || | |||
1293 | JLI_StrCmp(arg, "-?")strcmp((arg), ("-?")) == 0) { | |||
1294 | printUsage = JNI_TRUE1; | |||
1295 | return JNI_TRUE1; | |||
1296 | } else if (JLI_StrCmp(arg, "--help")strcmp((arg), ("--help")) == 0) { | |||
1297 | printUsage = JNI_TRUE1; | |||
1298 | printTo = USE_STDOUT0; | |||
1299 | return JNI_TRUE1; | |||
1300 | } else if (JLI_StrCmp(arg, "-version")strcmp((arg), ("-version")) == 0) { | |||
1301 | printVersion = JNI_TRUE1; | |||
1302 | return JNI_TRUE1; | |||
1303 | } else if (JLI_StrCmp(arg, "--version")strcmp((arg), ("--version")) == 0) { | |||
1304 | printVersion = JNI_TRUE1; | |||
1305 | printTo = USE_STDOUT0; | |||
1306 | return JNI_TRUE1; | |||
1307 | } else if (JLI_StrCmp(arg, "-showversion")strcmp((arg), ("-showversion")) == 0) { | |||
1308 | showVersion = JNI_TRUE1; | |||
1309 | } else if (JLI_StrCmp(arg, "--show-version")strcmp((arg), ("--show-version")) == 0) { | |||
1310 | showVersion = JNI_TRUE1; | |||
1311 | printTo = USE_STDOUT0; | |||
1312 | } else if (JLI_StrCmp(arg, "--dry-run")strcmp((arg), ("--dry-run")) == 0) { | |||
1313 | dryRun = JNI_TRUE1; | |||
1314 | } else if (JLI_StrCmp(arg, "-X")strcmp((arg), ("-X")) == 0) { | |||
1315 | printXUsage = JNI_TRUE1; | |||
1316 | return JNI_TRUE1; | |||
1317 | } else if (JLI_StrCmp(arg, "--help-extra")strcmp((arg), ("--help-extra")) == 0) { | |||
1318 | printXUsage = JNI_TRUE1; | |||
1319 | printTo = USE_STDOUT0; | |||
1320 | return JNI_TRUE1; | |||
1321 | /* | |||
1322 | * The following case checks for -XshowSettings OR -XshowSetting:SUBOPT. | |||
1323 | * In the latter case, any SUBOPT value not recognized will default to "all" | |||
1324 | */ | |||
1325 | } else if (JLI_StrCmp(arg, "-XshowSettings")strcmp((arg), ("-XshowSettings")) == 0 || | |||
1326 | JLI_StrCCmp(arg, "-XshowSettings:") == 0) { | |||
1327 | showSettings = arg; | |||
1328 | } else if (JLI_StrCmp(arg, "-Xdiag")strcmp((arg), ("-Xdiag")) == 0) { | |||
1329 | AddOption("-Dsun.java.launcher.diag=true", NULL((void*)0)); | |||
1330 | } else if (JLI_StrCmp(arg, "--show-module-resolution")strcmp((arg), ("--show-module-resolution")) == 0) { | |||
1331 | AddOption("-Djdk.module.showModuleResolution=true", NULL((void*)0)); | |||
1332 | /* | |||
1333 | * The following case provide backward compatibility with old-style | |||
1334 | * command line options. | |||
1335 | */ | |||
1336 | } else if (JLI_StrCmp(arg, "-fullversion")strcmp((arg), ("-fullversion")) == 0) { | |||
1337 | JLI_ReportMessage("%s full version \"%s\"", _launcher_name, GetFullVersion()); | |||
1338 | return JNI_FALSE0; | |||
1339 | } else if (JLI_StrCmp(arg, "--full-version")strcmp((arg), ("--full-version")) == 0) { | |||
1340 | JLI_ShowMessage("%s %s", _launcher_name, GetFullVersion()); | |||
1341 | return JNI_FALSE0; | |||
1342 | } else if (JLI_StrCmp(arg, "-verbosegc")strcmp((arg), ("-verbosegc")) == 0) { | |||
1343 | AddOption("-verbose:gc", NULL((void*)0)); | |||
1344 | } else if (JLI_StrCmp(arg, "-t")strcmp((arg), ("-t")) == 0) { | |||
1345 | AddOption("-Xt", NULL((void*)0)); | |||
1346 | } else if (JLI_StrCmp(arg, "-tm")strcmp((arg), ("-tm")) == 0) { | |||
1347 | AddOption("-Xtm", NULL((void*)0)); | |||
1348 | } else if (JLI_StrCmp(arg, "-debug")strcmp((arg), ("-debug")) == 0) { | |||
1349 | AddOption("-Xdebug", NULL((void*)0)); | |||
1350 | } else if (JLI_StrCmp(arg, "-noclassgc")strcmp((arg), ("-noclassgc")) == 0) { | |||
1351 | AddOption("-Xnoclassgc", NULL((void*)0)); | |||
1352 | } else if (JLI_StrCmp(arg, "-Xfuture")strcmp((arg), ("-Xfuture")) == 0) { | |||
1353 | JLI_ReportErrorMessage(ARG_DEPRECATED"Warning: %s option is deprecated and may be removed in a future release.", "-Xfuture"); | |||
1354 | AddOption("-Xverify:all", NULL((void*)0)); | |||
1355 | } else if (JLI_StrCmp(arg, "-verify")strcmp((arg), ("-verify")) == 0) { | |||
1356 | AddOption("-Xverify:all", NULL((void*)0)); | |||
1357 | } else if (JLI_StrCmp(arg, "-verifyremote")strcmp((arg), ("-verifyremote")) == 0) { | |||
1358 | AddOption("-Xverify:remote", NULL((void*)0)); | |||
1359 | } else if (JLI_StrCmp(arg, "-noverify")strcmp((arg), ("-noverify")) == 0) { | |||
1360 | /* | |||
1361 | * Note that no 'deprecated' message is needed here because the VM | |||
1362 | * issues 'deprecated' messages for -noverify and -Xverify:none. | |||
1363 | */ | |||
1364 | AddOption("-Xverify:none", NULL((void*)0)); | |||
1365 | } else if (JLI_StrCCmp(arg, "-ss") == 0 || | |||
1366 | JLI_StrCCmp(arg, "-oss") == 0 || | |||
1367 | JLI_StrCCmp(arg, "-ms") == 0 || | |||
1368 | JLI_StrCCmp(arg, "-mx") == 0) { | |||
1369 | char *tmp = JLI_MemAlloc(JLI_StrLen(arg)strlen((arg)) + 6); | |||
1370 | sprintf(tmp, "-X%s", arg + 1)__builtin___sprintf_chk (tmp, 2 - 1, __builtin_object_size (tmp , 2 > 1), "-X%s", arg + 1); /* skip '-' */ | |||
1371 | AddOption(tmp, NULL((void*)0)); | |||
1372 | } else if (JLI_StrCmp(arg, "-checksource")strcmp((arg), ("-checksource")) == 0 || | |||
1373 | JLI_StrCmp(arg, "-cs")strcmp((arg), ("-cs")) == 0 || | |||
1374 | JLI_StrCmp(arg, "-noasyncgc")strcmp((arg), ("-noasyncgc")) == 0) { | |||
1375 | /* No longer supported */ | |||
1376 | JLI_ReportErrorMessage(ARG_WARN"Warning: %s option is no longer supported.", arg); | |||
1377 | } else if (JLI_StrCCmp(arg, "-splash:") == 0) { | |||
1378 | ; /* Ignore machine independent options already handled */ | |||
1379 | } else if (ProcessPlatformOption(arg)) { | |||
1380 | ; /* Processing of platform dependent options */ | |||
1381 | } else { | |||
1382 | /* java.class.path set on the command line */ | |||
1383 | if (JLI_StrCCmp(arg, "-Djava.class.path=") == 0) { | |||
1384 | _have_classpath = JNI_TRUE1; | |||
1385 | } | |||
1386 | AddOption(arg, NULL((void*)0)); | |||
1387 | } | |||
1388 | } | |||
1389 | ||||
1390 | if (*pwhat == NULL((void*)0) && --argc >= 0) { | |||
1391 | *pwhat = *argv++; | |||
1392 | } | |||
1393 | ||||
1394 | if (*pwhat == NULL((void*)0)) { | |||
1395 | /* LM_UNKNOWN okay for options that exit */ | |||
1396 | if (!listModules && !describeModule && !validateModules) { | |||
1397 | *pret = 1; | |||
1398 | } | |||
1399 | } else if (mode
| |||
1400 | /* default to LM_CLASS if -m, -jar and -cp options are | |||
1401 | * not specified */ | |||
1402 | if (!_have_classpath) { | |||
1403 | SetClassPath("."); | |||
1404 | } | |||
1405 | mode = IsSourceFile(arg) ? LM_SOURCE : LM_CLASS; | |||
1406 | } else if (mode == LM_CLASS && IsSourceFile(arg)) { | |||
1407 | /* override LM_CLASS mode if given a source file */ | |||
1408 | mode = LM_SOURCE; | |||
1409 | } | |||
1410 | ||||
1411 | if (mode == LM_SOURCE) { | |||
1412 | AddOption("--add-modules=ALL-DEFAULT", NULL((void*)0)); | |||
1413 | *pwhat = SOURCE_LAUNCHER_MAIN_ENTRY"jdk.compiler/com.sun.tools.javac.launcher.Main"; | |||
1414 | // adjust (argc, argv) so that the name of the source file | |||
1415 | // is included in the args passed to the source launcher | |||
1416 | // main entry class | |||
1417 | *pargc = argc + 1; | |||
1418 | *pargv = argv - 1; | |||
1419 | } else { | |||
1420 | if (argc >= 0) { | |||
1421 | *pargc = argc; | |||
1422 | *pargv = argv; | |||
1423 | } | |||
1424 | } | |||
1425 | ||||
1426 | *pmode = mode; | |||
1427 | ||||
1428 | return JNI_TRUE1; | |||
1429 | } | |||
1430 | ||||
1431 | /* | |||
1432 | * Initializes the Java Virtual Machine. Also frees options array when | |||
1433 | * finished. | |||
1434 | */ | |||
1435 | static jboolean | |||
1436 | InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn) | |||
1437 | { | |||
1438 | JavaVMInitArgs args; | |||
1439 | jint r; | |||
1440 | ||||
1441 | memset(&args, 0, sizeof(args)); | |||
1442 | args.version = JNI_VERSION_1_20x00010002; | |||
1443 | args.nOptions = numOptions; | |||
1444 | args.options = options; | |||
1445 | args.ignoreUnrecognized = JNI_FALSE0; | |||
1446 | ||||
1447 | if (JLI_IsTraceLauncher()) { | |||
1448 | int i = 0; | |||
1449 | printf("JavaVM args:\n ")__printf_chk (2 - 1, "JavaVM args:\n "); | |||
1450 | printf("version 0x%08lx, ", (long)args.version)__printf_chk (2 - 1, "version 0x%08lx, ", (long)args.version); | |||
1451 | printf("ignoreUnrecognized is %s, ",__printf_chk (2 - 1, "ignoreUnrecognized is %s, ", args.ignoreUnrecognized ? "JNI_TRUE" : "JNI_FALSE") | |||
1452 | args.ignoreUnrecognized ? "JNI_TRUE" : "JNI_FALSE")__printf_chk (2 - 1, "ignoreUnrecognized is %s, ", args.ignoreUnrecognized ? "JNI_TRUE" : "JNI_FALSE"); | |||
1453 | printf("nOptions is %ld\n", (long)args.nOptions)__printf_chk (2 - 1, "nOptions is %ld\n", (long)args.nOptions ); | |||
1454 | for (i = 0; i < numOptions; i++) | |||
1455 | printf(" option[%2d] = '%s'\n",__printf_chk (2 - 1, " option[%2d] = '%s'\n", i, args.options [i].optionString) | |||
1456 | i, args.options[i].optionString)__printf_chk (2 - 1, " option[%2d] = '%s'\n", i, args.options [i].optionString); | |||
1457 | } | |||
1458 | ||||
1459 | r = ifn->CreateJavaVM(pvm, (void **)penv, &args); | |||
1460 | JLI_MemFree(options); | |||
1461 | return r == JNI_OK0; | |||
1462 | } | |||
1463 | ||||
1464 | static jclass helperClass = NULL((void*)0); | |||
1465 | ||||
1466 | jclass | |||
1467 | GetLauncherHelperClass(JNIEnv *env) | |||
1468 | { | |||
1469 | if (helperClass == NULL((void*)0)) { | |||
1470 | NULL_CHECK0(helperClass = FindBootStrapClass(env,do { if ((helperClass = FindBootStrapClass(env, "sun/launcher/LauncherHelper" )) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0) | |||
1471 | "sun/launcher/LauncherHelper"))do { if ((helperClass = FindBootStrapClass(env, "sun/launcher/LauncherHelper" )) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0); | |||
1472 | } | |||
1473 | return helperClass; | |||
1474 | } | |||
1475 | ||||
1476 | static jmethodID makePlatformStringMID = NULL((void*)0); | |||
1477 | /* | |||
1478 | * Returns a new Java string object for the specified platform string. | |||
1479 | */ | |||
1480 | static jstring | |||
1481 | NewPlatformString(JNIEnv *env, char *s) | |||
1482 | { | |||
1483 | int len = (int)JLI_StrLen(s)strlen((s)); | |||
1484 | jbyteArray ary; | |||
1485 | jclass cls = GetLauncherHelperClass(env); | |||
1486 | NULL_CHECK0(cls)do { if ((cls) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0); | |||
1487 | if (s == NULL((void*)0)) | |||
1488 | return 0; | |||
1489 | ||||
1490 | ary = (*env)->NewByteArray(env, len); | |||
1491 | if (ary != 0) { | |||
1492 | jstring str = 0; | |||
1493 | (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s); | |||
1494 | if (!(*env)->ExceptionOccurred(env)) { | |||
1495 | if (makePlatformStringMID == NULL((void*)0)) { | |||
1496 | NULL_CHECK0(makePlatformStringMID = (*env)->GetStaticMethodID(env,do { if ((makePlatformStringMID = (*env)->GetStaticMethodID (env, cls, "makePlatformString", "(Z[B)Ljava/lang/String;")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0) | |||
1497 | cls, "makePlatformString", "(Z[B)Ljava/lang/String;"))do { if ((makePlatformStringMID = (*env)->GetStaticMethodID (env, cls, "makePlatformString", "(Z[B)Ljava/lang/String;")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0); | |||
1498 | } | |||
1499 | str = (*env)->CallStaticObjectMethod(env, cls, | |||
1500 | makePlatformStringMID, USE_STDERR1, ary); | |||
1501 | CHECK_EXCEPTION_RETURN_VALUE(0)do { if ((*env)->ExceptionOccurred(env)) { return 0; } } while (0); | |||
1502 | (*env)->DeleteLocalRef(env, ary); | |||
1503 | return str; | |||
1504 | } | |||
1505 | } | |||
1506 | return 0; | |||
1507 | } | |||
1508 | ||||
1509 | /* | |||
1510 | * Returns a new array of Java string objects for the specified | |||
1511 | * array of platform strings. | |||
1512 | */ | |||
1513 | jobjectArray | |||
1514 | NewPlatformStringArray(JNIEnv *env, char **strv, int strc) | |||
1515 | { | |||
1516 | jarray cls; | |||
1517 | jarray ary; | |||
1518 | int i; | |||
1519 | ||||
1520 | NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"))do { if ((cls = FindBootStrapClass(env, "java/lang/String")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0); | |||
1521 | NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0))do { if ((ary = (*env)->NewObjectArray(env, strc, cls, 0)) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0); | |||
1522 | CHECK_EXCEPTION_RETURN_VALUE(0)do { if ((*env)->ExceptionOccurred(env)) { return 0; } } while (0); | |||
1523 | for (i = 0; i < strc; i++) { | |||
1524 | jstring str = NewPlatformString(env, *strv++); | |||
1525 | NULL_CHECK0(str)do { if ((str) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0); | |||
1526 | (*env)->SetObjectArrayElement(env, ary, i, str); | |||
1527 | (*env)->DeleteLocalRef(env, str); | |||
1528 | } | |||
1529 | return ary; | |||
1530 | } | |||
1531 | ||||
1532 | /* | |||
1533 | * Loads a class and verifies that the main class is present and it is ok to | |||
1534 | * call it for more details refer to the java implementation. | |||
1535 | */ | |||
1536 | static jclass | |||
1537 | LoadMainClass(JNIEnv *env, int mode, char *name) | |||
1538 | { | |||
1539 | jmethodID mid; | |||
1540 | jstring str; | |||
1541 | jobject result; | |||
1542 | jlong start = 0, end = 0; | |||
1543 | jclass cls = GetLauncherHelperClass(env); | |||
1544 | NULL_CHECK0(cls)do { if ((cls) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0); | |||
1545 | if (JLI_IsTraceLauncher()) { | |||
1546 | start = CurrentTimeMicros(); | |||
1547 | } | |||
1548 | NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,do { if ((mid = (*env)->GetStaticMethodID(env, cls, "checkAndLoadMain" , "(ZILjava/lang/String;)Ljava/lang/Class;")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0) | |||
1549 | "checkAndLoadMain",do { if ((mid = (*env)->GetStaticMethodID(env, cls, "checkAndLoadMain" , "(ZILjava/lang/String;)Ljava/lang/Class;")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0) | |||
1550 | "(ZILjava/lang/String;)Ljava/lang/Class;"))do { if ((mid = (*env)->GetStaticMethodID(env, cls, "checkAndLoadMain" , "(ZILjava/lang/String;)Ljava/lang/Class;")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0); | |||
1551 | ||||
1552 | NULL_CHECK0(str = NewPlatformString(env, name))do { if ((str = NewPlatformString(env, name)) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0); | |||
1553 | NULL_CHECK0(result = (*env)->CallStaticObjectMethod(env, cls, mid,do { if ((result = (*env)->CallStaticObjectMethod(env, cls , mid, 1, mode, str)) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0) | |||
1554 | USE_STDERR, mode, str))do { if ((result = (*env)->CallStaticObjectMethod(env, cls , mid, 1, mode, str)) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0); | |||
1555 | ||||
1556 | if (JLI_IsTraceLauncher()) { | |||
1557 | end = CurrentTimeMicros(); | |||
1558 | printf("%ld micro seconds to load main class\n", (long)(end-start))__printf_chk (2 - 1, "%ld micro seconds to load main class\n" , (long)(end-start)); | |||
1559 | printf("----%s----\n", JLDEBUG_ENV_ENTRY)__printf_chk (2 - 1, "----%s----\n", "_JAVA_LAUNCHER_DEBUG"); | |||
1560 | } | |||
1561 | ||||
1562 | return (jclass)result; | |||
1563 | } | |||
1564 | ||||
1565 | static jclass | |||
1566 | GetApplicationClass(JNIEnv *env) | |||
1567 | { | |||
1568 | jmethodID mid; | |||
1569 | jclass appClass; | |||
1570 | jclass cls = GetLauncherHelperClass(env); | |||
1571 | NULL_CHECK0(cls)do { if ((cls) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0); | |||
1572 | NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,do { if ((mid = (*env)->GetStaticMethodID(env, cls, "getApplicationClass" , "()Ljava/lang/Class;")) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0) | |||
1573 | "getApplicationClass",do { if ((mid = (*env)->GetStaticMethodID(env, cls, "getApplicationClass" , "()Ljava/lang/Class;")) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0) | |||
1574 | "()Ljava/lang/Class;"))do { if ((mid = (*env)->GetStaticMethodID(env, cls, "getApplicationClass" , "()Ljava/lang/Class;")) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return 0; } } while (0); | |||
1575 | ||||
1576 | appClass = (*env)->CallStaticObjectMethod(env, cls, mid); | |||
1577 | CHECK_EXCEPTION_RETURN_VALUE(0)do { if ((*env)->ExceptionOccurred(env)) { return 0; } } while (0); | |||
1578 | return appClass; | |||
1579 | } | |||
1580 | ||||
1581 | static char* expandWildcardOnLongOpt(char* arg) { | |||
1582 | char *p, *value; | |||
1583 | size_t optLen, valueLen; | |||
1584 | p = JLI_StrChr(arg, '=')strchr((arg), ('=')); | |||
1585 | ||||
1586 | if (p == NULL((void*)0) || p[1] == '\0') { | |||
1587 | JLI_ReportErrorMessage(ARG_ERROR1"Error: %s requires class path specification", arg); | |||
1588 | exit(1); | |||
1589 | } | |||
1590 | p++; | |||
1591 | value = (char *) JLI_WildcardExpandClasspath(p); | |||
1592 | if (p == value) { | |||
1593 | // no wildcard | |||
1594 | return arg; | |||
1595 | } | |||
1596 | ||||
1597 | optLen = p - arg; | |||
1598 | valueLen = JLI_StrLen(value)strlen((value)); | |||
1599 | p = JLI_MemAlloc(optLen + valueLen + 1); | |||
1600 | memcpy(p, arg, optLen); | |||
1601 | memcpy(p + optLen, value, valueLen); | |||
1602 | p[optLen + valueLen] = '\0'; | |||
1603 | return p; | |||
1604 | } | |||
1605 | ||||
1606 | /* | |||
1607 | * For tools, convert command line args thus: | |||
1608 | * javac -cp foo:foo/"*" -J-ms32m ... | |||
1609 | * java -ms32m -cp JLI_WildcardExpandClasspath(foo:foo/"*") ... | |||
1610 | * | |||
1611 | * Takes 4 parameters, and returns the populated arguments | |||
1612 | */ | |||
1613 | static void | |||
1614 | TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv) | |||
1615 | { | |||
1616 | int argc = *pargc; | |||
1617 | char **argv = *pargv; | |||
1618 | int nargc = argc + jargc; | |||
1619 | char **nargv = JLI_MemAlloc((nargc + 1) * sizeof(char *)); | |||
1620 | int i; | |||
1621 | ||||
1622 | *pargc = nargc; | |||
1623 | *pargv = nargv; | |||
1624 | ||||
1625 | /* Copy the VM arguments (i.e. prefixed with -J) */ | |||
1626 | for (i = 0; i < jargc; i++) { | |||
1627 | const char *arg = jargv[i]; | |||
1628 | if (arg[0] == '-' && arg[1] == 'J') { | |||
1629 | *nargv++ = ((arg + 2) == NULL((void*)0)) ? NULL((void*)0) : JLI_StringDup(arg + 2); | |||
1630 | } | |||
1631 | } | |||
1632 | ||||
1633 | for (i = 0; i < argc; i++) { | |||
1634 | char *arg = argv[i]; | |||
1635 | if (arg[0] == '-' && arg[1] == 'J') { | |||
1636 | if (arg[2] == '\0') { | |||
1637 | JLI_ReportErrorMessage(ARG_ERROR3"Error: The -J option should not be followed by a space."); | |||
1638 | exit(1); | |||
1639 | } | |||
1640 | *nargv++ = arg + 2; | |||
1641 | } | |||
1642 | } | |||
1643 | ||||
1644 | /* Copy the rest of the arguments */ | |||
1645 | for (i = 0; i < jargc ; i++) { | |||
1646 | const char *arg = jargv[i]; | |||
1647 | if (arg[0] != '-' || arg[1] != 'J') { | |||
1648 | *nargv++ = (arg == NULL((void*)0)) ? NULL((void*)0) : JLI_StringDup(arg); | |||
1649 | } | |||
1650 | } | |||
1651 | for (i = 0; i < argc; i++) { | |||
1652 | char *arg = argv[i]; | |||
1653 | if (arg[0] == '-') { | |||
1654 | if (arg[1] == 'J') | |||
1655 | continue; | |||
1656 | if (IsWildCardEnabled()) { | |||
1657 | if (IsClassPathOption(arg) && i < argc - 1) { | |||
1658 | *nargv++ = arg; | |||
1659 | *nargv++ = (char *) JLI_WildcardExpandClasspath(argv[i+1]); | |||
1660 | i++; | |||
1661 | continue; | |||
1662 | } | |||
1663 | if (JLI_StrCCmp(arg, "--class-path=") == 0) { | |||
1664 | *nargv++ = expandWildcardOnLongOpt(arg); | |||
1665 | continue; | |||
1666 | } | |||
1667 | } | |||
1668 | } | |||
1669 | *nargv++ = arg; | |||
1670 | } | |||
1671 | *nargv = 0; | |||
1672 | } | |||
1673 | ||||
1674 | /* | |||
1675 | * For our tools, we try to add 3 VM options: | |||
1676 | * -Denv.class.path=<envcp> | |||
1677 | * -Dapplication.home=<apphome> | |||
1678 | * -Djava.class.path=<appcp> | |||
1679 | * <envcp> is the user's setting of CLASSPATH -- for instance the user | |||
1680 | * tells javac where to find binary classes through this environment | |||
1681 | * variable. Notice that users will be able to compile against our | |||
1682 | * tools classes (sun.tools.javac.Main) only if they explicitly add | |||
1683 | * tools.jar to CLASSPATH. | |||
1684 | * <apphome> is the directory where the application is installed. | |||
1685 | * <appcp> is the classpath to where our apps' classfiles are. | |||
1686 | */ | |||
1687 | static jboolean | |||
1688 | AddApplicationOptions(int cpathc, const char **cpathv) | |||
1689 | { | |||
1690 | char *envcp, *appcp, *apphome; | |||
1691 | char home[MAXPATHLEN4096]; /* application home */ | |||
1692 | char separator[] = { PATH_SEPARATOR':', '\0' }; | |||
1693 | int size, i; | |||
1694 | ||||
1695 | { | |||
1696 | const char *s = getenv("CLASSPATH"); | |||
1697 | if (s) { | |||
1698 | s = (char *) JLI_WildcardExpandClasspath(s); | |||
1699 | /* 40 for -Denv.class.path= */ | |||
1700 | if (JLI_StrLen(s)strlen((s)) + 40 > JLI_StrLen(s)strlen((s))) { // Safeguard from overflow | |||
1701 | envcp = (char *)JLI_MemAlloc(JLI_StrLen(s)strlen((s)) + 40); | |||
1702 | sprintf(envcp, "-Denv.class.path=%s", s)__builtin___sprintf_chk (envcp, 2 - 1, __builtin_object_size ( envcp, 2 > 1), "-Denv.class.path=%s", s); | |||
1703 | AddOption(envcp, NULL((void*)0)); | |||
1704 | } | |||
1705 | } | |||
1706 | } | |||
1707 | ||||
1708 | if (!GetApplicationHome(home, sizeof(home))) { | |||
1709 | JLI_ReportErrorMessage(CFG_ERROR5"Error: Could not determine application home."); | |||
1710 | return JNI_FALSE0; | |||
1711 | } | |||
1712 | ||||
1713 | /* 40 for '-Dapplication.home=' */ | |||
1714 | apphome = (char *)JLI_MemAlloc(JLI_StrLen(home)strlen((home)) + 40); | |||
1715 | sprintf(apphome, "-Dapplication.home=%s", home)__builtin___sprintf_chk (apphome, 2 - 1, __builtin_object_size (apphome, 2 > 1), "-Dapplication.home=%s", home); | |||
1716 | AddOption(apphome, NULL((void*)0)); | |||
1717 | ||||
1718 | /* How big is the application's classpath? */ | |||
1719 | if (cpathc > 0) { | |||
1720 | size = 40; /* 40: "-Djava.class.path=" */ | |||
1721 | for (i = 0; i < cpathc; i++) { | |||
1722 | size += (int)JLI_StrLen(home)strlen((home)) + (int)JLI_StrLen(cpathv[i])strlen((cpathv[i])) + 1; /* 1: separator */ | |||
1723 | } | |||
1724 | appcp = (char *)JLI_MemAlloc(size + 1); | |||
1725 | JLI_StrCpy(appcp, "-Djava.class.path=")strcpy((appcp), ("-Djava.class.path=")); | |||
1726 | for (i = 0; i < cpathc; i++) { | |||
1727 | JLI_StrCat(appcp, home)strcat((appcp), (home)); /* c:\program files\myapp */ | |||
1728 | JLI_StrCat(appcp, cpathv[i])strcat((appcp), (cpathv[i])); /* \lib\myapp.jar */ | |||
1729 | JLI_StrCat(appcp, separator)strcat((appcp), (separator)); /* ; */ | |||
1730 | } | |||
1731 | appcp[JLI_StrLen(appcp)strlen((appcp))-1] = '\0'; /* remove trailing path separator */ | |||
1732 | AddOption(appcp, NULL((void*)0)); | |||
1733 | } | |||
1734 | return JNI_TRUE1; | |||
1735 | } | |||
1736 | ||||
1737 | /* | |||
1738 | * inject the -Dsun.java.command pseudo property into the args structure | |||
1739 | * this pseudo property is used in the HotSpot VM to expose the | |||
1740 | * Java class name and arguments to the main method to the VM. The | |||
1741 | * HotSpot VM uses this pseudo property to store the Java class name | |||
1742 | * (or jar file name) and the arguments to the class's main method | |||
1743 | * to the instrumentation memory region. The sun.java.command pseudo | |||
1744 | * property is not exported by HotSpot to the Java layer. | |||
1745 | */ | |||
1746 | void | |||
1747 | SetJavaCommandLineProp(char *what, int argc, char **argv) | |||
1748 | { | |||
1749 | ||||
1750 | int i = 0; | |||
1751 | size_t len = 0; | |||
1752 | char* javaCommand = NULL((void*)0); | |||
1753 | char* dashDstr = "-Dsun.java.command="; | |||
1754 | ||||
1755 | if (what == NULL((void*)0)) { | |||
1756 | /* unexpected, one of these should be set. just return without | |||
1757 | * setting the property | |||
1758 | */ | |||
1759 | return; | |||
1760 | } | |||
1761 | ||||
1762 | /* determine the amount of memory to allocate assuming | |||
1763 | * the individual components will be space separated | |||
1764 | */ | |||
1765 | len = JLI_StrLen(what)strlen((what)); | |||
1766 | for (i = 0; i < argc; i++) { | |||
1767 | len += JLI_StrLen(argv[i])strlen((argv[i])) + 1; | |||
1768 | } | |||
1769 | ||||
1770 | /* allocate the memory */ | |||
1771 | javaCommand = (char*) JLI_MemAlloc(len + JLI_StrLen(dashDstr)strlen((dashDstr)) + 1); | |||
1772 | ||||
1773 | /* build the -D string */ | |||
1774 | *javaCommand = '\0'; | |||
1775 | JLI_StrCat(javaCommand, dashDstr)strcat((javaCommand), (dashDstr)); | |||
1776 | JLI_StrCat(javaCommand, what)strcat((javaCommand), (what)); | |||
1777 | ||||
1778 | for (i = 0; i < argc; i++) { | |||
1779 | /* the components of the string are space separated. In | |||
1780 | * the case of embedded white space, the relationship of | |||
1781 | * the white space separated components to their true | |||
1782 | * positional arguments will be ambiguous. This issue may | |||
1783 | * be addressed in a future release. | |||
1784 | */ | |||
1785 | JLI_StrCat(javaCommand, " ")strcat((javaCommand), (" ")); | |||
1786 | JLI_StrCat(javaCommand, argv[i])strcat((javaCommand), (argv[i])); | |||
1787 | } | |||
1788 | ||||
1789 | AddOption(javaCommand, NULL((void*)0)); | |||
1790 | } | |||
1791 | ||||
1792 | /* | |||
1793 | * JVM would like to know if it's created by a standard Sun launcher, or by | |||
1794 | * user native application, the following property indicates the former. | |||
1795 | */ | |||
1796 | static void SetJavaLauncherProp() { | |||
1797 | AddOption("-Dsun.java.launcher=SUN_STANDARD", NULL((void*)0)); | |||
1798 | } | |||
1799 | ||||
1800 | /* | |||
1801 | * Prints the version information from the java.version and other properties. | |||
1802 | */ | |||
1803 | static void | |||
1804 | PrintJavaVersion(JNIEnv *env, jboolean extraLF) | |||
1805 | { | |||
1806 | jclass ver; | |||
1807 | jmethodID print; | |||
1808 | ||||
1809 | NULL_CHECK(ver = FindBootStrapClass(env, "java/lang/VersionProps"))do { if ((ver = FindBootStrapClass(env, "java/lang/VersionProps" )) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1810 | NULL_CHECK(print = (*env)->GetStaticMethodID(env,do { if ((print = (*env)->GetStaticMethodID(env, ver, (extraLF == 1) ? "println" : "print", "(Z)V" )) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1811 | ver,do { if ((print = (*env)->GetStaticMethodID(env, ver, (extraLF == 1) ? "println" : "print", "(Z)V" )) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1812 | (extraLF == JNI_TRUE) ? "println" : "print",do { if ((print = (*env)->GetStaticMethodID(env, ver, (extraLF == 1) ? "println" : "print", "(Z)V" )) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1813 | "(Z)V"do { if ((print = (*env)->GetStaticMethodID(env, ver, (extraLF == 1) ? "println" : "print", "(Z)V" )) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1814 | )do { if ((print = (*env)->GetStaticMethodID(env, ver, (extraLF == 1) ? "println" : "print", "(Z)V" )) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1815 | )do { if ((print = (*env)->GetStaticMethodID(env, ver, (extraLF == 1) ? "println" : "print", "(Z)V" )) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1816 | ||||
1817 | (*env)->CallStaticVoidMethod(env, ver, print, printTo); | |||
1818 | } | |||
1819 | ||||
1820 | /* | |||
1821 | * Prints all the Java settings, see the java implementation for more details. | |||
1822 | */ | |||
1823 | static void | |||
1824 | ShowSettings(JNIEnv *env, char *optString) | |||
1825 | { | |||
1826 | jmethodID showSettingsID; | |||
1827 | jstring joptString; | |||
1828 | jclass cls = GetLauncherHelperClass(env); | |||
1829 | NULL_CHECK(cls)do { if ((cls) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1830 | NULL_CHECK(showSettingsID = (*env)->GetStaticMethodID(env, cls,do { if ((showSettingsID = (*env)->GetStaticMethodID(env, cls , "showSettings", "(ZLjava/lang/String;JJJ)V")) == ((void*)0) ) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1831 | "showSettings", "(ZLjava/lang/String;JJJ)V"))do { if ((showSettingsID = (*env)->GetStaticMethodID(env, cls , "showSettings", "(ZLjava/lang/String;JJJ)V")) == ((void*)0) ) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1832 | NULL_CHECK(joptString = (*env)->NewStringUTF(env, optString))do { if ((joptString = (*env)->NewStringUTF(env, optString )) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1833 | (*env)->CallStaticVoidMethod(env, cls, showSettingsID, | |||
1834 | USE_STDERR1, | |||
1835 | joptString, | |||
1836 | (jlong)initialHeapSize, | |||
1837 | (jlong)maxHeapSize, | |||
1838 | (jlong)threadStackSize); | |||
1839 | } | |||
1840 | ||||
1841 | /** | |||
1842 | * Show resolved modules | |||
1843 | */ | |||
1844 | static void | |||
1845 | ShowResolvedModules(JNIEnv *env) | |||
1846 | { | |||
1847 | jmethodID showResolvedModulesID; | |||
1848 | jclass cls = GetLauncherHelperClass(env); | |||
1849 | NULL_CHECK(cls)do { if ((cls) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1850 | NULL_CHECK(showResolvedModulesID = (*env)->GetStaticMethodID(env, cls,do { if ((showResolvedModulesID = (*env)->GetStaticMethodID (env, cls, "showResolvedModules", "()V")) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1851 | "showResolvedModules", "()V"))do { if ((showResolvedModulesID = (*env)->GetStaticMethodID (env, cls, "showResolvedModules", "()V")) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1852 | (*env)->CallStaticVoidMethod(env, cls, showResolvedModulesID); | |||
1853 | } | |||
1854 | ||||
1855 | /** | |||
1856 | * List observable modules | |||
1857 | */ | |||
1858 | static void | |||
1859 | ListModules(JNIEnv *env) | |||
1860 | { | |||
1861 | jmethodID listModulesID; | |||
1862 | jclass cls = GetLauncherHelperClass(env); | |||
1863 | NULL_CHECK(cls)do { if ((cls) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1864 | NULL_CHECK(listModulesID = (*env)->GetStaticMethodID(env, cls,do { if ((listModulesID = (*env)->GetStaticMethodID(env, cls , "listModules", "()V")) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1865 | "listModules", "()V"))do { if ((listModulesID = (*env)->GetStaticMethodID(env, cls , "listModules", "()V")) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1866 | (*env)->CallStaticVoidMethod(env, cls, listModulesID); | |||
1867 | } | |||
1868 | ||||
1869 | /** | |||
1870 | * Describe a module | |||
1871 | */ | |||
1872 | static void | |||
1873 | DescribeModule(JNIEnv *env, char *optString) | |||
1874 | { | |||
1875 | jmethodID describeModuleID; | |||
1876 | jstring joptString = NULL((void*)0); | |||
1877 | jclass cls = GetLauncherHelperClass(env); | |||
1878 | NULL_CHECK(cls)do { if ((cls) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1879 | NULL_CHECK(describeModuleID = (*env)->GetStaticMethodID(env, cls,do { if ((describeModuleID = (*env)->GetStaticMethodID(env , cls, "describeModule", "(Ljava/lang/String;)V")) == ((void* )0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1880 | "describeModule", "(Ljava/lang/String;)V"))do { if ((describeModuleID = (*env)->GetStaticMethodID(env , cls, "describeModule", "(Ljava/lang/String;)V")) == ((void* )0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1881 | NULL_CHECK(joptString = NewPlatformString(env, optString))do { if ((joptString = NewPlatformString(env, optString)) == ( (void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1882 | (*env)->CallStaticVoidMethod(env, cls, describeModuleID, joptString); | |||
1883 | } | |||
1884 | ||||
1885 | /* | |||
1886 | * Prints default usage or the Xusage message, see sun.launcher.LauncherHelper.java | |||
1887 | */ | |||
1888 | static void | |||
1889 | PrintUsage(JNIEnv* env, jboolean doXUsage) | |||
1890 | { | |||
1891 | jmethodID initHelp, vmSelect, vmSynonym, printHelp, printXUsageMessage; | |||
1892 | jstring jprogname, vm1, vm2; | |||
1893 | int i; | |||
1894 | jclass cls = GetLauncherHelperClass(env); | |||
1895 | NULL_CHECK(cls)do { if ((cls) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1896 | if (doXUsage) { | |||
1897 | NULL_CHECK(printXUsageMessage = (*env)->GetStaticMethodID(env, cls,do { if ((printXUsageMessage = (*env)->GetStaticMethodID(env , cls, "printXUsageMessage", "(Z)V")) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1898 | "printXUsageMessage", "(Z)V"))do { if ((printXUsageMessage = (*env)->GetStaticMethodID(env , cls, "printXUsageMessage", "(Z)V")) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1899 | (*env)->CallStaticVoidMethod(env, cls, printXUsageMessage, printTo); | |||
1900 | } else { | |||
1901 | NULL_CHECK(initHelp = (*env)->GetStaticMethodID(env, cls,do { if ((initHelp = (*env)->GetStaticMethodID(env, cls, "initHelpMessage" , "(Ljava/lang/String;)V")) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1902 | "initHelpMessage", "(Ljava/lang/String;)V"))do { if ((initHelp = (*env)->GetStaticMethodID(env, cls, "initHelpMessage" , "(Ljava/lang/String;)V")) == ((void*)0)) { JLI_ReportErrorMessage ("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1903 | ||||
1904 | NULL_CHECK(vmSelect = (*env)->GetStaticMethodID(env, cls, "appendVmSelectMessage",do { if ((vmSelect = (*env)->GetStaticMethodID(env, cls, "appendVmSelectMessage" , "(Ljava/lang/String;Ljava/lang/String;)V")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1905 | "(Ljava/lang/String;Ljava/lang/String;)V"))do { if ((vmSelect = (*env)->GetStaticMethodID(env, cls, "appendVmSelectMessage" , "(Ljava/lang/String;Ljava/lang/String;)V")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1906 | ||||
1907 | NULL_CHECK(vmSynonym = (*env)->GetStaticMethodID(env, cls,do { if ((vmSynonym = (*env)->GetStaticMethodID(env, cls, "appendVmSynonymMessage" , "(Ljava/lang/String;Ljava/lang/String;)V")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1908 | "appendVmSynonymMessage",do { if ((vmSynonym = (*env)->GetStaticMethodID(env, cls, "appendVmSynonymMessage" , "(Ljava/lang/String;Ljava/lang/String;)V")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1909 | "(Ljava/lang/String;Ljava/lang/String;)V"))do { if ((vmSynonym = (*env)->GetStaticMethodID(env, cls, "appendVmSynonymMessage" , "(Ljava/lang/String;Ljava/lang/String;)V")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1910 | ||||
1911 | NULL_CHECK(printHelp = (*env)->GetStaticMethodID(env, cls,do { if ((printHelp = (*env)->GetStaticMethodID(env, cls, "printHelpMessage" , "(Z)V")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0) | |||
1912 | "printHelpMessage", "(Z)V"))do { if ((printHelp = (*env)->GetStaticMethodID(env, cls, "printHelpMessage" , "(Z)V")) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1913 | ||||
1914 | NULL_CHECK(jprogname = (*env)->NewStringUTF(env, _program_name))do { if ((jprogname = (*env)->NewStringUTF(env, _program_name )) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1915 | ||||
1916 | /* Initialize the usage message with the usual preamble */ | |||
1917 | (*env)->CallStaticVoidMethod(env, cls, initHelp, jprogname); | |||
1918 | CHECK_EXCEPTION_RETURN()do { if ((*env)->ExceptionOccurred(env)) { return; } } while (0); | |||
1919 | ||||
1920 | ||||
1921 | /* Assemble the other variant part of the usage */ | |||
1922 | for (i=1; i<knownVMsCount; i++) { | |||
1923 | if (knownVMs[i].flag == VM_KNOWN) { | |||
1924 | NULL_CHECK(vm1 = (*env)->NewStringUTF(env, knownVMs[i].name))do { if ((vm1 = (*env)->NewStringUTF(env, knownVMs[i].name )) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1925 | NULL_CHECK(vm2 = (*env)->NewStringUTF(env, knownVMs[i].name+1))do { if ((vm2 = (*env)->NewStringUTF(env, knownVMs[i].name +1)) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1926 | (*env)->CallStaticVoidMethod(env, cls, vmSelect, vm1, vm2); | |||
1927 | CHECK_EXCEPTION_RETURN()do { if ((*env)->ExceptionOccurred(env)) { return; } } while (0); | |||
1928 | } | |||
1929 | } | |||
1930 | for (i=1; i<knownVMsCount; i++) { | |||
1931 | if (knownVMs[i].flag == VM_ALIASED_TO) { | |||
1932 | NULL_CHECK(vm1 = (*env)->NewStringUTF(env, knownVMs[i].name))do { if ((vm1 = (*env)->NewStringUTF(env, knownVMs[i].name )) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1933 | NULL_CHECK(vm2 = (*env)->NewStringUTF(env, knownVMs[i].alias+1))do { if ((vm2 = (*env)->NewStringUTF(env, knownVMs[i].alias +1)) == ((void*)0)) { JLI_ReportErrorMessage("Error: A JNI error has occurred, please check your installation and try again" ); return ; } } while (0); | |||
1934 | (*env)->CallStaticVoidMethod(env, cls, vmSynonym, vm1, vm2); | |||
1935 | CHECK_EXCEPTION_RETURN()do { if ((*env)->ExceptionOccurred(env)) { return; } } while (0); | |||
1936 | } | |||
1937 | } | |||
1938 | ||||
1939 | /* Complete the usage message and print to stderr*/ | |||
1940 | (*env)->CallStaticVoidMethod(env, cls, printHelp, printTo); | |||
1941 | } | |||
1942 | return; | |||
1943 | } | |||
1944 | ||||
1945 | /* | |||
1946 | * Read the jvm.cfg file and fill the knownJVMs[] array. | |||
1947 | * | |||
1948 | * The functionality of the jvm.cfg file is subject to change without | |||
1949 | * notice and the mechanism will be removed in the future. | |||
1950 | * | |||
1951 | * The lexical structure of the jvm.cfg file is as follows: | |||
1952 | * | |||
1953 | * jvmcfg := { vmLine } | |||
1954 | * vmLine := knownLine | |||
1955 | * | aliasLine | |||
1956 | * | warnLine | |||
1957 | * | ignoreLine | |||
1958 | * | errorLine | |||
1959 | * | predicateLine | |||
1960 | * | commentLine | |||
1961 | * knownLine := flag "KNOWN" EOL | |||
1962 | * warnLine := flag "WARN" EOL | |||
1963 | * ignoreLine := flag "IGNORE" EOL | |||
1964 | * errorLine := flag "ERROR" EOL | |||
1965 | * aliasLine := flag "ALIASED_TO" flag EOL | |||
1966 | * predicateLine := flag "IF_SERVER_CLASS" flag EOL | |||
1967 | * commentLine := "#" text EOL | |||
1968 | * flag := "-" identifier | |||
1969 | * | |||
1970 | * The semantics are that when someone specifies a flag on the command line: | |||
1971 | * - if the flag appears on a knownLine, then the identifier is used as | |||
1972 | * the name of the directory holding the JVM library (the name of the JVM). | |||
1973 | * - if the flag appears as the first flag on an aliasLine, the identifier | |||
1974 | * of the second flag is used as the name of the JVM. | |||
1975 | * - if the flag appears on a warnLine, the identifier is used as the | |||
1976 | * name of the JVM, but a warning is generated. | |||
1977 | * - if the flag appears on an ignoreLine, the identifier is recognized as the | |||
1978 | * name of a JVM, but the identifier is ignored and the default vm used | |||
1979 | * - if the flag appears on an errorLine, an error is generated. | |||
1980 | * - if the flag appears as the first flag on a predicateLine, and | |||
1981 | * the machine on which you are running passes the predicate indicated, | |||
1982 | * then the identifier of the second flag is used as the name of the JVM, | |||
1983 | * otherwise the identifier of the first flag is used as the name of the JVM. | |||
1984 | * If no flag is given on the command line, the first vmLine of the jvm.cfg | |||
1985 | * file determines the name of the JVM. | |||
1986 | * PredicateLines are only interpreted on first vmLine of a jvm.cfg file, | |||
1987 | * since they only make sense if someone hasn't specified the name of the | |||
1988 | * JVM on the command line. | |||
1989 | * | |||
1990 | * The intent of the jvm.cfg file is to allow several JVM libraries to | |||
1991 | * be installed in different subdirectories of a single JRE installation, | |||
1992 | * for space-savings and convenience in testing. | |||
1993 | * The intent is explicitly not to provide a full aliasing or predicate | |||
1994 | * mechanism. | |||
1995 | */ | |||
1996 | jint | |||
1997 | ReadKnownVMs(const char *jvmCfgName, jboolean speculative) | |||
1998 | { | |||
1999 | FILE *jvmCfg; | |||
2000 | char line[MAXPATHLEN4096+20]; | |||
2001 | int cnt = 0; | |||
2002 | int lineno = 0; | |||
2003 | jlong start = 0, end = 0; | |||
2004 | int vmType; | |||
2005 | char *tmpPtr; | |||
2006 | char *altVMName = NULL((void*)0); | |||
2007 | char *serverClassVMName = NULL((void*)0); | |||
2008 | static char *whiteSpace = " \t"; | |||
2009 | if (JLI_IsTraceLauncher()) { | |||
2010 | start = CurrentTimeMicros(); | |||
2011 | } | |||
2012 | ||||
2013 | jvmCfg = fopen(jvmCfgName, "r"); | |||
2014 | if (jvmCfg == NULL((void*)0)) { | |||
2015 | if (!speculative) { | |||
2016 | JLI_ReportErrorMessage(CFG_ERROR6"Error: could not open `%s'", jvmCfgName); | |||
2017 | exit(1); | |||
2018 | } else { | |||
2019 | return -1; | |||
2020 | } | |||
2021 | } | |||
2022 | while (fgets(line, sizeof(line), jvmCfg) != NULL((void*)0)) { | |||
2023 | vmType = VM_UNKNOWN; | |||
2024 | lineno++; | |||
2025 | if (line[0] == '#') | |||
2026 | continue; | |||
2027 | if (line[0] != '-') { | |||
2028 | JLI_ReportErrorMessage(CFG_WARN2"Warning: No leading - on line %d of `%s'", lineno, jvmCfgName); | |||
2029 | } | |||
2030 | if (cnt >= knownVMsLimit) { | |||
2031 | GrowKnownVMs(cnt); | |||
2032 | } | |||
2033 | line[JLI_StrLen(line)strlen((line))-1] = '\0'; /* remove trailing newline */ | |||
2034 | tmpPtr = line + JLI_StrCSpn(line, whiteSpace)strcspn((line), (whiteSpace)); | |||
2035 | if (*tmpPtr == 0) { | |||
2036 | JLI_ReportErrorMessage(CFG_WARN3"Warning: Missing VM type on line %d of `%s'", lineno, jvmCfgName); | |||
2037 | } else { | |||
2038 | /* Null-terminate this string for JLI_StringDup below */ | |||
2039 | *tmpPtr++ = 0; | |||
2040 | tmpPtr += JLI_StrSpn(tmpPtr, whiteSpace)strspn((tmpPtr), (whiteSpace)); | |||
2041 | if (*tmpPtr == 0) { | |||
2042 | JLI_ReportErrorMessage(CFG_WARN3"Warning: Missing VM type on line %d of `%s'", lineno, jvmCfgName); | |||
2043 | } else { | |||
2044 | if (!JLI_StrCCmp(tmpPtr, "KNOWN")) { | |||
2045 | vmType = VM_KNOWN; | |||
2046 | } else if (!JLI_StrCCmp(tmpPtr, "ALIASED_TO")) { | |||
2047 | tmpPtr += JLI_StrCSpn(tmpPtr, whiteSpace)strcspn((tmpPtr), (whiteSpace)); | |||
2048 | if (*tmpPtr != 0) { | |||
2049 | tmpPtr += JLI_StrSpn(tmpPtr, whiteSpace)strspn((tmpPtr), (whiteSpace)); | |||
2050 | } | |||
2051 | if (*tmpPtr == 0) { | |||
2052 | JLI_ReportErrorMessage(CFG_WARN3"Warning: Missing VM type on line %d of `%s'", lineno, jvmCfgName); | |||
2053 | } else { | |||
2054 | /* Null terminate altVMName */ | |||
2055 | altVMName = tmpPtr; | |||
2056 | tmpPtr += JLI_StrCSpn(tmpPtr, whiteSpace)strcspn((tmpPtr), (whiteSpace)); | |||
2057 | *tmpPtr = 0; | |||
2058 | vmType = VM_ALIASED_TO; | |||
2059 | } | |||
2060 | } else if (!JLI_StrCCmp(tmpPtr, "WARN")) { | |||
2061 | vmType = VM_WARN; | |||
2062 | } else if (!JLI_StrCCmp(tmpPtr, "IGNORE")) { | |||
2063 | vmType = VM_IGNORE; | |||
2064 | } else if (!JLI_StrCCmp(tmpPtr, "ERROR")) { | |||
2065 | vmType = VM_ERROR; | |||
2066 | } else if (!JLI_StrCCmp(tmpPtr, "IF_SERVER_CLASS")) { | |||
2067 | /* ignored */ | |||
2068 | } else { | |||
2069 | JLI_ReportErrorMessage(CFG_WARN5"Warning: Unknown VM type on line %d of `%s'", lineno, &jvmCfgName[0]); | |||
2070 | vmType = VM_KNOWN; | |||
2071 | } | |||
2072 | } | |||
2073 | } | |||
2074 | ||||
2075 | JLI_TraceLauncher("jvm.cfg[%d] = ->%s<-\n", cnt, line); | |||
2076 | if (vmType != VM_UNKNOWN) { | |||
2077 | knownVMs[cnt].name = JLI_StringDup(line); | |||
2078 | knownVMs[cnt].flag = vmType; | |||
2079 | switch (vmType) { | |||
2080 | default: | |||
2081 | break; | |||
2082 | case VM_ALIASED_TO: | |||
2083 | knownVMs[cnt].alias = JLI_StringDup(altVMName); | |||
2084 | JLI_TraceLauncher(" name: %s vmType: %s alias: %s\n", | |||
2085 | knownVMs[cnt].name, "VM_ALIASED_TO", knownVMs[cnt].alias); | |||
2086 | break; | |||
2087 | } | |||
2088 | cnt++; | |||
2089 | } | |||
2090 | } | |||
2091 | fclose(jvmCfg); | |||
2092 | knownVMsCount = cnt; | |||
2093 | ||||
2094 | if (JLI_IsTraceLauncher()) { | |||
2095 | end = CurrentTimeMicros(); | |||
2096 | printf("%ld micro seconds to parse jvm.cfg\n", (long)(end-start))__printf_chk (2 - 1, "%ld micro seconds to parse jvm.cfg\n", ( long)(end-start)); | |||
2097 | } | |||
2098 | ||||
2099 | return cnt; | |||
2100 | } | |||
2101 | ||||
2102 | ||||
2103 | static void | |||
2104 | GrowKnownVMs(int minimum) | |||
2105 | { | |||
2106 | struct vmdesc* newKnownVMs; | |||
2107 | int newMax; | |||
2108 | ||||
2109 | newMax = (knownVMsLimit == 0 ? INIT_MAX_KNOWN_VMS10 : (2 * knownVMsLimit)); | |||
2110 | if (newMax <= minimum) { | |||
2111 | newMax = minimum; | |||
2112 | } | |||
2113 | newKnownVMs = (struct vmdesc*) JLI_MemAlloc(newMax * sizeof(struct vmdesc)); | |||
2114 | if (knownVMs != NULL((void*)0)) { | |||
2115 | memcpy(newKnownVMs, knownVMs, knownVMsLimit * sizeof(struct vmdesc)); | |||
2116 | } | |||
2117 | JLI_MemFree(knownVMs); | |||
2118 | knownVMs = newKnownVMs; | |||
2119 | knownVMsLimit = newMax; | |||
2120 | } | |||
2121 | ||||
2122 | ||||
2123 | /* Returns index of VM or -1 if not found */ | |||
2124 | static int | |||
2125 | KnownVMIndex(const char* name) | |||
2126 | { | |||
2127 | int i; | |||
2128 | if (JLI_StrCCmp(name, "-J") == 0) name += 2; | |||
2129 | for (i = 0; i < knownVMsCount; i++) { | |||
2130 | if (!JLI_StrCmp(name, knownVMs[i].name)strcmp((name), (knownVMs[i].name))) { | |||
2131 | return i; | |||
2132 | } | |||
2133 | } | |||
2134 | return -1; | |||
2135 | } | |||
2136 | ||||
2137 | static void | |||
2138 | FreeKnownVMs() | |||
2139 | { | |||
2140 | int i; | |||
2141 | for (i = 0; i < knownVMsCount; i++) { | |||
2142 | JLI_MemFree(knownVMs[i].name); | |||
2143 | knownVMs[i].name = NULL((void*)0); | |||
2144 | } | |||
2145 | JLI_MemFree(knownVMs); | |||
2146 | } | |||
2147 | ||||
2148 | /* | |||
2149 | * Displays the splash screen according to the jar file name | |||
2150 | * and image file names stored in environment variables | |||
2151 | */ | |||
2152 | void | |||
2153 | ShowSplashScreen() | |||
2154 | { | |||
2155 | const char *jar_name = getenv(SPLASH_JAR_ENV_ENTRY"_JAVA_SPLASH_JAR"); | |||
2156 | const char *file_name = getenv(SPLASH_FILE_ENV_ENTRY"_JAVA_SPLASH_FILE"); | |||
2157 | int data_size; | |||
2158 | void *image_data = NULL((void*)0); | |||
2159 | float scale_factor = 1; | |||
2160 | char *scaled_splash_name = NULL((void*)0); | |||
2161 | jboolean isImageScaled = JNI_FALSE0; | |||
2162 | size_t maxScaledImgNameLength = 0; | |||
2163 | if (file_name == NULL((void*)0)){ | |||
2164 | return; | |||
2165 | } | |||
2166 | ||||
2167 | if (!DoSplashInit()) { | |||
2168 | goto exit; | |||
2169 | } | |||
2170 | ||||
2171 | maxScaledImgNameLength = DoSplashGetScaledImgNameMaxPstfixLen(file_name); | |||
2172 | ||||
2173 | scaled_splash_name = JLI_MemAlloc( | |||
2174 | maxScaledImgNameLength * sizeof(char)); | |||
2175 | isImageScaled = DoSplashGetScaledImageName(jar_name, file_name, | |||
2176 | &scale_factor, | |||
2177 | scaled_splash_name, maxScaledImgNameLength); | |||
2178 | if (jar_name) { | |||
2179 | ||||
2180 | if (isImageScaled) { | |||
2181 | image_data = JLI_JarUnpackFile( | |||
2182 | jar_name, scaled_splash_name, &data_size); | |||
2183 | } | |||
2184 | ||||
2185 | if (!image_data) { | |||
2186 | scale_factor = 1; | |||
2187 | image_data = JLI_JarUnpackFile( | |||
2188 | jar_name, file_name, &data_size); | |||
2189 | } | |||
2190 | if (image_data) { | |||
2191 | DoSplashSetScaleFactor(scale_factor); | |||
2192 | DoSplashLoadMemory(image_data, data_size); | |||
2193 | JLI_MemFree(image_data); | |||
2194 | } else { | |||
2195 | DoSplashClose(); | |||
2196 | } | |||
2197 | } else { | |||
2198 | if (isImageScaled) { | |||
2199 | DoSplashSetScaleFactor(scale_factor); | |||
2200 | DoSplashLoadFile(scaled_splash_name); | |||
2201 | } else { | |||
2202 | DoSplashLoadFile(file_name); | |||
2203 | } | |||
2204 | } | |||
2205 | JLI_MemFree(scaled_splash_name); | |||
2206 | ||||
2207 | DoSplashSetFileJarName(file_name, jar_name); | |||
2208 | ||||
2209 | exit: | |||
2210 | /* | |||
2211 | * Done with all command line processing and potential re-execs so | |||
2212 | * clean up the environment. | |||
2213 | */ | |||
2214 | (void)UnsetEnv(ENV_ENTRY"_JAVA_VERSION_SET"); | |||
2215 | (void)UnsetEnv(SPLASH_FILE_ENV_ENTRY"_JAVA_SPLASH_FILE"); | |||
2216 | (void)UnsetEnv(SPLASH_JAR_ENV_ENTRY"_JAVA_SPLASH_JAR"); | |||
2217 | ||||
2218 | JLI_MemFree(splash_jar_entry); | |||
2219 | JLI_MemFree(splash_file_entry); | |||
2220 | ||||
2221 | } | |||
2222 | ||||
2223 | static const char* GetFullVersion() | |||
2224 | { | |||
2225 | return _fVersion; | |||
2226 | } | |||
2227 | ||||
2228 | static const char* GetProgramName() | |||
2229 | { | |||
2230 | return _program_name; | |||
2231 | } | |||
2232 | ||||
2233 | static const char* GetLauncherName() | |||
2234 | { | |||
2235 | return _launcher_name; | |||
2236 | } | |||
2237 | ||||
2238 | static jboolean IsJavaArgs() | |||
2239 | { | |||
2240 | return _is_java_args; | |||
2241 | } | |||
2242 | ||||
2243 | static jboolean | |||
2244 | IsWildCardEnabled() | |||
2245 | { | |||
2246 | return _wc_enabled; | |||
2247 | } | |||
2248 | ||||
2249 | int | |||
2250 | ContinueInNewThread(InvocationFunctions* ifn, jlong threadStackSize, | |||
2251 | int argc, char **argv, | |||
2252 | int mode, char *what, int ret) | |||
2253 | { | |||
2254 | if (threadStackSize == 0) { | |||
2255 | /* | |||
2256 | * If the user hasn't specified a non-zero stack size ask the JVM for its default. | |||
2257 | * A returned 0 means 'use the system default' for a platform, e.g., Windows. | |||
2258 | * Note that HotSpot no longer supports JNI_VERSION_1_1 but it will | |||
2259 | * return its default stack size through the init args structure. | |||
2260 | */ | |||
2261 | struct JDK1_1InitArgs args1_1; | |||
2262 | memset((void*)&args1_1, 0, sizeof(args1_1)); | |||
2263 | args1_1.version = JNI_VERSION_1_10x00010001; | |||
2264 | ifn->GetDefaultJavaVMInitArgs(&args1_1); /* ignore return value */ | |||
2265 | if (args1_1.javaStackSize > 0) { | |||
2266 | threadStackSize = args1_1.javaStackSize; | |||
2267 | } | |||
2268 | } | |||
2269 | ||||
2270 | { /* Create a new thread to create JVM and invoke main method */ | |||
2271 | JavaMainArgs args; | |||
2272 | int rslt; | |||
2273 | ||||
2274 | args.argc = argc; | |||
2275 | args.argv = argv; | |||
2276 | args.mode = mode; | |||
2277 | args.what = what; | |||
2278 | args.ifn = *ifn; | |||
2279 | ||||
2280 | rslt = CallJavaMainInNewThread(threadStackSize, (void*)&args); | |||
2281 | /* If the caller has deemed there is an error we | |||
2282 | * simply return that, otherwise we return the value of | |||
2283 | * the callee | |||
2284 | */ | |||
2285 | return (ret != 0) ? ret : rslt; | |||
2286 | } | |||
2287 | } | |||
2288 | ||||
2289 | static void | |||
2290 | DumpState() | |||
2291 | { | |||
2292 | if (!JLI_IsTraceLauncher()) return ; | |||
2293 | printf("Launcher state:\n")__printf_chk (2 - 1, "Launcher state:\n"); | |||
2294 | printf("\tFirst application arg index: %d\n", JLI_GetAppArgIndex())__printf_chk (2 - 1, "\tFirst application arg index: %d\n", JLI_GetAppArgIndex ()); | |||
2295 | printf("\tdebug:%s\n", (JLI_IsTraceLauncher() == JNI_TRUE) ? "on" : "off")__printf_chk (2 - 1, "\tdebug:%s\n", (JLI_IsTraceLauncher() == 1) ? "on" : "off"); | |||
2296 | printf("\tjavargs:%s\n", (_is_java_args == JNI_TRUE) ? "on" : "off")__printf_chk (2 - 1, "\tjavargs:%s\n", (_is_java_args == 1) ? "on" : "off"); | |||
2297 | printf("\tprogram name:%s\n", GetProgramName())__printf_chk (2 - 1, "\tprogram name:%s\n", GetProgramName()); | |||
2298 | printf("\tlauncher name:%s\n", GetLauncherName())__printf_chk (2 - 1, "\tlauncher name:%s\n", GetLauncherName( )); | |||
2299 | printf("\tjavaw:%s\n", (IsJavaw() == JNI_TRUE) ? "on" : "off")__printf_chk (2 - 1, "\tjavaw:%s\n", (IsJavaw() == 1) ? "on" : "off"); | |||
2300 | printf("\tfullversion:%s\n", GetFullVersion())__printf_chk (2 - 1, "\tfullversion:%s\n", GetFullVersion()); | |||
2301 | } | |||
2302 | ||||
2303 | /* | |||
2304 | * A utility procedure to always print to stderr | |||
2305 | */ | |||
2306 | JNIEXPORT__attribute__((visibility("default"))) void JNICALL | |||
2307 | JLI_ReportMessage(const char* fmt, ...) | |||
2308 | { | |||
2309 | va_list vl; | |||
2310 | va_start(vl, fmt)__builtin_va_start(vl, fmt); | |||
2311 | vfprintf(stderrstderr, fmt, vl); | |||
2312 | fprintf(stderr, "\n")__fprintf_chk (stderr, 2 - 1, "\n"); | |||
2313 | va_end(vl)__builtin_va_end(vl); | |||
2314 | } | |||
2315 | ||||
2316 | /* | |||
2317 | * A utility procedure to always print to stdout | |||
2318 | */ | |||
2319 | void | |||
2320 | JLI_ShowMessage(const char* fmt, ...) | |||
2321 | { | |||
2322 | va_list vl; | |||
2323 | va_start(vl, fmt)__builtin_va_start(vl, fmt); | |||
2324 | vfprintf(stdoutstdout, fmt, vl); | |||
2325 | fprintf(stdout, "\n")__fprintf_chk (stdout, 2 - 1, "\n"); | |||
2326 | va_end(vl)__builtin_va_end(vl); | |||
2327 | } |