JDK-7129420 : [macosx] SplashScreen.getSplashScreen() returns null
  • Type: Bug
  • Status: Closed
  • Resolution: Fixed
  • Component: client-libs
  • Sub-Component: java.awt
  • Priority: P2
  • Affected Version: 7
  • OS: os_x
  • CPU: x86
  • Submit Date: 2012-01-12
  • Updated Date: 2012-04-10
  • Resolved Date: 2012-03-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availabitlity Release.

To download the current JDK release, click here.
7u4 b11Fixed
While it is possible to define and show a splash screen, SplashScreen.getSplashScreen() returns null. Try for instance a simple test/closed/java/awt/SplashScreen/JavaOneSplashTest.java. Several jck tests fail because of that.

EVALUATION 8-na: the fix is integrated as a part of 7113349.

SUGGESTED FIX --- old/src/solaris/bin/java_md.c 2012-01-20 20:25:58.000000000 +0400 +++ new/src/solaris/bin/java_md.c 2012-01-20 20:25:57.000000000 +0400 @@ -1763,42 +1763,18 @@ splashLibPath = SPLASHSCREEN_SO; #else char path[PATH_MAX]; - Dl_info dli; - - path[0] = 0; - if (dladdr(&SplashProcAddress, &dli)) { - // This is always reported as <path>/bin/java* (java or javaw, whatever) - char * realPath = realpath(dli.dli_fname, path); - - if (realPath != path) { - path[0] = 0; - } else { - // chop off the "/bin/java*" part... - char * c = strrchr(path, '/'); - - if (!c) { - path[0] = 0; - } else { - *c = 0; - c = strrchr(path, '/'); - - if (!c) { - path[0] = 0; - } else { - *c = 0; - // ...and add the lib path instead - snprintf(c, sizeof(path)-strlen(path), "/lib/%s", SPLASHSCREEN_SO); - } - } - } + if (!GetJREPath(path, sizeof(path), GetArch(), JNI_FALSE)) { + JLI_ReportErrorMessage("Failed to GetJREPath()"); + return NULL; } - if (path[0]) { - splashLibPath = path; - } else { - // try our best, but most probably this will fail to load - splashLibPath = SPLASHSCREEN_SO; + const int spaceLeft = sizeof(path) - strlen(path); + if (snprintf(path + strlen(path), spaceLeft, "/lib/%s", SPLASHSCREEN_SO) >= spaceLeft) { + JLI_ReportErrorMessage("JRE path is too long to append the splash screen library name"); + return NULL; } + + splashLibPath = path; #endif hSplashLib = dlopen(splashLibPath, RTLD_LAZY | RTLD_GLOBAL); #ifdef MACOSX

EVALUATION After additional investigation it appears that this is a problem in java_md.c in the code that loads the libsplashscreen.dylib library. The usual RE build has the following directory structure: bin java jre bin java lib libsplashscreen.dylib If we use the jre/bin/java binary to launch tests, then everything works fine. This is because the code in src/solaris/bin/java_md.c in SplashProcAddress() starts off the executable binary path and expects to find the library in ../lib/. However, if tests are run with the toplevel bin/java binary, then this assumption is wrong, and as such the launcher code is unable to load the splashscreen dynamic library. Note that on MS Windows (see src/windows/bin/java_md.c) we explicitly retreive the JRE path, and search the splash screen library from there. This is to allow one to run the jdk/bin/java executable. We should take similar approach in MacOSX implementation as well.

EVALUATION Hmm, well, I have all necessary permissions according to the creation mask: readable for all and writable for group+user. Did you try b225? It would be better to use the same build. I can make a build from a current state of the repo but RE build is something definite. Try RE build b225, and if it works for you, let's use jabber to setup the access. Note that I have logs from a regression suite run on a quite different machine, all with the same result.

EVALUATION That was a false alarm since there was a problem with file permissions. Now I'm still unable to reproduce the problem. I'm doing the following: cd test/closed/java/awt/SplashScreen javac JavaOneSplashTest.java <path_to_my_latest_build>/bin/java -splash:javaonesplashtest.gif JavaOneSplashTest And it does work fine. Please provide a listing of: $ ls -l javaonesplashtest.gif and check if you have read permissions for this file. I'm testing this on Mac OS X Lion 10.7.2. If the issue is still reproducible for you, could you provide a remote access (VNC) to your system please?

EVALUATION Indeed, on Lion the issue is reproducible.

EVALUATION The simplest way to run this example is, it seems to me, just javac JavaOneSplashTest.java; java -splash:javaonesplashtest.gif JavaOneSplashTest It runs OK on Linux but fails with "SplashScree.getSplashScreen() returned null" on Lion. Unfortunately I don't have a Snow Leopard installation available: we have all suitable machines here upgraded to 10.7. I'll try to find a 10.6.8 later today but again, 10.7 is the supported platform.

EVALUATION I'm unable to reproduce this issue on my Snow Leopard system. Firslty, the JavaOneSplashTest.java isn't a test itslef. The closed/java/awt/SplashScreen/test8.sh is the proper name for the test that uses this java source file. When running $ jtreg -testjdk:/path/to/the/latest/7u-osx/build -m test8.sh it acually passes w/o problems. Note that the closed/java/awt/SplashScreen/header.sh needs to be modified as: diff -r 05d03c2a381b java/awt/SplashScreen/header.sh --- a/java/awt/SplashScreen/header.sh +++ b/java/awt/SplashScreen/header.sh @@ -38,7 +38,7 @@ FILESEP="/" ;; - Linux ) + Linux | Darwin ) VAR="A different value for Linux" DEFAULT_JDK=/usr/local/java/jdk1.4/linux-i386 FILESEP="/" Does this modification resolve the issue for you? Could you provide any other relevant details that could help reproduce the issue?