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

Switch to JavaFX native launcher #33

Open
3 of 7 tasks
hinerm opened this issue Jun 8, 2015 · 18 comments
Open
3 of 7 tasks

Switch to JavaFX native launcher #33

hinerm opened this issue Jun 8, 2015 · 18 comments

Comments

@hinerm
Copy link
Member

hinerm commented Jun 8, 2015

Our goal is to simplify the ImageJ launch process so we are not so intimately tied to a custom, complex launcher with its own JDK version concerns.

Perfect world goals include:

JavaFX is currently our first choice for deployment. It appears to be capable of building standalone (no bundled JRE) and self-contained (bundled JRE) apps cross-platform. These is also a maven plugin

JavaFX issues that need to be solved:

  • Not able to set <fx:platform basedir=""/> to get standalone deployment. SOLVED by using build.xml. See also No way to set fx:platform basedir javafx-maven-plugin/javafx-maven-plugin#127.
  • jfx:native goal doesn't respect app name configuration. SOLVED - see jfx:native goal does not respect jfxMainAppJarName javafx-maven-plugin/javafx-maven-plugin#128.
  • Preloaders. WONTUSE preloaders live in the same JVM as the application. They will not meet our needs.
  • Command line arguments - we need to be able to support things like --debugger=8000 which the native launcher translated to JVM argument(s). See SO #30809330.
  • Figure out how we want to handle updating. This is tied to the refresh menus problem. It sounds like the .jar lock in Windows may be fixed in Java 7 allowing runtime swapping, in which case checking for updates at startup and replacing .jars before loading classes and spinning up a context may be an option worth investigating, especially if we remove the ImageJ update site - which would become an immutable /lib.
  • We need a splash screen. Options would be using java -splash or JavaFX.
  • To test: what happens if you try running a no-JRE JFX distribution on a platform without Java installed?

Platform-specific notes

Linux

  • Debian bundler requires fakeroot to be installed and just fails if it isn't. This will only affect developer machines though.
  • Native launcher produced by debian bundler fails with no packaged JRE (message complains that JRE can't be found)

Windows

  • Install WiX (wixtoolset.org) - Version 3.X
  • Install Inno Setup jrsoftware.org/isdl.php
  • Had to fix classpath (didn't have to on linux/osx)
  • exe installer installed to C:\Users\username\AppData\Local\ImageJ
  • msi installer installed to C:\Program Files\ImageJ
  • icon works except it's lost on the app for .exe installer
@hinerm
Copy link
Member Author

hinerm commented Jun 8, 2015

JavaFX may solve this issue

@hinerm
Copy link
Member Author

hinerm commented Jun 8, 2015

However, we need to document what features we may be losing from migrating to JavaFX..

@hinerm
Copy link
Member Author

hinerm commented Jun 8, 2015

Note that whatever solution we settle on we also should ensure our Java3D problems are solved forever and ever.

@ctrueden has a fork of Java 3D 1.6 that is Mavenized.. that may be sufficient..

@ctrueden
Copy link
Member

ctrueden commented Jun 8, 2015

JavaFX provides a developer-facing API for controlling which parameters go to the JVM (e.g., memory settings). Devs can write code letting users set these in their UI of choice, and propagate the information to the JavaFX launcher in a platform-agnostic way (uses Java Prefs API internally). See UserJvmOptionsService API docs for details.

@ctrueden
Copy link
Member

ctrueden commented Jun 8, 2015

Experimental javafx branch can create standalone app (i.e., a double-clickable JAR file which leans on the installed system JRE) as well as a self-contained app (i.e., an app which bundles its own JRE).

Unfortunately, there is no middle ground in JavaFX by default: you cannot have an app (EXE on Windows, .app bundle on OS X, etc.) which does not bundle a JRE.

Or can you? Yes you can! This would be great so that users still get JRE security updates without it being ImageJ's responsibility.

@ctrueden
Copy link
Member

ctrueden commented Jun 9, 2015

I updated the javafx branch in an attempt to use a custom preloader, but it doesn't work yet.

To test things at a lower level—and also to test the <fx:platform basedir=""/> hack for creating a self-contained app without JRE—it is probably time to start calling the Ant tasks directly. Once those are working, we can debug into the javafx-maven-plugin to figure out how to enhance/fix it accordingly.

@ctrueden
Copy link
Member

I tested the <fx:platform basedir=""/> thing to create a self-contained bundle sans JRE, and it works. imagej/ImageJ@f29b4ec Hooray!

This might not actually be the direction we want to go, but it is nice to know we can do it.

Now, we just have to fully understand preloaders...

@FibreFoX
Copy link

Preloaders. WONTUSE preloaders live in the same JVM as the application. They will not meet our needs.

Just my two cents: preloaders are not fully supported on native app launchers, but can be archived by other ways (I noted it down here)

You could create that kind of "splash-screens" as first stage and just switching when ready (like proposed as solution 5 at stackoverflow)

@FibreFoX
Copy link

FibreFoX commented Aug 3, 2015

Hi, just wanted to inform you guys about a pull-request I made for supporting UserJvmOptionsService via javafx-maven-plugin, here is the issue-ticket about it, maybe you want to try this out (just checked back, because i remembered you thinking about using that API).

Hopefully you don't see this as spamming ;)

@ctrueden
Copy link
Member

ctrueden commented Aug 3, 2015

@FibreFoX Thanks for the heads up, and for your great responsiveness in general. 😄 Will try to process and review the linked issue later this month.

@ctrueden
Copy link
Member

Reminder to myself: when progress is made on this issue, follow up on Fiji bug #933 with a link to a JavaFX-based Fiji application bundle, for Antonio Sechi to try out.

@FibreFoX
Copy link

To test: what happens if you try running a no-JRE JFX distribution on a platform without Java installed?

When the bundle does not contain the stripped JRE (which is generated by the javafx-bundler itself), the generated .cfg-file contains an "empty" entry app.runtime=, which can be seen here. Running the native launcher will search for the .cfg-file, if there was something specified, that path will be taken as JRE-root, which can be found here. I crossed these files while bugtracking issue 124. This means, that when not having the runtime bundled, at least on windows-systems, the local installed version will be taken (which might reduce the size of the bundle, but increases problems with not-tested java-versions, or outdated ones...)

There still is some problem which I found just right now with the javafx-maven-plugin: normal way for me was to specify an empty setting:

<bundleArguments>
    <runtime />
</bundleArguments>

But the resulting .cfg-file still containes the wrong line. This is something, I will fix in the next days. EDIT: this is fixed in current 8.1.6-snapshot

Command line arguments - we need to be able to support things like --debugger=8000 which the native launcher translated to JVM argument(s).

For the debugger-thing, maybe you want to create multiple native launchers, this feature is available with normal ant-version of java(fx)bundler and will come in the next days (I'm already developing this feature). All CLI-arguments can be passed normally (and accessed in the main-method, there exists a IT-project for this), but to activate special java-properties I suggest to have multiple pre-configured launchers. Maybe it'll work to have UserJvmOptionsService for this instead of different native launchers, this is supported by putting the packager.jar as system-scoped dependency to your project, like in this IT-project (not nice, but working). All in all these ways might remove the need of own native launchers.

@ctrueden
Copy link
Member

Thanks @FibreFoX. All the links in particular are very helpful and much appreciated.

We are increasingly leaning toward always bundling a JRE in the platform-specific distributions, for the reasons you mention. We want to ship the app via modern "blessed" distribution mechanisms such as the App Store on OS X, to make our users' lives easier. So at least on OS X we would need to bundle a JRE anyway.

Regarding multiple native launchers: my current thinking is to have one native launcher with sensible defaults and configurability via the UserJvmOptionsService... and then one shell script launcher for developers which provides total customizability—e.g., launching with a debug port open. I cannot come up with a use case for non-developer users where specifying the desired JVM flags in a UI window, and then restarting, isn't good enough.

@FibreFoX
Copy link

Native launcher produced by debian bundler fails with no packaged JRE (message complains that JRE can't be found)

This might be since java 1.8.0 update 60, see the issue on javafx-maven-plugin, this got a workaround in latest snapshot-version (had this problem on windows too)

exe installer installed to C:\Users\username\AppData\Local\ImageJ
msi installer installed to C:\Program Files\ImageJ

This can be changed by modifying the generated installer-file (wsx), which is placed under some temporary folder, will be shown/reported, when javafx-maven-plugin contains <verbose>true</verbose>, same goes for msi-installer. In current JDK (since update 60) there seems to exist one specific bundleArgument to make installation-target selectable, I have tried it and it seems to work as expected (but with defaults you listed above); bundle argument for both: exe-bundler and msi-bundler:

<bundleArgument>
    <installdirChooser>true</installdirChooser>
</bundleArgument>

The default installation paths will be determined by the bundle argument <systemWide>.

@FibreFoX
Copy link

For the splash-screen, because I don't want to have preloader-magic, I'm using some launcher-class which encapsulates some heavier calculationparts while showing slashscreen. I've created a GIST about this already which is free to use, but might not be the best solution. The reason I took that approach: Showing some messsages while loading user-settings or processing some signals which are business-logic, which does not fit into normal "splash-screen"-logic.

@FibreFoX
Copy link

😄 oh, and sorry for spamming your thread here

@ctrueden ctrueden added the java8 label Nov 24, 2015
@ctrueden ctrueden changed the title Decouple Java requirement from launch process Switch to JavaFX native launcher Nov 24, 2015
@ctrueden
Copy link
Member

Apparently there is now a Java Packager which is (will become?) part of Java 12.

Here is an article discussing it:
https://medium.com/@adam_carroll/java-packager-with-jdk11-31b3d620f4a8

So the Java Packager will need to be evaluated as well, as part of this work.

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

No branches or pull requests

3 participants