Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debug SplashScreen from Eclipse without generating the Jar

I have search all over the web but could not find answer to this question:

I need to debug the functioning of an application that changes the SplashScreen based on the module you are accessing.

I do know that the code:

SplashScreen splash = SplashScreen.getSplashScreen();

Can be used to get the instance when you pass either:

  • Splash from command line: java -splash:path/image.gif ClassFile
  • Splash image in manifest: splashscreen-image: img/SplashNomina.gif

Still when I tried to run the application by passing the -splash value from VM args in Eclipse it did not work.

Is it actually possible as SplashScreen.getSplashScreen() is always NULL. I have been trying passing without success:

  • -splash:image.gif
  • -Dsplash=image.gif

Right now I see lots of limitations in this Splash api, as it is always required to have a parameter being passed. I think it would be much more flexible to be able to just pass the parameter at runtime :(

Any help woult be really appreciated!

like image 722
will824 Avatar asked Aug 02 '11 01:08

will824


1 Answers

OK, this has bitten me too.

I built a runnable jar with manifest entry

SplashScreen-Image: MyGraphic.jpg

and it works as it's supposed to.

From Eclipse, specifying the VM arg as

-splash:MyGraphic.jpg

no such luck

SplashScreen.getSplashScreen() returns null.

The reason for this is the brain-dead implementation of SplashScreen.getSplashScreen() in the JDK (at least 1.6). I think. It's kind of hard to tell without getting into what the native code is doing. But, here is this method from java.awt.SplashScreen. I'm not sure if it's called but studying it did provide me with the essential clue I needed to get this working in Eclipse:

public synchronized URL getImageURL() throws IllegalStateException {
    checkVisible();
    if (imageURL == null) {
        try {
            String fileName = _getImageFileName(splashPtr);
            String jarName = _getImageJarName(splashPtr);
            if (fileName != null) {
                if (jarName != null) {
                    imageURL = new URL("jar:"+(new File(jarName).toURL().toString())+"!/"+fileName);
                } else {
                    imageURL = new File(fileName).toURL();
                }
            }
        }
        catch(java.net.MalformedURLException e) {
            // we'll just return null in this case
        }
    }
    return imageURL;
}

Note that in the case of a file (i.e. command-line rather than jar launch) it's not doing a getResource() to get the URL but opening a file relative to the CWD. Since Eclipse run configurations default to running from the root of the project, the answer is to specify the path as a relative path and not to expect a classpath lookup.

Therefore, since I am building with maven, my image is located at src/main/resources/MyGraphic.jpg. Specifying this as the command line parameter: i.e.

-splash:src/main/resources/MyGraphic.jpg 

allows it to work in Eclipse (or, I guess, any command line)

I'm not sure WHY this is, since the getImageURL method is NOT called by getSplashScreen() but it DOES work.

To me this is kind of brain-dead on the part of Sun/Oracle. They could have easily done a classpath lookup with something like imageURL = getResource(filename) but they did not.

The short answer is that the Splash Screen command line syntax refers to a filename relative to the current working direrctory, not relative to the classpath.

like image 159
Steve Cohen Avatar answered Sep 22 '22 10:09

Steve Cohen