I've been a zone leader with DZone since 2008, and I'm crazy about community. Every day I get to work with the best that JavaScript, HTML5, Android and iOS has to offer, creating apps that truly make at difference, as principal front-end architect at Avego. James is a DZone Zone Leader and has posted 639 posts at DZone. You can read more from them at their website. View Full User Profile

Reducing Development Time by Running JavaFX Applications Using Class Files and JRebel

02.22.2010
| 9323 views |
  • submit to reddit

I always thought that there ought to be a better way to develop JavaFX applications, with kind of similar and gratifying experience as developing Java Swing applications. Traditionally in developing desktop applications, one normally develops and tests using class file to save time, and only uses JAR file for deployment (or if running in mobile emulator or device). However with the advent of RIA platform, the trend is to use a application container file (eg jar, swf) as default way of development since it facilitates seamless running in several modes without hassle (eg as Applet, webstart, and mobile device). Unfortunately, this is rather inefficient if one is developing desktop application, or experimenting with ideas. Unnecessary waiting time only disrupts the creativity and programming flow. Saving a few seconds for every run will accumulate into significant saving of time. Besides, it is rather counter-productive to use container file as the only mode of development if the technology can support alternative efficient way.

Editors Note: Content submitted by geekycoder

Flex’s dilemma

The case in point is that JavaFX does not need to suffer the same fate as Flex in term of development. Flex which is based on Flash technology requires the generation of SWF container file for every change need to be made. This actually increases the waiting processing time as composite files that store in SWF file grow in number and size. For RIA application that a rich appealing user interface that relies extensively on custom-made graphics, developers often have to use lower quality “proxy” graphics in place of high-quality but larger file size graphics to avoid the time wasted to create SWF file for day-to-day development. Hence, developers have to find creative ways to improve the waiting time by reducing the number and size of files to be processed into the container file during development. In the future, Adobe will probably allows development and testing of application in “exploded” format rather than only through SWF.

JavaFX

So how does Flex’s “inefficient” development relate to JavaFX ? Like Flex, JavaFX default to using JAR file as mode of development in NetBeans. Everytime, a JavaFX application is modified, it will be compiled into a JAR file for execution. However, unlike Flex, JavaFX does not actually require using container JAR file for execution unless it is deployed as applet, webstart or mobile application. JavaFX is truly capable of running off from class file using classpath much like its Swing application counterpart. One less unnecessary step means one less waiting time.

JAR file execution: Compile => JAR generation => JavaFX.exe

Class file execution: Compile => JavaFX.exe

NetBeans support of “Running by class file”

imageOut of the box, NetBeans does not explicitly support JavaFX development through class file. The JAR will automatically be generated and run every time the application is modified and run. Developers do not have much control for this case from GUI side of view as see from the Project Properties. However, with some experimenting and understanding of how NetBeans works with JavaFX, it is in fact possible to make NetBeans supports running of JavaFX application by class file. Bear in mind that the subsequent method refers to running in Standard Execution model (Desktop application), not the webstart, browser applet and mobile mode as these modes require JAR file.

 

imageSince the default behaviour is to generate JAR file, it will be useful if the Standard Execution includes a checkbox to explicitly indicates running of Application by class file, thereby bypassing generation of JAR file.

 

Let’s start the exploration
The best way is to learn the concept along side with real practical example so that developers can follow and understand it better.  I am using Windows 7 running NetBeans 6.8 with JavaFX v1.2.3 (the latest as of current. Go to the end on how to add JavaFX v1.2.3 support to NetBeans 6.8 which contains outdated version of JavaFX).

In this case, I use a JavaFX sample example [PathAnimation]from NetBeans. The following applies to any JavaFX application develop in NetBeans. After creating the sample, run the JavaFX example once so that the following file structure will appear as below.

image

You have to use the Files view tab in order to see the full JavaFX application file structure.

There are many files in JavaFX application, however I will only  explain those files and directories that are crucial for “Running by class file”.

The  [build.xml] file is the first file that will be called to initiate the compile and run process.

image

As see, it actually call [build-impl.xml] file which contains the implementation instruction for the build file. This build file when invoke, will create the [build] directory and compile and store the JavaFX class file there (All JavaFX source will be compiled into bytecode class file). When run command is issued,  it will build the JAR file using class files from [build] directory into [dist] distribution directory and then invoke java command to run the JAR file. This is the default behaviour for JavaFX development in NetBeans.

Now open [build-impl.xml] file into the editor and modify some sections (you can also copy this file and alter the file and point that file in [build.xml] file. But for quick demonstration purpose, the original [build-imp] is used instead)

Modification of  [build-impl.xml] file

  • “Disable” generation of JAR file
    Javafxpackager is a JavaFX tool responsible for compiling JavaFX source codes into corresponding Java class files, and generation of JAR file. Note that there is currently no way to turn off the generation of JAR file. The JAR file will always be generated (as far as I know).  It will be elegant if Javafxpackager include command-line option to produce java class from JavaFX source without generating JAR file although the following workaround will prevent this generation from happening

    Search for :
    <exec executable="${platform.fxhome}/bin/javafxpackager${binary.extension}" failonerror="true">
    image 
    a) Replace the line
    <arg file="${dist.dir}"/>
    with
    <arg file="k:\javafxhack"/>  where k stands for any NON-EXISTING drive. It is important to use a non-existing drive because Javafxpackager will attempt to create the directory. The dummy directory is needed to trick Javafxpackager into thinking that it is using a valid directory. If you are using Linux then adjust the path accordingly.

    b) Next, replace
    failoneerror="true"
    with
    failoneerror="false"  
    This step is important because Javafxpackager will complain about invalid JAR file from a) and will not proceed further until this is set to false. 

    After modification, you will get the following

    image

  • Running of JavaFX application through class file
    Since the JAR file is no longer generated, JavaFX application must be run through class file in the [build] directory.

    Search for:
    <java classname="${main.class}" classpath="${dist.dir}/${application.title}.jar" 
    image

    and change it to the following:
    <java classname="${main.class}" classpath="${build.dir}/compiled"

    image 

    Now, JavaFX application is configured to run from [build/compiled] directory rather than through JAR file.

Running by Class file

Now,  run the JavaFX application, and NetBeans will show the following console message.

image 

Even though the jar file cannot be found, the application will still be executed because it is now running off through class file.  You can delete the [dist] directory to verify that JAR file is not generated.

The time-saving is very much depend on the size of the JAR file. You can compare the time with and without using JAR file by simply adding FX.exit() at last statement of run() function of  Main.fx. NetBeans will report the time taken when JavaFX application terminates.

As for my case, this example running on Pentium M 1.5Gz takes around 9s on JAR file, and 6s on class file, a saving of 33%  time saved, though this timing varies from machine configuration and performance over time.

Tips

  • You may want to create another build of [build-impl.xml] file (eg build-impl-classfile.xml) just for the above setting, and then change [build.xml]’s import tag to use the implementation file accordingly. 
  • NetBeans will request for regeneration of [build-impl.xml] file for every change to Project Properties if you have altered the file. This will overwrite the changes you make. Hence, using alternate implementation file will be a good choice.
     image
  • For performance reason, NetBeans caches the settings of [build-impl.xml] file in memory, and any change to the file will not be recognized by NetBeans unless it is edited in Netbeans editor. This means that if  [build-impl.xml] file is modified outside NetBeans (eg using Notepad), and the project is run, those change will not take effect. Only updating the file in NetBeans will those change be reloaded.

 

Running JRebel with JavaFX

Yes ! It is true that by using the aforementioned method, you can actually use JRebel with JavaFX. In the past, there is no easy way that JRebel can work with JavaFX if the JAR file is used to run JavaFX application but by using the class file method to run the application, JRebel can now detect change to those classes automatically and perform its magic. Now, you can get more productive time by running through class file and using JRebel. The best way to see this effect is change the event handling through JavaFX function call image

image

For some unknown reasons, I am unable to run the JRebel plug-in in NetBeans, however you can still use JRebel by adding the following to JVM arguments (change the JRebel path accordingly):

 -noverify -javaagent:"C:\devsys\java\lib\jrebel\jrebel.jar"

 

Just make the change and compile the JavaFX file, and JRebel will automatically reload those changes.

image

Video showing demonstration of JavaFX application running by class file and with JRebel

 

How to add JavaFX SDK v1.2.3 to NetBeans 6.8

You can update to the latest JavaFX SDK simply by replacing the old version with the new version.

Just place the updated JavaFX files into <NetBeans directory>\javafx2\javafx-sdk