154 * \|/
155 * Paths have well known
156 * jvm paths ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
157 * YES YES --> Continue
158 * |
159 * |
160 * \|/
161 * Does libjvm.so exist
162 * in any of them ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
163 * YES YES --> Continue
164 * |
165 * |
166 * \|/
167 * Re-exec / Spawn
168 * |
169 * |
170 * \|/
171 * Main
172 */
173
174 #define GetArch() GetArchPath(CURRENT_DATA_MODEL)
175
176 /* Store the name of the executable once computed */
177 static char *execname = NULL;
178
179 /*
180 * execname accessor from other parts of platform dependent logic
181 */
182 const char *
183 GetExecName() {
184 return execname;
185 }
186
187 const char *
188 GetArchPath(int nbits)
189 {
190 switch(nbits) {
191 default:
192 return LIBARCHNAME;
193 }
194 }
195
196
197 /*
198 * Exports the JNI interface from libjli
199 *
200 * This allows client code to link against the .jre/.jdk bundles,
201 * and not worry about trying to pick a HotSpot to link against.
202 *
203 * Switching architectures is unsupported, since client code has
204 * made that choice before the JVM was requested.
205 */
206
207 static InvocationFunctions *sExportedJNIFunctions = NULL;
208 static char *sPreferredJVMType = NULL;
209
210 static InvocationFunctions *GetExportedJNIFunctions() {
211 if (sExportedJNIFunctions != NULL) return sExportedJNIFunctions;
212
213 char jrePath[PATH_MAX];
214 jboolean gotJREPath = GetJREPath(jrePath, sizeof(jrePath), GetArch(), JNI_FALSE);
215 if (!gotJREPath) {
216 JLI_ReportErrorMessage("Failed to GetJREPath()");
217 return NULL;
218 }
219
220 char *preferredJVM = sPreferredJVMType;
221 if (preferredJVM == NULL) {
222 #if defined(__i386__)
223 preferredJVM = "client";
224 #elif defined(__x86_64__)
225 preferredJVM = "server";
226 #else
227 #error "Unknown architecture - needs definition"
228 #endif
229 }
230
231 char jvmPath[PATH_MAX];
232 jboolean gotJVMPath = GetJVMPath(jrePath, preferredJVM, jvmPath, sizeof(jvmPath), GetArch(), CURRENT_DATA_MODEL);
233 if (!gotJVMPath) {
234 JLI_ReportErrorMessage("Failed to GetJVMPath()");
235 return NULL;
236 }
237
238 InvocationFunctions *fxns = malloc(sizeof(InvocationFunctions));
239 jboolean vmLoaded = LoadJavaVM(jvmPath, fxns);
240 if (!vmLoaded) {
241 JLI_ReportErrorMessage("Failed to LoadJavaVM()");
242 return NULL;
243 }
244
245 return sExportedJNIFunctions = fxns;
246 }
247
248 #ifndef STATIC_BUILD
249
250 JNIEXPORT jint JNICALL
251 JNI_GetDefaultJavaVMInitArgs(void *args) {
252 InvocationFunctions *ifn = GetExportedJNIFunctions();
373 CreateExecutionEnvironment(int *pargc, char ***pargv,
374 char jrepath[], jint so_jrepath,
375 char jvmpath[], jint so_jvmpath,
376 char jvmcfg[], jint so_jvmcfg) {
377 /*
378 * First, determine if we are running the desired data model. If we
379 * are running the desired data model, all the error messages
380 * associated with calling GetJREPath, ReadKnownVMs, etc. should be
381 * output. However, if we are not running the desired data model,
382 * some of the errors should be suppressed since it is more
383 * informative to issue an error message based on whether or not the
384 * os/processor combination has dual mode capabilities.
385 */
386 jboolean jvmpathExists;
387
388 /* Compute/set the name of the executable */
389 SetExecname(*pargv);
390
391 /* Check data model flags, and exec process, if needed */
392 {
393 char *arch = (char *)GetArch(); /* like sparc or sparcv9 */
394 char * jvmtype = NULL;
395 int argc = *pargc;
396 char **argv = *pargv;
397 int running = CURRENT_DATA_MODEL;
398
399 int wanted = running; /* What data mode is being
400 asked for? Current model is
401 fine unless another model
402 is asked for */
403
404 char** newargv = NULL;
405 int newargc = 0;
406
407 /*
408 * Starting in 1.5, all unix platforms accept the -d32 and -d64
409 * options. On platforms where only one data-model is supported
410 * (e.g. ia-64 Linux), using the flag for the other data model is
411 * an error and will terminate the program.
412 */
413
445 }
446
447 /* copy rest of args [i .. argc) */
448 while (i < argc) {
449 newargv[newargc++] = argv[i++];
450 }
451 newargv[newargc] = NULL;
452
453 /*
454 * newargv has all proper arguments here
455 */
456
457 argc = newargc;
458 argv = newargv;
459 }
460
461 /* If the data model is not changing, it is an error if the
462 jvmpath does not exist */
463 if (wanted == running) {
464 /* Find out where the JRE is that we will be using. */
465 if (!GetJREPath(jrepath, so_jrepath, arch, JNI_FALSE) ) {
466 JLI_ReportErrorMessage(JRE_ERROR1);
467 exit(2);
468 }
469 JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%s%sjvm.cfg",
470 jrepath, FILESEP, FILESEP, "", "");
471 /* Find the specified JVM type */
472 if (ReadKnownVMs(jvmcfg, JNI_FALSE) < 1) {
473 JLI_ReportErrorMessage(CFG_ERROR7);
474 exit(1);
475 }
476
477 jvmpath[0] = '\0';
478 jvmtype = CheckJvmType(pargc, pargv, JNI_FALSE);
479 if (JLI_StrCmp(jvmtype, "ERROR") == 0) {
480 JLI_ReportErrorMessage(CFG_ERROR9);
481 exit(4);
482 }
483
484 if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, arch, wanted)) {
485 JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath);
486 exit(4);
487 }
488
489 /*
490 * Mac OS X requires the Cocoa event loop to be run on the "main"
491 * thread. Spawn off a new thread to run main() and pass
492 * this thread off to the Cocoa event loop.
493 */
494 MacOSXStartup(argc, argv);
495
496 /*
497 * we seem to have everything we need, so without further ado
498 * we return back, otherwise proceed to set the environment.
499 */
500 return;
501 } else { /* do the same speculatively or exit */
502 #if defined(DUAL_MODE)
503 if (running != wanted) {
504 /* Find out where the JRE is that we will be using. */
505 if (!GetJREPath(jrepath, so_jrepath, GetArchPath(wanted), JNI_TRUE)) {
506 /* give up and let other code report error message */
507 JLI_ReportErrorMessage(JRE_ERROR2, wanted);
508 exit(1);
509 }
510 JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%s%sjvm.cfg",
511 jrepath, FILESEP, FILESEP, "", "");
512 /*
513 * Read in jvm.cfg for target data model and process vm
514 * selection options.
515 */
516 if (ReadKnownVMs(jvmcfg, JNI_TRUE) < 1) {
517 /* give up and let other code report error message */
518 JLI_ReportErrorMessage(JRE_ERROR2, wanted);
519 exit(1);
520 }
521 jvmpath[0] = '\0';
522 jvmtype = CheckJvmType(pargc, pargv, JNI_TRUE);
523 if (JLI_StrCmp(jvmtype, "ERROR") == 0) {
524 JLI_ReportErrorMessage(CFG_ERROR9);
525 exit(4);
526 }
527
528 /* exec child can do error checking on the existence of the path */
529 jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, GetArchPath(wanted), wanted);
530 }
531 #else /* ! DUAL_MODE */
532 JLI_ReportErrorMessage(JRE_ERROR2, wanted);
533 exit(1);
534 #endif /* DUAL_MODE */
535 }
536 {
537 char *newexec = execname;
538 JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
539 (void) fflush(stdout);
540 (void) fflush(stderr);
541 /*
542 * Use posix_spawn() instead of execv() on Mac OS X.
543 * This allows us to choose which architecture the child process
544 * should run as.
545 */
546 {
547 posix_spawnattr_t attr;
548 size_t unused_size;
549 pid_t unused_pid;
562
563 posix_spawn(&unused_pid, newexec, NULL, &attr, argv, environ);
564 }
565 JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
566
567 #if defined(DUAL_MODE)
568 if (running != wanted) {
569 JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
570 }
571 #endif /* DUAL_MODE */
572 }
573 exit(1);
574 }
575 }
576
577 /*
578 * VM choosing is done by the launcher (java.c).
579 */
580 static jboolean
581 GetJVMPath(const char *jrepath, const char *jvmtype,
582 char *jvmpath, jint jvmpathsize, const char * arch, int bitsWanted)
583 {
584 struct stat s;
585
586 if (JLI_StrChr(jvmtype, '/')) {
587 JLI_Snprintf(jvmpath, jvmpathsize, "%s/" JVM_DLL, jvmtype);
588 } else {
589 /*
590 * macosx client library is built thin, i386 only.
591 * 64 bit client requests must load server library
592 */
593 const char *jvmtypeUsed = ((bitsWanted == 64) && (strcmp(jvmtype, "client") == 0)) ? "server" : jvmtype;
594 JLI_Snprintf(jvmpath, jvmpathsize, "%s/lib/%s/" JVM_DLL, jrepath, jvmtypeUsed);
595 }
596
597 JLI_TraceLauncher("Does `%s' exist ... ", jvmpath);
598
599 #ifdef STATIC_BUILD
600 return JNI_TRUE;
601 #else
602 if (stat(jvmpath, &s) == 0) {
603 JLI_TraceLauncher("yes.\n");
604 return JNI_TRUE;
605 } else {
606 JLI_TraceLauncher("no.\n");
607 return JNI_FALSE;
608 }
609 #endif
610 }
611
612 /*
613 * Find path to JRE based on .exe's location or registry settings.
614 */
615 static jboolean
616 GetJREPath(char *path, jint pathsize, const char * arch, jboolean speculative)
617 {
618 char libjava[MAXPATHLEN];
619
620 if (GetApplicationHome(path, pathsize)) {
621 /* Is JRE co-located with the application? */
622 #ifdef STATIC_BUILD
623 char jvm_cfg[MAXPATHLEN];
624 JLI_Snprintf(jvm_cfg, sizeof(jvm_cfg), "%s/lib/jvm.cfg", path);
625 if (access(jvm_cfg, F_OK) == 0) {
626 return JNI_TRUE;
627 }
628 #else
629 JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path);
630 if (access(libjava, F_OK) == 0) {
631 return JNI_TRUE;
632 }
633 #endif
634 /* ensure storage for path + /jre + NULL */
635 if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) {
636 JLI_TraceLauncher("Insufficient space to store JRE path\n");
824 if (OSXAPP_SetJavaVM) {
825 OSXAPP_SetJavaVM(jvm);
826 } else {
827 jvm = NULL;
828 }
829 }
830
831 dlclose(handle);
832 }
833
834 return jvm;
835 }
836
837 static const char* SPLASHSCREEN_SO = JNI_LIB_NAME("splashscreen");
838
839 static void* hSplashLib = NULL;
840
841 void* SplashProcAddress(const char* name) {
842 if (!hSplashLib) {
843 char jrePath[PATH_MAX];
844 if (!GetJREPath(jrePath, sizeof(jrePath), GetArch(), JNI_FALSE)) {
845 JLI_ReportErrorMessage(JRE_ERROR1);
846 return NULL;
847 }
848
849 char splashPath[PATH_MAX];
850 const int ret = JLI_Snprintf(splashPath, sizeof(splashPath),
851 "%s/lib/%s", jrePath, SPLASHSCREEN_SO);
852 if (ret >= (int)sizeof(splashPath)) {
853 JLI_ReportErrorMessage(JRE_ERROR11);
854 return NULL;
855 }
856 if (ret < 0) {
857 JLI_ReportErrorMessage(JRE_ERROR13);
858 return NULL;
859 }
860
861 hSplashLib = dlopen(splashPath, RTLD_LAZY | RTLD_GLOBAL);
862 // It's OK if dlopen() fails. The splash screen library binary file
863 // might have been stripped out from the JRE image to reduce its size
864 // (e.g. on embedded platforms).
|
154 * \|/
155 * Paths have well known
156 * jvm paths ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
157 * YES YES --> Continue
158 * |
159 * |
160 * \|/
161 * Does libjvm.so exist
162 * in any of them ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
163 * YES YES --> Continue
164 * |
165 * |
166 * \|/
167 * Re-exec / Spawn
168 * |
169 * |
170 * \|/
171 * Main
172 */
173
174 /* Store the name of the executable once computed */
175 static char *execname = NULL;
176
177 /*
178 * execname accessor from other parts of platform dependent logic
179 */
180 const char *
181 GetExecName() {
182 return execname;
183 }
184
185 /*
186 * Exports the JNI interface from libjli
187 *
188 * This allows client code to link against the .jre/.jdk bundles,
189 * and not worry about trying to pick a HotSpot to link against.
190 *
191 * Switching architectures is unsupported, since client code has
192 * made that choice before the JVM was requested.
193 */
194
195 static InvocationFunctions *sExportedJNIFunctions = NULL;
196 static char *sPreferredJVMType = NULL;
197
198 static InvocationFunctions *GetExportedJNIFunctions() {
199 if (sExportedJNIFunctions != NULL) return sExportedJNIFunctions;
200
201 char jrePath[PATH_MAX];
202 jboolean gotJREPath = GetJREPath(jrePath, sizeof(jrePath), JNI_FALSE);
203 if (!gotJREPath) {
204 JLI_ReportErrorMessage("Failed to GetJREPath()");
205 return NULL;
206 }
207
208 char *preferredJVM = sPreferredJVMType;
209 if (preferredJVM == NULL) {
210 #if defined(__i386__)
211 preferredJVM = "client";
212 #elif defined(__x86_64__)
213 preferredJVM = "server";
214 #else
215 #error "Unknown architecture - needs definition"
216 #endif
217 }
218
219 char jvmPath[PATH_MAX];
220 jboolean gotJVMPath = GetJVMPath(jrePath, preferredJVM, jvmPath, sizeof(jvmPath), CURRENT_DATA_MODEL);
221 if (!gotJVMPath) {
222 JLI_ReportErrorMessage("Failed to GetJVMPath()");
223 return NULL;
224 }
225
226 InvocationFunctions *fxns = malloc(sizeof(InvocationFunctions));
227 jboolean vmLoaded = LoadJavaVM(jvmPath, fxns);
228 if (!vmLoaded) {
229 JLI_ReportErrorMessage("Failed to LoadJavaVM()");
230 return NULL;
231 }
232
233 return sExportedJNIFunctions = fxns;
234 }
235
236 #ifndef STATIC_BUILD
237
238 JNIEXPORT jint JNICALL
239 JNI_GetDefaultJavaVMInitArgs(void *args) {
240 InvocationFunctions *ifn = GetExportedJNIFunctions();
361 CreateExecutionEnvironment(int *pargc, char ***pargv,
362 char jrepath[], jint so_jrepath,
363 char jvmpath[], jint so_jvmpath,
364 char jvmcfg[], jint so_jvmcfg) {
365 /*
366 * First, determine if we are running the desired data model. If we
367 * are running the desired data model, all the error messages
368 * associated with calling GetJREPath, ReadKnownVMs, etc. should be
369 * output. However, if we are not running the desired data model,
370 * some of the errors should be suppressed since it is more
371 * informative to issue an error message based on whether or not the
372 * os/processor combination has dual mode capabilities.
373 */
374 jboolean jvmpathExists;
375
376 /* Compute/set the name of the executable */
377 SetExecname(*pargv);
378
379 /* Check data model flags, and exec process, if needed */
380 {
381 char * jvmtype = NULL;
382 int argc = *pargc;
383 char **argv = *pargv;
384 int running = CURRENT_DATA_MODEL;
385
386 int wanted = running; /* What data mode is being
387 asked for? Current model is
388 fine unless another model
389 is asked for */
390
391 char** newargv = NULL;
392 int newargc = 0;
393
394 /*
395 * Starting in 1.5, all unix platforms accept the -d32 and -d64
396 * options. On platforms where only one data-model is supported
397 * (e.g. ia-64 Linux), using the flag for the other data model is
398 * an error and will terminate the program.
399 */
400
432 }
433
434 /* copy rest of args [i .. argc) */
435 while (i < argc) {
436 newargv[newargc++] = argv[i++];
437 }
438 newargv[newargc] = NULL;
439
440 /*
441 * newargv has all proper arguments here
442 */
443
444 argc = newargc;
445 argv = newargv;
446 }
447
448 /* If the data model is not changing, it is an error if the
449 jvmpath does not exist */
450 if (wanted == running) {
451 /* Find out where the JRE is that we will be using. */
452 if (!GetJREPath(jrepath, so_jrepath, JNI_FALSE) ) {
453 JLI_ReportErrorMessage(JRE_ERROR1);
454 exit(2);
455 }
456 JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%s%sjvm.cfg",
457 jrepath, FILESEP, FILESEP, "", "");
458 /* Find the specified JVM type */
459 if (ReadKnownVMs(jvmcfg, JNI_FALSE) < 1) {
460 JLI_ReportErrorMessage(CFG_ERROR7);
461 exit(1);
462 }
463
464 jvmpath[0] = '\0';
465 jvmtype = CheckJvmType(pargc, pargv, JNI_FALSE);
466 if (JLI_StrCmp(jvmtype, "ERROR") == 0) {
467 JLI_ReportErrorMessage(CFG_ERROR9);
468 exit(4);
469 }
470
471 if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, wanted)) {
472 JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath);
473 exit(4);
474 }
475
476 /*
477 * Mac OS X requires the Cocoa event loop to be run on the "main"
478 * thread. Spawn off a new thread to run main() and pass
479 * this thread off to the Cocoa event loop.
480 */
481 MacOSXStartup(argc, argv);
482
483 /*
484 * we seem to have everything we need, so without further ado
485 * we return back, otherwise proceed to set the environment.
486 */
487 return;
488 } else { /* do the same speculatively or exit */
489 #if defined(DUAL_MODE)
490 if (running != wanted) {
491 /* Find out where the JRE is that we will be using. */
492 if (!GetJREPath(jrepath, so_jrepath, JNI_TRUE)) {
493 /* give up and let other code report error message */
494 JLI_ReportErrorMessage(JRE_ERROR2, wanted);
495 exit(1);
496 }
497 JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%s%sjvm.cfg",
498 jrepath, FILESEP, FILESEP, "", "");
499 /*
500 * Read in jvm.cfg for target data model and process vm
501 * selection options.
502 */
503 if (ReadKnownVMs(jvmcfg, JNI_TRUE) < 1) {
504 /* give up and let other code report error message */
505 JLI_ReportErrorMessage(JRE_ERROR2, wanted);
506 exit(1);
507 }
508 jvmpath[0] = '\0';
509 jvmtype = CheckJvmType(pargc, pargv, JNI_TRUE);
510 if (JLI_StrCmp(jvmtype, "ERROR") == 0) {
511 JLI_ReportErrorMessage(CFG_ERROR9);
512 exit(4);
513 }
514
515 /* exec child can do error checking on the existence of the path */
516 jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, wanted);
517 }
518 #else /* ! DUAL_MODE */
519 JLI_ReportErrorMessage(JRE_ERROR2, wanted);
520 exit(1);
521 #endif /* DUAL_MODE */
522 }
523 {
524 char *newexec = execname;
525 JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
526 (void) fflush(stdout);
527 (void) fflush(stderr);
528 /*
529 * Use posix_spawn() instead of execv() on Mac OS X.
530 * This allows us to choose which architecture the child process
531 * should run as.
532 */
533 {
534 posix_spawnattr_t attr;
535 size_t unused_size;
536 pid_t unused_pid;
549
550 posix_spawn(&unused_pid, newexec, NULL, &attr, argv, environ);
551 }
552 JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
553
554 #if defined(DUAL_MODE)
555 if (running != wanted) {
556 JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
557 }
558 #endif /* DUAL_MODE */
559 }
560 exit(1);
561 }
562 }
563
564 /*
565 * VM choosing is done by the launcher (java.c).
566 */
567 static jboolean
568 GetJVMPath(const char *jrepath, const char *jvmtype,
569 char *jvmpath, jint jvmpathsize, int bitsWanted)
570 {
571 struct stat s;
572
573 if (JLI_StrChr(jvmtype, '/')) {
574 JLI_Snprintf(jvmpath, jvmpathsize, "%s/" JVM_DLL, jvmtype);
575 } else {
576 /*
577 * macosx client library is built thin, i386 only.
578 * 64 bit client requests must load server library
579 */
580 const char *jvmtypeUsed = ((bitsWanted == 64) && (strcmp(jvmtype, "client") == 0)) ? "server" : jvmtype;
581 JLI_Snprintf(jvmpath, jvmpathsize, "%s/lib/%s/" JVM_DLL, jrepath, jvmtypeUsed);
582 }
583
584 JLI_TraceLauncher("Does `%s' exist ... ", jvmpath);
585
586 #ifdef STATIC_BUILD
587 return JNI_TRUE;
588 #else
589 if (stat(jvmpath, &s) == 0) {
590 JLI_TraceLauncher("yes.\n");
591 return JNI_TRUE;
592 } else {
593 JLI_TraceLauncher("no.\n");
594 return JNI_FALSE;
595 }
596 #endif
597 }
598
599 /*
600 * Find path to JRE based on .exe's location or registry settings.
601 */
602 static jboolean
603 GetJREPath(char *path, jint pathsize, jboolean speculative)
604 {
605 char libjava[MAXPATHLEN];
606
607 if (GetApplicationHome(path, pathsize)) {
608 /* Is JRE co-located with the application? */
609 #ifdef STATIC_BUILD
610 char jvm_cfg[MAXPATHLEN];
611 JLI_Snprintf(jvm_cfg, sizeof(jvm_cfg), "%s/lib/jvm.cfg", path);
612 if (access(jvm_cfg, F_OK) == 0) {
613 return JNI_TRUE;
614 }
615 #else
616 JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path);
617 if (access(libjava, F_OK) == 0) {
618 return JNI_TRUE;
619 }
620 #endif
621 /* ensure storage for path + /jre + NULL */
622 if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) {
623 JLI_TraceLauncher("Insufficient space to store JRE path\n");
811 if (OSXAPP_SetJavaVM) {
812 OSXAPP_SetJavaVM(jvm);
813 } else {
814 jvm = NULL;
815 }
816 }
817
818 dlclose(handle);
819 }
820
821 return jvm;
822 }
823
824 static const char* SPLASHSCREEN_SO = JNI_LIB_NAME("splashscreen");
825
826 static void* hSplashLib = NULL;
827
828 void* SplashProcAddress(const char* name) {
829 if (!hSplashLib) {
830 char jrePath[PATH_MAX];
831 if (!GetJREPath(jrePath, sizeof(jrePath), JNI_FALSE)) {
832 JLI_ReportErrorMessage(JRE_ERROR1);
833 return NULL;
834 }
835
836 char splashPath[PATH_MAX];
837 const int ret = JLI_Snprintf(splashPath, sizeof(splashPath),
838 "%s/lib/%s", jrePath, SPLASHSCREEN_SO);
839 if (ret >= (int)sizeof(splashPath)) {
840 JLI_ReportErrorMessage(JRE_ERROR11);
841 return NULL;
842 }
843 if (ret < 0) {
844 JLI_ReportErrorMessage(JRE_ERROR13);
845 return NULL;
846 }
847
848 hSplashLib = dlopen(splashPath, RTLD_LAZY | RTLD_GLOBAL);
849 // It's OK if dlopen() fails. The splash screen library binary file
850 // might have been stripped out from the JRE image to reduce its size
851 // (e.g. on embedded platforms).
|