Reducing Development Time by Running JavaFX Applications Using Class Files and JRebel
Join the DZone community and get the full member experience.
Join For Freei 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”
out
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.
since
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.
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.
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 happeningsearch for :
<exec executable="${platform.fxhome}/bin/javafxpackager${binary.extension}" failonerror="true">
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
-
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"
and change it to the following:
<java classname="${main.class}" classpath="${build.dir}/compiled"
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.
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.
- 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
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.
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
Opinions expressed by DZone contributors are their own.
Comments