Bug Summary

File:jdk/src/java.base/share/native/libjli/java.c
Warning:line 781, column 28
Although the value stored to 'jvmidx' is used in the enclosing expression, the value is never actually read from 'jvmidx'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name java.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libjava -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -D LIBC=gnu -D _GNU_SOURCE -D _REENTRANT -D _LARGEFILE64_SOURCE -D LINUX -D DEBUG -D _LITTLE_ENDIAN -D ARCH="amd64" -D amd64 -D _LP64=1 -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libjli -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjli -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/java.base -D _FORTIFY_SOURCE=2 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wno-unused -Wno-unused-function -Wno-implicit-fallthrough -std=c99 -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c /home/daniel/Projects/java/jdk/src/java.base/share/native/libjli/java.c
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
68static jboolean printVersion = JNI_FALSE0; /* print and exit */
69static jboolean showVersion = JNI_FALSE0; /* print but continue */
70static jboolean printUsage = JNI_FALSE0; /* print and exit*/
71static jboolean printTo = USE_STDERR1; /* where to print version/usage */
72static jboolean printXUsage = JNI_FALSE0; /* print and exit*/
73static jboolean dryRun = JNI_FALSE0; /* initialize VM and exit */
74static char *showSettings = NULL((void*)0); /* print but continue */
75static jboolean showResolvedModules = JNI_FALSE0;
76static jboolean listModules = JNI_FALSE0;
77static char *describeModule = NULL((void*)0);
78static jboolean validateModules = JNI_FALSE0;
79
80static const char *_program_name;
81static const char *_launcher_name;
82static jboolean _is_java_args = JNI_FALSE0;
83static jboolean _have_classpath = JNI_FALSE0;
84static const char *_fVersion;
85static 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 */
93static char* splash_file_entry = NULL((void*)0);
94static char* splash_jar_entry = NULL((void*)0);
95
96/*
97 * List of VM options to be specified when the VM is created.
98 */
99static JavaVMOption *options;
100static int numOptions, maxOptions;
101
102/*
103 * Prototypes for functions internal to launcher.
104 */
105static const char* GetFullVersion();
106static jboolean IsJavaArgs();
107static void SetJavaLauncherProp();
108static void SetClassPath(const char *s);
109static void SetMainModule(const char *s);
110static void SelectVersion(int argc, char **argv, char **main_class);
111static jboolean ParseArguments(int *pargc, char ***pargv,
112 int *pmode, char **pwhat,
113 int *pret, const char *jrepath);
114static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv,
115 InvocationFunctions *ifn);
116static jstring NewPlatformString(JNIEnv *env, char *s);
117static jclass LoadMainClass(JNIEnv *env, int mode, char *name);
118static jclass GetApplicationClass(JNIEnv *env);
119
120static void TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv);
121static jboolean AddApplicationOptions(int cpathc, const char **cpathv);
122static void SetApplicationClassPath(const char**);
123
124static void PrintJavaVersion(JNIEnv *env, jboolean extraLF);
125static void PrintUsage(JNIEnv* env, jboolean doXUsage);
126static void ShowSettings(JNIEnv* env, char *optString);
127static void ShowResolvedModules(JNIEnv* env);
128static void ListModules(JNIEnv* env);
129static void DescribeModule(JNIEnv* env, char* optString);
130static jboolean ValidateModules(JNIEnv* env);
131
132static void SetPaths(int argc, char **argv);
133
134static void DumpState();
135
136enum 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
145static int GetOpt(int *pargc, char ***pargv, char **poption, char **pvalue);
146static 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 */
152enum 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
162struct vmdesc {
163 char *name;
164 int flag;
165 char *alias;
166 char *server_class;
167};
168static struct vmdesc *knownVMs = NULL((void*)0);
169static int knownVMsCount = 0;
170static int knownVMsLimit = 0;
171
172static void GrowKnownVMs(int minimum);
173static int KnownVMIndex(const char* name);
174static void FreeKnownVMs();
175static 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 */
207static jlong threadStackSize = 0; /* stack size of the new thread */
208static jlong maxHeapSize = 0; /* max heap size */
209static 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 */
224JNIEXPORT__attribute__((visibility("default"))) int JNICALL
225JLI_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
388int
389JavaMain(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 */
559static jboolean
560IsClassPathOption(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 */
569static jboolean
570IsLauncherMainOption(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 */
578static jboolean
579IsLauncherOption(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 */
592static jboolean
593IsModuleOption(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
606static jboolean
607IsLongFormModuleOption(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 */
621jboolean
622IsWhiteSpaceOption(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 */
632static int
633checkMode(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 */
644static 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 */
656char *
657CheckJvmType(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;
Although the value stored to 'jvmidx' is used in the enclosing expression, the value is never actually read from 'jvmidx'
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()" */
798static int
799parse_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 */
837void
838AddOption(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
892static void
893SetClassPath(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
919static void
920AddLongFormOption(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
932static void
933SetMainModule(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 */
962static void
963SelectVersion(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 */
1123static jboolean
1124IsOptionWithArgument(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 */
1140static int
1141GetOpt(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 */
1202static jboolean
1203ParseArguments(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 == LM_UNKNOWN) {
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 */
1435static jboolean
1436InitializeJVM(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
1464static jclass helperClass = NULL((void*)0);
1465
1466jclass
1467GetLauncherHelperClass(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
1476static jmethodID makePlatformStringMID = NULL((void*)0);
1477/*
1478 * Returns a new Java string object for the specified platform string.
1479 */
1480static jstring
1481NewPlatformString(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 */
1513jobjectArray
1514NewPlatformStringArray(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 */
1536static jclass
1537LoadMainClass(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
1565static jclass
1566GetApplicationClass(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
1581static 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 */
1613static void
1614TranslateApplicationArgs(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 */
1687static jboolean
1688AddApplicationOptions(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 */
1746void
1747SetJavaCommandLineProp(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 */
1796static 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 */
1803static void
1804PrintJavaVersion(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 */
1823static void
1824ShowSettings(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 */
1844static void
1845ShowResolvedModules(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 */
1858static void
1859ListModules(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 */
1872static void
1873DescribeModule(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 */
1888static void
1889PrintUsage(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 */
1996jint
1997ReadKnownVMs(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
2103static void
2104GrowKnownVMs(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 */
2124static int
2125KnownVMIndex(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
2137static void
2138FreeKnownVMs()
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 */
2152void
2153ShowSplashScreen()
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
2223static const char* GetFullVersion()
2224{
2225 return _fVersion;
2226}
2227
2228static const char* GetProgramName()
2229{
2230 return _program_name;
2231}
2232
2233static const char* GetLauncherName()
2234{
2235 return _launcher_name;
2236}
2237
2238static jboolean IsJavaArgs()
2239{
2240 return _is_java_args;
2241}
2242
2243static jboolean
2244IsWildCardEnabled()
2245{
2246 return _wc_enabled;
2247}
2248
2249int
2250ContinueInNewThread(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
2289static void
2290DumpState()
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 */
2306JNIEXPORT__attribute__((visibility("default"))) void JNICALL
2307JLI_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 */
2319void
2320JLI_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}