Igor Nekrestyanov yesterday wrote a very important blog post on native packaging for JavaFX applications. Some of you have tried out and commented on our previous blog post about FX Experience Tools, which used native installers. The jfxtras project has likewise created such native installers. The native application bundle approach to deployment is a new mechanism that we’re rolling out for both JavaFX and hopefully in the near future also for Java SE applications (such as Swing and AWT).
Starting with the iPhone, the industry has been moving more and more toward app stores, with app stores being the only distribution mechanism for some platforms for native apps. Apple has even gone so far as to distribute entire new operating systems through the app store, which demonstrates their commitment to the concept. Microsoft is following suit with the Windows app store, as also have all the mobile operating system platforms.
Native app deployment is, in my opinion, the easiest and most natural way to deliver desktop applications. This is particularly true when the JRE and all libraries needed by the application are bundled with the application. Although this leads to larger download sizes, in a world where folks are downloading HD movies over their internet connection, it is becoming less and less of an issue. That doesn’t mean we have carte blanche to just make app downloads huge, indeed, we need to work on making it much smaller than these first prototypes are today. Java 8 modularity will be the first order optimization, such that you can omit modules (via proper tooling). We also would like to see some obfuscation and stripping capabilities added to the toolchain such that (much like you could do in JavaME for years) you can create a subset of the JRE / JavaFX platform that contains only those features and functions that your app actually requires.
The goal with native app bundles is to deliver desktop (and mobile) applications in the manner that is natural for the host OS. For example, you should have a .dmg and .app for Mac OS, and .msi and .exe for Windows, .rpm and .deb for Linux (and .zip / .tgz for platforms not supporting rpm or deb). By delivering Java applications using native formats, we make it really easy to deliver applications using normal workflows. For example, an enterprise IT department can take the .msi and push new versions of your app onto different desktops.
Although the user’s life becomes much simpler (they don’t have to have admin rights, they don’t have to have Java preinstalled, they don’t have to worry about what version of Java is installed, they don’t get blocked from running applets by their browser, etc, they just run the application installer and off they go, just like any other native application), the developer’s life becomes a little more complicated. Well, more or less. The truth is that deploying JNLP applications wasn’t trivial either, so maybe its a wash. But in any case, whereas before you would produce a jar (or set of jars), now you have to wait a little longer while the build process produces native executables. You have to offer up the right executable to users depending on what platform they are on. It isn’t very difficult, but it is some extra leg work. On the upside, the application executable / installer that you give to users is just gonna work. It will work the way users expect and are accustomed to. And by far (in my mind) the greatest advantage is that your application runs with exactly the same version of Java that you qualified your application against. You won’t be burned by updates to Java / JavaFX which cause regressions. You don’t have to worry about older versions of Java installed on the system than what you support. Everything is cobundled, making deployment a cinch.
We’re building this toolchain support into javafxpackager now, but will also be getting IDE support in the future as well as expanding the capability of app packaging to Swing / AWT / other Java apps as well.
Now, we have a great solution here for distributing and installing JavaFX applications. But what about upgrades? One of the advantages of WebStart is that it has auto-updating capabilities. Of course, in an app store scenario, it is unnecessary (prohibited even) for an application to auto-update itself outside the app store. And for IT department installed MSI files, you also won’t require auto-update since the correct way to distribute application updates is by producing a new MSI and giving it to the IT department. But for a broad swath of applications which neither are distributed via app stores nor through a corporate IT department, having some form of auto-update is going to be important.
In the Mac world, this is almost always done by the use of a 3rd party open source framework called Sparkle. Google has developed two different frameworks for this for Chrome and other Google apps (Omaha which is apparently windows only and Update Engine for the mac). Of these, I think Sparkle more closely matches what we want to do for auto-update, but it unfortunately isn’t cross platform. My current feeling on it is that we ought to write a 99% pure java update tool very similar to Sparkle, but that uses JavaFX UI for the dialogs and uses as little native code as possible (mostly just for doing the OS calls to swap the downloaded update with the current application and relaunching). I’ve been talking with our deployment team and with Dan Zwolenski (zonski) who has started a prototype on windows with auto-update capabilities. We’ll be discussing this shortly on the openjfx-dev mailing list.
I’m excited about this work, I think it represents a significant new direction for Java deployment which will make it trivial for end users to download and use Java and JavaFX applications, which in turn makes it much easier for developers and companies to invest in JavaFX clients for their desktop application development needs.