Features described in this sections are no longer supported and will be removed in the next major release of Excelsior JET.
To quickly check if these features are used in your projects, switch the CHECKDEPRECATED option ON
in the project file and try to re-compile it. If usages of any deprecated feature are found, the compiler terminates with the respective error message.
The JET Runtime comes with two JIT compilers:
This JIT compiler is essentially the main static compiler, scaled down and adapted for runtime use.
This compiler implements a few low-cost optimizations, and thus is an order of magnitude faster than the optimizing JIT compiler. The Fast JIT compiler is enabled by default.
Future versions of Excelsior JET will not include the Optimizing JIT compiler. Instead we will make the Fast JIT compiler produce better code
The differences between the two compilers are summarized in the following table:
|Characteristic||Optimizing JIT||Fast JIT|
|Compilation speed||Low (order of magnitude slower than HotSpot)||High (comparable to HotSpot)|
|Code quality||High (somewhat below the static compiler)||Moderate|
Note: If the optimizing JIT compiler fails to compile a method due to lack of memory or inability to restore the method’s structure suitable for optimizations, which may be caused e.g. by obfuscation, it always invokes the fast JIT compiler for such a method.
You select either optimizing or fast JIT compiler on Options page of the JET Control Panel. Another way to force using a particular JIT is setting the system property jet.jit.optimizing or jet.jit.fast, respectively.
If you use the Optimizing JIT compiler, it may run out of memory when compiling very large methods. In such case, you can set the jet.jit.heap.size VM option that defines the maximum amount of memory the JIT compiler is allowed to use. Default value is 128 megabytes.
Note: information in this section is not applicable to the Standard Edition and 64-bit version of Excelsior JET.
To reduce the overhead of dynamic compilation, the JET Runtime is capable of caching the code produced by the JIT compiler during execution. Once a JIT cache is created, it may be reused by the application on next launches so that JIT compiler will not be invoked for the cached classes. To provide correctness, the JET Runtime performs consistency checks to ensure that the bytecode being loaded has not been changed since the previous run. If the checks fail, JIT cache is (partially) rejected, that is, the outdated code is not used. In place of it, the JIT compiler produces an up-to-date version of the cache.
You enable the caching mechanism for your application on Options page of the JET Control Panel or by setting the system property jet.jit.cache.
Technically, JIT cache is organized as a directory that contains a set of shared libraries with the cached code and a cache descriptor file. The JET Runtime consults the cache descriptor when it performs consistency checks or looks for a piece of the cached code.
By default, the JIT cache directory has the name jittemp and is located in:
the directory which is set current when the executable is launched (if applicable, the Working Directory property of the respective shortcut, otherwise the directory containing the executable file)
the current directory of the calling process at the moment of the first call to JNI_CreateJavaVM()
You may assign a different location for the cache directory on Options page of the JET Control Panel or by setting the system property jet.jit.cache.dir, for instance:
Note: In general, using an absolute pathname for the cache directory is not recommended as it may cause troubles on deployment. If you want to rename the cache directory or change its location on end user systems, specify the jet.jit.cache.dir property when packaging your application for deployment (see Editing Java system properties for details.)
Note: information in this section is not applicable to the Standard Edition and 64-bit version of Excelsior JET.
This section describes JIT Cache Optimization, that enables you to use the JET static compiler to optimize applications that rely on custom classloaders.
JIT cache optimization is a three-step process:
Alternatively, you may use the xjava launcher to run your entire application through the Caching JIT compiler and then optimize it.
Suppose you have an application that uses the JET Caching JIT compiler and you set a cache directory, for example, MyTemp:
export JETVMPROP=-Djet.jit.cache -Djet.jit.cache.dir:MyTemp
First, set the jet.jit.save.classes property to flush all dynamically compiled bytecode to disk for subsequent recompilation. Class flushing has a positive side effect: it allows you to pre-compile even those classes which do not exist on your system in the form of class files (e.g. if they are dynamically created at run time).
Note: You may use jet.jit.save.classes on the developer’s machine only and disable it in the compiled application if you find that it may cause security violation. Turn DISABLECLASSSAVING option ON in your project file to prohibit class flushing on end users’ systems.
After that, you run your application using the JET Caching JIT compiler to create a JIT cache. Along with compiled code, the dynamic compiler creates a cache descriptor in your JIT cache directory. Cache descriptor is a plain text files named
(for instance, jit37023.cache).
Create a separate project specifying the cache descriptor as a source:
------------- fuseCache.prj -------------
% JETVER/VCODE hold JET/JRE version codes
and build it as
jc =p fuseCache.prj
As a result, you will get a new cache descriptor (e.g. jit31523.cache) created in the MyTemp directory and fusedCache.so created in the current directory.
At this point, you may remove all files from MyJITTemp except the cache descriptor and copy the newly created fusedCache.so to that directory. Also, remove jet.jit.save.classes property setting.
Now, if you run your executable, it will automatically use the fused cache.
You may fuse JIT Cache incrementally. For that, follow the steps described in JIT cache optimization, but do not delete flushed classes and leave the jet.jit.save.classes setting intact on Step 3. If your application creates new cache entries that you wish to fuse with the shared library created at previous steps, just perform the procedure again. This saves time of dynamic compilation because the cached code is reused and compilation occurs only for newly loaded classes. To save time of static recompilation of JIT cache, you may specify =s switch to enable the incremental build mode as
jc =p =s fuseCache.prj
When you decide to stop the process, remove jet.jit.save.classes setting and run your application without flushing classes.
You can optimize JIT cache using the xjava launcher (see xjava launcher) with the following options:
If launcher-name is not specified, the launcher will be named after the main class specified on the xjava command line (or after the jar file if the -jar option is used.)
Note: Only the options that affect code generation will be retrieved from prj-file.
The -Xcompile option changes the behavior of xjava completely. Instead of running your application, it does the following:
Any command-line options other than -Xcompile are hard-wired into the custom launcher, so the correct usage is to add -Xcompile to the options you previously specified:
xjava -cp MyLib.jar -Dfoo=bar -Xmx256M foo.bar.Main
xjava -cp MyLib.jar -Dfoo=bar -Xmx256M -Xcompile foo.bar.Main
If you want to change the default settings for JIT cache compilation, use the -Xuseprj:prj-file option, where prj-file is a regular JET project file. xjava ignores prj-file directives that do not affect code generation.
To begin using the xjava launcher, you normally just need to replace the “java” / “javaw” command with “xjava”. For instance, the following command:
xjava -cp MyLib.jar foo.bar.MainClass
will run your application with the JIT compiler caching files in the ‘jittemp” subdirectory of the current working directory. Then, you can optimize that cache by adding the -Xcompile option:
xjava -Xcompile -cp MyLib.jar foo.bar.MainClass
The result will be the custom launcher foo.bar.MainClass, optimized cache shared library, and new cache descriptor. The -cp MyLib.jar option will be hardwired into the launcher. Now you may run the optimized application by typing just
To deploy the optimized application, create a new package in JetPackII and add the launcher executable to it. JetPackII will recognize the launcher and prompt you for adding the optimized cache to the package. See Adding files using filechooser for details.
If startup of your application takes longer than you would like it to do, the thumb rule is to show a splash screen. It definitely relieves the loading process from the end user’s perception, moreover, the splash may contain information about your product and company.
The splash screen functionality appeared in Java API since Java SE 6. For more details, see
Excelsior JET extends that functionality as follows:
All you need to do is to specify the necessary splash settings to the JET Runtime.
If the splash image has been specified in the manifest of the application’s JAR file, the respective image will be obtained automatically:
Otherwise, you need to assign the application a splash screen image manually:
The supported image formats are PNG, GIF and JPEG, including images with transparency, translucency, and animation.
You may convert images to required format using a third-party image processing tool.
Once assigned, the splash will quickly appear at the very startup of the application (hence the name InstantSplash.)
There are various options to control when the splash screen image shall disappear.
An obvious behavior of the splash screen is to disappear when the main application’s window is opened. However, it is less obvious how to determine what window is the main one (consider an application that opens auxiliary windows such as console, list of warnings, or some dialogs before the main window.) You may choose one of the following "auto-hide" policies:
Note: By default, the splash screen disappears as the application opens any AWT frame. If you choose the other option, the following limitations apply: translucency in the splash image is not supportted .
If you want to change the default policy, do the following:
-splashcloseontitle="My main window"
Another option that controls the splash screen behavior is a splash delay. You may wish to delay splash disappearance, e.g. to let the user enjoy your artwork. For that, specify the number of seconds you want it to stay on the screen:
Note: The splash delay does not work if you opted to hide the splash screen when any AWT window opens. In that case, the Show splash for box is disabled and the SPLASHMINTIME equation is ignored.
If a delay is set, the splash works as follows. It appears at application startup and stays on the screen for the specified time. After that, the selected "auto hide" policy has effect. If the window has been already opened, the splash disappears; if not, it remains on the screen until the respective window will be opened.
Finally, you may choose whether to hide the splash screen if user clicks on it. By default, user click hides the splash screen for Java 5 applications, but does nothing for Java 6 applications. If you wish the splash screen to disappear on user clicks for Java 6 applications as well, do the following: