Native packaging for JavaFX

Posted by igor on Oracle Blogs See other posts from Oracle Blogs or by igor
Published on Fri, 15 Jun 2012 06:49:38 +0000 Indexed on 2012/06/15 15:23 UTC
Read the original article Hit count: 556

Filed under:

JavaFX 2.2 adds new packaging option for JavaFX applications, allowing you to package your application as a "native bundle". This gives your users a way to install and run your application without any external dependencies on a system JRE or FX SDK. I'd like to give you an overview of what is it, motivation behind it, and finally explain how to get started with it.

Screenshots may give you some idea of user experience but first hand experience is always the best. Before we go into all of the boring details, here are few different flavors of Ensemble for you to try: exe, msi, dmgrpm installers and zip of linux bundle for non-rpm aware systems. Alternatively, check out native packages for JFXtras 2.


Whats wrong with existing deployment options?

JavaFX 2 applications are easy to distribute as a standalone application or as an application deployed on the web (embedded in the web page or as link to launch application from the webpage). JavaFX packaging tools, such as ant tasks and javafxpackager utility, simplify the creation of deployment packages even further. Why add new deployment options?

JavaFX applications have implicit dependency on the availability of Java and JavaFX runtimes, and while existing deployment methods provide a means to validate the system requirements are met -- and even guide user to perform required installation/upgrades -- they do not fully address all of the important scenarios.

In particular, here are few examples:

  • the user may not have admin permissions to install new system software
  • if the application was certified to run in the specific environment (fixed version of Java and JavaFX) then it may be hard to ensure user has this environment due to an autoupdate of the system version of Java/JavaFX (to ensure they are secure). Potentially, other apps may have a requirement for a different JRE or FX version that your app is incompatible with.
  • your distribution channel may disallow dependencies on external frameworks (e.g. Mac AppStore)

What is a "native package" for JavaFX application?

In short it is 

  • A Wrapper for your JavaFX application that makes is into a platform-specific application bundle
  • Each Bundle is self-contained and includes
    • your application code and resources (same set as need to launch standalone application from jar)
    • Java and JavaFX runtimes (private copies to be used by this application only)
    • native application launcher 
    • metadata (icons, etc.)
  • No separate installation is needed for Java and JavaFX runtimes
  • Can be distributed as .zip or packaged as platform-specific installer
  • No application changes, the same jar app binaries can be deployed as a native bundle, double-clickable jar, applet, or web start app

What is good about it:

  • Easy deployment of your application on fresh systems, without admin permissions when using .zip or a user-level installer
  • No-hassle compatibility.  Your application is using a private copy of Java and JavaFX. The developer (you!) controls when these are updated.
  • Easily package your application for Mac AppStore (or Windows, or...)
  • Process name of running application is named after your application (and not just java.exe) 
  • Easily deploy your application using enterprise deployment tools (e.g. deploy as MSI)
  • Support is built in into JDK 7u6 (that includes JavaFX 2.2)

Is it a silver bullet for the deployment that other deployment options will be deprecated? No.  There are no plans to deprecate other deployment options supported by JavaFX, each approach addresses different needs. Deciding whether native packaging is a best way to deploy your application depends on your requirements.

A few caveats to consider:

  • "Download and run" user experience
    Unlike web deployment, the user experience is not about "launch app from web". It is more of "download, install and run" process, and the user may need to go through additional steps to get application launched - e.g. accepting a browser security dialog or finding and launching the application installer from "downloads" folder.
  • Larger download size
    In general size of bundled application will be noticeably higher than size of unbundled app as a private copy of the JRE and JavaFX are included.  We're working to reduce the size through compression and customizable "trimming", but it will always be substantially larger than than an app that depends on a "system JRE".
  • Bundle per target platform
    Bundle formats are platform specific. Currently a native bundle can only be produced for the same system you are building on.  That is, if you want to deliver native app bundles on Windows, Linux and Mac you will have to build your project on all three platforms.
  • Application updates are the responsibility of developer
    Web deployed Java applications automatically download application updates from the web as soon as they are available. The Java Autoupdate mechanism takes care of updating the Java and JavaFX runtimes to latest secure version several times every year. There is no built in support for this in for bundled applications. It is possible to use 3rd party libraries (like Sparkle on Mac) to add autoupdate support at application level.  In a future version of JavaFX we may include built-in support for autoupdate (add yourself as watcher for RT-22211 if you are interested in this)

Getting started with native bundles

First, you need to get the latest JDK 7u6 beta build (build 14 or later is recommended). On Windows/Mac/Linux it comes with JavaFX 2.2 SDK as part of JDK installation and contains JavaFX packaging tools, including:

  • bin/javafxpackager
    Command line utility to produce JavaFX packages.
  • lib/ant-javafx.jar 
    Set of ant tasks to produce JavaFX packages (most recommended way to deploy apps)
For general information on how to use them refer to the Deploying JavaFX Application guide.

Once you know how use these tools to package your JavaFX application for other deployment methods there are only a few minor tweaks necessary to produce native bundles:

  • make sure java is used from JDK7u6 bundle you have installed
    • adjust your PATH settings if needed 
  • if you are using ant tasks
    • add "nativeBundles=all" attribute to fx:deploy task
  • if you are using javafxpackager
    • pass "-native" option to deploy command
    • or if you are using makeall command then it will try build native packages by default
  • result bundles will be in the "bundles" folder next to other deployment artifacts

Note that building some types of native packages (e.g. .exe or .msi) may require additional free 3rd party software to be installed and available on PATH.

As of JDK 7u6 build 14 you could build following types of packages:

  • Windows
    • bundle image
    • EXE
      • Inno Setup 5 or later is required
      • Result exe will perform user level installation (no admin permissions are required)
      • At least one shortcut will be created (menu or desktop)
      • Application will be launched at the end of install
    • MSI
      • WiX 3.0 or later is required
      • Result MSI will perform user level installation (no admin permissions are required)
      • At least one shortcut will be created (menu or desktop)
  •  MacOS
    • bundle image
    • dmg (drag and drop) installer
  • Linux
    • bundle image
    • rpm
      • rpmbuild is required
      • shortcut will be added to the programs menu

If you are using Netbeans for producing the deployment packages then you will need to add custom build step to the build.xml to execute the fx:deploy task with native bundles enabled. Here is what we do for BrickBreaker sample:

    
     <target name="-post-jfx-deploy">
       <fx:deploy width="${javafx.run.width}" height="${javafx.run.height}" 
                 nativeBundles="all"
                 outdir="${basedir}/${dist.dir}" outfile="${application.title}">
          <fx:application name="${application.title}" mainClass="${javafx.main.class}">
             <fx:resources>
                <fx:fileset dir="${basedir}/${dist.dir}" includes="BrickBreaker.jar"/>
             </fx:resources>
             <info title="${application.title}" vendor="${application.vendor}"/>
          </fx:application>
        </fx:deploy>          
     </target>
  

This is pretty much regular use of fx:deploy task, the only special thing here is nativeBundles="all".

Perhaps the easiest way to try building native bundles is to download the latest JavaFX samples bundle and build Ensemble, BrickBreaker or SwingInterop.

Please give it a try and share your experience. We need your feedback!

BTW, do not hesitate to file bugs and feature requests to JavaFX bug database!

Wait! How can i ...

This entry is not a comprehensive guide into native bundles, and we plan to post on this topic more. However, I am sure that once you play with native bundles you will have a lot of questions. We may not have all the answers, but please do not hesitate to ask! Knowing all of the questions is the first step to finding all of the answers.

© Oracle Blogs or respective owner

Related posts about /Oracle