Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Splash screen in Packr on macOS #216

Open
hvdwolf opened this issue Oct 31, 2021 · 7 comments
Open

Splash screen in Packr on macOS #216

hvdwolf opened this issue Oct 31, 2021 · 7 comments
Labels

Comments

@hvdwolf
Copy link

hvdwolf commented Oct 31, 2021

Hi,
Build platform: Ubuntu focal fossa 20.0.4.3 LTS
Test platform: macOS Catalina and Big Sur
Packr: release version 4.0.0
build jdk: adoptopenjdk 11.0.x
packed jre: adoptopenjdk 11.0.x

(This refers also to issue #65 :Some ambiguity with vmargs in config.json)

I build my java jar for Linux, Windows and macOS with the splashscreen functionality from java itself, as that is the easiest.
On macOS I use packr v4 recently (I could not make it work with v3, maybe my fault). Before that I created a bundle manually and use a script to start the app with java -jar jExifToolGUI.jar with some vmargs. That showed the splashscreen.
(my app is jExifToolGUI in case you're interested or in case it matters)
Now with pack 4.0.0, even with my builtin java splashscreen, it doesn't work.
If I double-click the the app, it doesn't show the splash screen.
If I do an open jExifToolGUI.app, it doesn't show the splash screen.
If I do an ./jExifToolGUI.app/Contents/MacOS/jexiftoolgui, it doesn't show the splash screen.
If I do a 'java -jar jExifToolGUI.app/Contents/Resources/jExifToolGUI.jar`, I do get the splash screen.

I already created a jexiftoolgui.json with or without a vmargs splash:my_splash_screen and splash:my_splash_screen.png (although the latter with extension should not be needed) and adding the png to my bundle, but that doesn't work either, which is of course in ling with issue #65.
I understand the explanation in issue #65, but why does the Packr binary block my java builtin splash screen?

(It does work on Windows (using launch4j), it works using a .deb and an AppImage, or simply using java -jar ...)

@hvdwolf hvdwolf changed the title Splash screen in pack on macOS Splash screen in Packr on macOS Oct 31, 2021
@karlsabo
Copy link
Member

karlsabo commented Nov 6, 2021

Are you creating the splash screen yourself in code doing something like final SplashScreen splash = SplashScreen.getSplashScreen();? Or is it only the -splash argument?

I'm not sure a -splash argument gets passed to the JVM shared library when it's loaded.

@karlsabo
Copy link
Member

karlsabo commented Nov 6, 2021

Have you tried running the packr executable with the arguments -c --verbose to see what gets printed out?

@hvdwolf
Copy link
Author

hvdwolf commented Nov 6, 2021

The splash is created by adding the splash screen in the jar and add an entry to the manifest. The manifest is created from the build.gradle.kts

val jar by tasks.getting(Jar::class) {
    manifest {
        attributes["Main-Class"] = project.ext["mainClassName"] as String
        attributes["Build-Timestamp"] = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(Date())
        attributes["Created-By"] = "Gradle ${gradle.gradleVersion}"
        attributes["Author"] = "Harry van der Wolf"
        attributes["SplashScreen-Image"] = "icons/jexiftoolgui-splashlogo.png"
        attributes["Multi-Release"] = "true"
    }
}

So it is not coded.
I also tried with the vmargs option by specifying the logo --vmargs splash:jexiftoolgui-splashlogo.png, using many both jar internal as normal disk paths to try it out.
I tried to code it this morning using the SplashScreen splash = SplashScreen.getSplashScreen();, but somehow I can't make that work.
In my initial Application.java I end with SwingUtilities.invokeLater(mainScreen::createAndShowGUI); as "it should be done".
This however prevents me from using the splash screen as I get "suddenly" nullpointer exceptions in my main thread crashing my application. When using the same code from a plain simple java app it works fine.
I have not sorted that out yet.

EDIT: sorry, forgot to mention the -c --verbose options. I copied the relevant part

Using default configuration file jexiftoolgui.json ...
Changing working directory to /Users/harryvanderwolf/Downloads/java/packr/jExifToolGUI.app/Contents/Resources ...
Loading JVM runtime library ...
fileSearch found libjli! filename=jre/lib/jli/libjli.dylib, lastFileSearch=
Loading libjli=/Users/harryvanderwolf/Downloads/java/packr/jExifToolGUI.app/Contents/Resources/jre/lib/jli/libjli.dylib
Passing VM options ...
isZgcSupported()=1, hasJsonValue(jsonRoot, "useZgcIfSupportedOs", sajson::TYPE_TRUE)=0
  # -Xmx2G
  # -Dlogback.configurationFile=logback.xml
  # -splash:jexiftoolgui-splashlogo.png
Passing VM options:
  -Xmx2G
  -Dlogback.configurationFile=logback.xml
  -splash:jexiftoolgui-splashlogo.png
Creating Java VM ...
Passing command line arguments ...
Loading JAR file ...
Adding 1 classpaths ...
  # jExifToolGUI.jar

@hvdwolf
Copy link
Author

hvdwolf commented Nov 6, 2021

I now coded it with both a URL from resource in my jar, which doesn't work.
I also coded it now by using the SplashScreen splash = SplashScreen.getSplashScreen(); with using the vmargs parameter, but that doesn't work either. The second perhaps because that is that blocking issue between java and macOS.

@karlsabo
Copy link
Member

karlsabo commented Nov 6, 2021

I'm not sure if this is accurate, but there's an old StackOverflow that says the splash screen is created by native code: https://stackoverflow.com/questions/32215515/how-java-splashscreen-works.

If that's true, it would explain why it doesn't work, packr only loads the JVM shared library and executes your main method.

I think the best chance you have is to show a splash screen yourself from your main method like they did in #65.

@karlsabo
Copy link
Member

karlsabo commented Nov 6, 2021

It could also be similar to an issue jpackage had: https://bugs.openjdk.java.net/browse/JDK-8250611. Maybe loading the splashscreen shared library would fix it. You could try updating the C code to load those libraries, or try out jpackage.

@hvdwolf
Copy link
Author

hvdwolf commented Nov 6, 2021

I already tried jpackage for jdk16 and jdk17. Exactly the same behavior as Packr, with the disadvantage of jpackage that Packr is platform independent and jpackage is not.
And with regard to the "early loading" as described. That is exactly what I was doing: load the splash screen from the manifest using the native C-launcher before the JVM loads.
I guess the jpackage launcher and Packr launcher are slightly different from the manifest invoked launcher.

I have seen the solution in #65, but my UI loads diferently via the SwingUtilities.invokeLater scheduler.
I actually hate to write a special code block only for a splash screen and only for macOS. The manifest solution is such an elegant solution and when doing a java -jar whatever.jar it simply works. Maybe it might be better to do some of my initialization in the background using an executor to show my screen faster.

Executor executor = Executors.newSingleThreadExecutor();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    .................
                }
            }
});

I really appreciate your feedback and thinking along, but I think I will "park" this for some time and look at other ways. This already took my whole day only for a splash screen. I will stay with Packr and abandon my manual bundle, as the Packr method delivers a real bundle instead of my script in a bundle starting java with a jar.
If I find something different from #65 I will certainly share the snippet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants