Java App as a Single EXE
Despite Sun’s (now Oracle’s) best efforts to push Java to all PCs in the world, people keep coming to our Web site seeking a way to turn a Java app into a single EXE file that would just run on any Windows box without installation.
Problem is, even though Excelsior JET is capable of compiling your Java application classes together with Java SE standard library classes into a single executable, that executable still needs a number of separate files to run: native method libraries, fonts, time zone information, etc.
Those files are needed because Excelsior JET includes the licensed reference implementation of the Java SE standard library, and that’s the way it works. Changing all the places referencing those files and propagating the changes through Java version updates would be prohibitively expensive.
The solution we used to suggest is to export your application as a self-contained directory, which may then be reduced to a single executable using one of the generic application virtualization technologies such as VMware ThinApp.
If you think application virtualization is an overkill for your needs (especially considering the exorbitant costs of the commercial solutions), here is a quick workaround we recently discovered. Using the free 7-Zip archiver, you may turn the self-contained directory produced by JetPackII into an SFX archive that would unpack itself into a temporary directory, launch your application, wait for its termination and clean up after itself.
For those of you who want to try it immediately, here is a link to the Knowledge Base article with step-by-step instructions and tips to avoid the UAC prompts and PCA warnings on Windows 7 and Vista:
Packaging a Private JRE
You may be wondering now why you would need Excelsior JET when you could place a private copy of the JRE alongside your application jars in the SFX archive. This is a very valid question, but I suggest you keep reading to learn about the benefits of using our product compared to a private JRE.
I will be using our pet example – RSSOwl RSS reader – again. RSSOwl is implemented as an Eclipse RCP application and itself takes 17 MB when unzipped. It also needs a Java runtime so as to run on any computer, whether Java-enabled or not. I have four options:
- Uncompressed application directory with a private JRE
- Same packaged into an SFX archive as described above
- Natively compiled application exported as a self-contained directory
- Same packaged into an SFX archive
And here is the disk footprint chart:
As you may see, even in the uncompressed natively compiled form the application’s disk footprint is not much worse than compressed jars with a private JRE.
Startup Time Impact (can be positive)
Now there is a concern that the intermediate decompression step may substantially increase the overall startup time of the application. At the same time, reading one compressed file sequentially, especially from a slow-seek device such as an optical disk drive, takes less time than reading multiple files in a scattered order. Also, the decompressed files will remain in the disk cache, so the application will then enjoy a very warm start. So if the processor is fast enough to decompress the archive at the pace matching the transfer rate of the device containing the SFX, the application may actually start faster.
I have conducted some measurements to prove or disprove the above speculations. Specifically, I could think of the following scenarios where packaging your app as a single, install-free EXE is desirable:
- You want to place it on the desktop of a digitally challenged friend or family member with the words “when you need X, fast-click this icon twice”;
- You want to place it in a well-known shared folder on your intranet for your non-IT colleagues to use.
- You want to carry it around on a USB stick so as to be able to run it on any PC.
- You want it to run automatically from a CD/DVD (you’ll see why single EXE is desirable in this case as well)
I have run the tests on my desktop (AMD Phenom 9750 Quad-Core, 4GB RAM, Optiarc DVD±RW AD-5260S, Windows 7 Professional 64-bit), measuring startup time as the time to fully display the main window.
You may notice that the decompression overhead is negligible these days even on a midrange desktop PC. Moreover, the use of compression totally eliminates the huge optical drive seek overhead, making Java a viable option for creating “autorun” apps.
I have put the SFX packages on our Web site so that you could test them on your systems.
Download RSSOwl 2.0.6 packaged as a single EXE:
Of course, the generic application virtualization solutions and Portable application creators are way more versatile than the above trick, but they are also way more complex and priced in accordance with that
complexityversatility, as this case study nicely illustrates.
More Startup Time Tests
I also tested on an ultraportable laptop: dual-core ULV Intel Celeron SU2300, 2GB RAM, Windows 7 Home Premium 64-bit (no optical drive – sorry.)
Here Excelsior JET is a clear winner over the conventional JRE in cold startup times, whether SFX packaging is used or not.
What about older PCs and netbooks? I do not have a netbook handy, so hope that my old PC (Celeron 2.4 GHz, 1GB RAM, Windows 2000 SP4) would be a good approximation.
For the avoidance of doubt, the DVD drive was spun up before measurement to simulate the autorun scenario. Also note that I was using a DVD+R disc, so the read speed on the new desktop PC peaked at just about 9.5MB/sec, whereas the same drive would read a pressed DVD-ROM at 17 MB/sec.
On my old PC, warm start was noticeably slower from CD and USB stick compared to desktop, but I decided to not clutter the chart.
I also tried running from a network drive, but the results we too inconsistent. Guess I had to get hold of a spare router and setup a workgroup with just two computers. Forgive my laziness.