JET (Just Enough Time)
AOT (Ahead Of Time)
What Is JET?
is a static compiler that lets a developer create standard exe
file applications that load and run very quickly.
you can say simply someprog.exe instead of
the usual more verbose java.exe -jar
someprog.jar on the command line.
applications will run even if the Java
JRE (Java Runtime Environment)
is not installed.
- Ordinary jar files are very easy to reverse engineer.
executables are almost impossible to reverse engineer. If you are a
developer this makes it difficult for pirates to defang your
licencing restrictions or to pirate your code.
- With the use of JetPackII, JET-compiled, programs are
self-installing just like Windows apps written in C++.
- JET-compiled programs look like perfectly ordinary familiar
Windows exe files.
- There is no royalty for
- The catch is, unlike the conventional jar version of the
application, they are no longer
WORA (Write Once, Run Anywhere).
You can only use the Windows version of the
on Windows and the Linux version on Linux, nowhere else. Unless you
have Windows or Linux you must use the conventional jar version,
e.g. if you have a Mac.
applications require 32 MB run-time
library which is usually included and downloaded with every
application and update. It contains only the parts of the run time
actually used. Pretty must the smallest distributable is 32
MB, for even the simplest utility and the smallest exe file is about
is Excelsior’s Java optimiser and native code generator, created
in Novosibirsk Russia. There are currently versions for Windows and
Linux in English. Excelsior is not responsible for the accuracy of
anything said on this page. It is based on my personal experience with
over a number of years.
Version jet10.5-ent-x86 supports up to Java 1.7.0_55
(The most recent Oracle release is 1.8.0_40
). Last revised/verified: 2014-08-04. JET
supports XP, W2003, Vista, W2008, W7-32, W7-64, W8-32, W8-64 and Linux. Mac OSX is coming soon.
JET comes with a precompiled JRE,
so you don’t actually need to install a Oracle JDK (Java Development Kit) 1.7.0_55 though obviously you will need some JDK
for development, usually JDK 1.8.0_40. JET
jet10.5-ent-x86 now lets you natively compile Tomcat and
Tomcat applications. There are currently two MPs (Modifier Packs) to download and install for Jet jet10.5-ent-x86.
Why Use JET?
Downside of JET
executables are considerably larger than the equivalent jar. They
contain much of the JRE in compiled form. In contrast, distributed
jars do not contain any run time. However, the RAM overhead of
Runtime is smaller than for the JRE. The distributed bundle produced
may be substantially smaller than the JRE alone and the installed
application will occupy less disk space than the JRE. So if you are
bundling the JRE with your app now, your
distributables will be smaller; if not, they will be larger. This
true for small apps even if you don’t use the Java Run-Time Slim-Down
The files I send people are a minimum of 4 MB, rather than the
tiny jars I would send otherwise. (My apps tend to be quite small,
usually under 100K jars). I have to
post the distributables on my website for pickup rather than
sending by email. You could also send these via WinZip Courier.
is usually a month or two behind Oracle in supporting new JVMs.
Currently it is 5 versions behind the
where the current Oracle JDK is 1.8.0_40.
Last revised/verified: 2008-02-18
You can still compile with the current version of javac.exe
and debug with the current version of java.exe.
- The runtime must exactly match the code. You can’t run new
code on old runtimes or vice versa. This means when a new version
comes out, you will likely at some point recompile and redeploy the
entire universe of every
program you ever wrote on every customer machine. In development, an
executable finds the runtime by scanning the path. If you uninstall
a version of
or replace it with a newer version, all code compiled with it will
stop working since it can’t find the old runtime. You must
recompile it with jc.exe.
- The scheme for distributing the support DLLs and compiled JREs
seemed brittle, at least in the early versions. I have not done any
further distribution experiments since about 2003.
has improved drastically in other areas since then.
worked beautifully on my own machine, but sometimes mysteriously
stopped working on other machines, or never worked, when I deployed.
I got error messages saying that DLLs had gone missing or that the
runtime had not been installed. It is hard to remotely troubleshoot
such problems with an unsophisticated customer. Until I redo my
experiments and can vouch all is now well, I suggest you experiment
with the evaluation version to make sure distribution and remote
installs work smoothly for you. They are probably OK now.
- It installs the
runtime in theAppdir/
RT so that if some other developer is using
or you are providing several applications, there will be duplicate
copies of the
runtime. With today’s terabyte disks this is not longer so
much of a concern.
When Not To Use JET
is not a replacement for Oracle’s javac.exe.
to compile the jars that javac.exe and jar.exe produce. You still use Oracle’s javac.exe to do the source code compiling and
does not have debug features comparable to the trace in Intellij
Idea. You do your debugging on the class files before using
compiles take considerably longer than a javac.exe
compile. You don’t use
until you are fairly sure the code is debugged.
- The only platforms Excelsior
supports at the moment are Windows and Linux. If you are considering
compiling your Java applications to native code to prevent reverse
engineering, but some of your customers use Macs, Excelsior
6.0 won’t help you. If you are using
for the speed, you could ship natively compiled
versions of your app to Windows and Linux users and the bytecode
class files to all others.
Example of Command Line JET Use
You can define a
project and compile it, complete with installer using a GUI. It is a
multi-step process, but not complicated. You can also compile in various
ways from the command line or *.bat scripts.
Example of ANT JET Use
My projects are typically quite simple and I compile them with ANT
scripts simply by handing a jar to the
Your program can detect that is in running under
by looking at the system properties such as:
java.vm.version=1.6.0_31 e.g. This
may be important since
does not support Throwable. getStackTrace()
by default. You must request stack trace support, which slows the
I have been very impressed with the
people. Even without an official support contract, the
people have responded quickly and thoroughly to my bug reports and
suggestions for improvements. They have provided better service free
than most companies provide for hefty fees. I wonder what they do for
an encore when you do sign up for support! Optimising compilers are
notoriously buggy, yet
seems to generate flawless code time after time. I have never
encountered any wrong code generated. The only serious problem I have
is Jet does not have as many built-in root SSL certificates as Oracle
Java 7. This means my apps when running under Jet have trouble screen
scraping some https: websites. You can of course copy Oracle’s cacerts file on top of Jet’s for your own
personal use in testing and debugging, but you cannot legally do that
for programs you distribute.
How Does It Work
See Excelsior’s simplified overview of how
work? It needs somebody else’s compiler such as Oracle’s
to produce the byte codes, then it converts class files to a native
Windows EXE file. Why is it so fast? It is able to determine if
methods overriding a particular non-final method are never actually
called in a particular application and therefore inline the method or
generate direct calls of it.
will allocate some local objects on the stack. It can eliminate a
remarkable amount of code that is not necessary, e.g. redundant checks
for null by both caller and callee.
does loop versioning, i.e. it creates a special safe version of loop
code used when it knows that various exceptions can’t possibly
happen, e.g. subscripts out of range. This way it can avoid much of
the overhead of the Java safety net.
There are now three
versions (four if you count the Embedded edition) described in
It supports all of Java including class.forName
dynamic class loading.
Preparing An Application for Distribution
Here is an overview of the process of preparing Jet-compiled
application for distribution. I am describing the process for Windows,
but it is similar for Linux. Let us assume your application is called
Rabbit and will eventually run on the
client machine as rabbit.exe.
- Write and debug your Rabbit.java java
source code in an IDE such an IntelliJ
- Compile your Rabbit.java source with javac.exe,
probably using Ant or Maven.
- Bundle your Rabbit.class files into rabbit.jar with jar.exe or genjar.jar.
- Compile (i.e. convert class files in the jar into native machine
code) your rabbit.jar from the command
line with jc.exe or for finer control use
the Jet Control Panel GUI to produce a rabbit.exe file. The compiliation tweaking
hints are stored in the human-readable rabbit.prj
file. The rabbit.exe file will run
locally. It is quite small since it uses the pre-installed Jet Run
time and library of precompiled JDKs. It leaves behind intermediate
files in jetpdb to speed up future
compiles. rabbit.xbind.script contains a
DLLs (Dynamic Link Libraries)
that rabbit needs to run. With the Jet Control
Panel you can implement a splash screen that comes up
immediately without having to write any code.
- Use the JetPack GUI to bundle up your
executable, jet compiled parts of the JDK that it uses and library
code into one big setup-rabbit.exe self
installing exe bundle. That is what you
distribute. JetPack stores its tweaking
hints in the rabbit.jpn file.
- You then post the fat setup-rabbit.exe
on a website or burn it on a CD and distribute it to your client.
- When the user runs setup-rabbit.exe it
unpacks itself and places its various pieces, including rabbit.exe
and runtime on the hard disk, then sets up desktop icons and menus.
is 32-bit with 64-bit
planned for 2009. When the
32-bit executables run on 64-bit
windows you have a 3 GB address space. Oracle HotSpot requires a
contiguous address space for the heap, whereas Excelsior
(and, for that matter, JRockit) does not. So if you have lots of RAM,
but the virtual address space is fragmented due to DLLs already
may be able to allocate more objects on the heap than HotSpot.
you don’t have to specify the heap size. You can have it
automatically adjust as it runs taking more or less memory depending
on how much is available in the system. This lets you automatically
exploit the whole machine when there are no other jobs running.
Have a look at the Which
utility for code to recognise
executables and whether they are up-to-date, compiled for the latest
||Human-readable project file.|
||Compiler. Converts *.jar to *.exe
or *.class to *.exe.|
||prepares self-installing apps.|
||Adds support for yet another
JVM (Java Virtual Machine).|
||Project control, GUI control of the compiler.|
Viewing Generated Assembler
versions prior to 5.0 allow you to view the assembler generated by using
the -genasm+ key (aka compiler option switch)
in the project file to generate assembler instead of object files. This
was an undocumented feature. For
5.0+, you will need to use a conventional disassembler
to view the generated code.
-generated code is unusually difficult to reverse engineer since the
compiler does loop versioning and hiking and is so creative at devising
code that does the same thing as the original but in a quite different
From time to time, Excelsior issues
MP (Maintenance Pack) s
to upgrade the Jet compiler, runtime and highest level of the Oracle
Java runtime supported. When you install these, for all practical
purposes all your Jet application exes will stop working until you
rebuild them. It is possible to ask Jet to retain obsolete runtimes or
to regenerate them. However, I have never been able to get old apps to
work without rebuilding them. I have problems with incompatibility
between versions of Java, versions of Jet and something called binary
compatibility level which might be sort of build number. If I fully
understood how this worked under the hood, presumably, I could manage
a corral of both obsolete and up-to-date Jet software and my
Jet-compiled applications of various vintages.
I impatiently cut the Gordian knot. I just delete all my old exes and
rebuild everything. The catch is my build process uses custom
Jet-compiled applications. I can’t rebuild because all my tools
stop working. I kludge my way through this chicken-egg problem mainly
by reverting to executing the orginal jars instead of the Jet-prepared
exes. I can ease the pain of the transition by first temporarily
rebuilding my exes without first rebuilding my Java source or jars,
then rebuild the java and Jars (using recently-rebuilt Jet-complied
build tools) and then rebuild all the Jet exes a second time.
If the setup utility stops working after installing a
maintenance pack, just reboot. It might be a good idea to reboot after
the install on general principles.
I wrote a free utility called Which
to, among other things, help you find obsolete Jet-compiled
JETPack bundles up self-installing applications. It is much like an
InstallAnywhere for Java/
JETPack is very easy to use. Just fill in the blanks.
- Automatically bundle the required Excelsior
- Set up shortcuts on desktop and menu.
- Assign an optional *.ico icon and *.bmp splash screen for your app (done in the
project, not the JETPack installer). You don’t need to write
any code to get this feature built into your executable.
- Display a splash screen during install.
- display a EULA
- Versions 3.7 and earlier required you to have Oracle’s JRE
installed as well a
DLL runtime library on machines running the
executables. Starting with version 4.0,
there is no longer any need to have the corresponding JRE installed,
just the runtime. Unfortunately, an option to create fully self
contained executables that could run without the DLLs has gone.
JETPack will bundle the application and the DLL runtime library into
a rather bulky download: about 9MB for a mid-size Swing application
such as jEdit.
JETPerfect was the global optimiser that came with the Professional
Edition. It is no longer supported. It did a very time consuming and
labour-intensive form of global optimisation creating a stand-alone
When you first install
for development, if you don’t accept the default JVM, it has to
compile the entire JVM set of class files. This takes about an hour on
modern machines or over twelve hours on clunkers with less than 512 MB
of RAM. People who just want to run
have to do this.
Obviously, to use
you need the JDK installed on
each developer machine. To run the programs you need the
DLL runtime and the application. The DLL contains a compiled version
of the JRE. Even though Oracle’s license prohibits partial JRE
redistribution, Excelsior has come up with a solution
that enables you to omit the unused Java SE APIs without breaking the
Oracle license. In a general case however, the entire Java SE API has
to be bundled with your
application to deploy it on a customer machine.
JET 10.5 Improvements
- New garbage collector.
- Apple Mac OSX 10.10 bit support.
- Smaller 64-bit executables.
- I still can’t use the 64-bit version because it does not
implement HUGECLINT. I tend to have quite a bit of static
- Still supports only up to Java 1.7.0_55.
JET 10.0 Improvements
- 64-bit versions improved. They still fail when you have large
amounts of static initialisation.
- Apple Mac OS 64 bit
- Supports Java 1.7.0_55.
JET 9.0 Improvements
- The big improvement is supporting Java 1.7.0_51.
- Linux 64 bit
JET 7.0 Improvements
- The big improvement is the ability to compile Tomcat and Tomcat
- The 64-bit alpha version is out. The compiler runs 64-bit and the
run-time is 64-bit. The optimisations are not hooked up yet, so this
is just for experimenting.
- It also features multi-app executables..
With it, you may compile several applications into a single
executable to simplify deployment and maximize code and data sharing
without manually extracting common parts into dynamic libraries.
- It now supports Windows 7.
- Code runs 1.2 to 3
JET 6.5 Improvements
- Better Eclipse integration.
- Faster memory allocation and garbage collection.
- JIT compilation is twice as fast.
JET 6.4 Improvements
- Optional encryption of literals and resources to make reverse
engineering or tampering harder.
- Twice as fast startup of the finished applications.
- faster compiling, both
JIT (Just In Time)
run time addition of dynamic classes).
- slimmer distributables.
- Not-so-dumb compilation: now a settings change that has no impact
on generated code results in a re-link instead of a full build.
JET 6.0 Improvements
- Keeps getting faster
- Support for Java 1.6, e.g. annotations.
- more flexible installer
- Plug-in for IntelliJ Idea
- more efficient memory management and better register allocation.
JET 5.0 Improvements
creates only one extra directory per project called jetpdb.
It used to create a large directory tree with names duplicating the
branches of your packages. This caused havoc with tcc/TakeCommand CDD.
The new system has a little
PDB (Project DataBase) for
each project for JET’s files.
The distributables are slimmer, 8 MB for Swing/AWT and as small as 5
MB for SWT or LWJGL. You can distribute a package that consists of
your app and just the parts of the JRE that it uses. This prunes
down the size of the distributable.
- Start up time 30% faster when compiled
with the global optimiser.
- 1.7 times faster execution on some
benchmarks because of: new loop optimizations, faster floating-point
operations, faster memory allocation and more effective
implementation of other runtime routines.
- Faster compilation.
- IntelliJ Plugin.
- To suppress the voluminous progress messages, use jc
-DECOR= on the command line.
finds its files using a registry entry at:
- Adaptive Heap Size
- A program bundle distributed to customers. When it runs, it
installs the program on the clien’ts disk. It contains the
program, auxiliary DLLs, data files, icons etc.
- The company headquartered in Novosibirsk Russia that makes
- program containing machine language code that can run on Windows
or Linux. The
native compiler produces executables. You can run these directly on
the machine used to compile them. You must bundle them first into
distributables if you want to run them on other machines.
native compiler than converts class files produced by javac.exe
to Windows or Linux native executables (*.exe files). You control
whether to use production or beta jc.exe
by putting the corresponding directory on the path.
- A native Java compiler for Windows and Linux from Excelsior than
includes an installer. It comes is three versions, standard,
professional and enterprise.
- JET Enterprise
- the high
end version of the JET Java native compiler. The main
advantage over the professional version is the optimised server
runtime for extra speed.
- JET Standard
- the entry
level version of the JET Java native compiler.
- JET Professional
- the intermediate
level version of the
Java native compiler. The main advantage over the standard version
is slimmer distributables. This is what I use.
- The GUI used to bundle a
application up for distribution.
Oracle’s Java run time. It is not required on either the
development or client machine to run
-compiled version of it is automatically bundled with distributed
application along with Excelsior-written native classes and DLLs.
- JET launchpad
- the GUI used to set up
projects to control how they are compiled.
Oracle’s Java development tool. It is not required on either
client machine to run
you would normally have a copy of the JDK on the development
- a powerful optimisation technique
uses to create several specialised versions of a loop body so that
it does not have to check conditions in the middle of the loop body.
It selects the loop body version at the top of the loop. This
removes time-consuming loop body jumps and improves code locality
and avoids instruction pre-fetch cache flushing. The technique is
almost impossible to do by hand in assembler. This is one of the
can often out-perform the best assembler hand coding.