JAX Tutorial


JAX is a Java program packaging tool that reduces the program's size. It works by analyzing a Java program, extracting the essential artifacts out of it, appling some optimizations that reduce space overhead, and then compressing what is left. An estimated 30-50% reduction of the original program size is currently feasible with JAX. In addition, a JAXed Java program is also obfuscated. Obfuscation makes the reconstruction of source code from byte codes difficult.

JAX takes as input a the name of a Java class that represents the Java program whose size you want to reduce. Since JAX is written in Java, you run JAX the same way you would run any other Java program.
java jax <class_name>

JAX uses the current setting of the CLASSPATH variable to detect the location of the <class_name>.class file (in the same way a Java VM would). When loading class <class_name>, JAX will determine the classes <class_name> depends on and automatically load these classes also.

After loading all class files, the class files are analyzed, the essential artifacts are extracted, optimization is preformed, and the remaining artifacts are compressed. Both the original and the JAXed version of the program are saved in two zip files <class_name>_big.zip and <class_name>_jax.zip. With the default settings, JAX tries to create a zip file that is as small as possible.

We will use a sample program, Hanoi, to explain the usage of JAX. Hanoi can be found in the demo directory in the JAX distribution. So, to reduce the size of the Hanoi program, run the following command:

The output to the screen is:

ProgramName is "Hanoi"
JDK used is Microsoft Corp. version 1.1

jax V5.0-Monday-Mar-1-1999 Copyright IBM 1997-1999. All rights reserved.
Info inside IBM: http://w3.watson.ibm.com/~laffra/jax
Info outside IBM: http://www.alphaWorks.ibm.com/formula/jax

Your free license expires on Jun 1 1999. After this date,
download a new version with major improvements and bug fixes.

Options: obfuscate transform verify devirtualize inline compatibleserialization

loading, this may take a while

finished loading, total 289 classes

starting search for entry points
finished search for entry points

starting RTA analysis
finished RTA analysis

starting inlining
finished inlining

starting class hierarchy transformations
finished class hierarchy transformations

starting name compression
finished name compression

starting devirtualization of method calls
finished devirtualization of method calls

Warning: no "Hanoi_jax.dlc" file with dynamically loaded class names
Warning: no "Hanoi_jax.fcn" file with fixed class names
Warning: no "Hanoi_jax.dim" file with names of dynamically invoked methods
Warning: no "Hanoi_jax.daf" file with names of dynamically accessed fields

starting verification
verifying...
finished verification

saving, this may take a while

saved 22 classes into Hanoi_jax.zip

Analyzed: 31 classes.

Total memory used by jax for processing: 4154928 bytes.

--------------------------------------------------------------
zipfile methods fields classes
--------------------------------------------------------------
before: 58140 285 147 31
after: 22041 184 100 22
--------------------------------------------------------------
savings: 36099 101 47 9
62% 35% 31% 29%
--------------------------------------------------------------


Detailed information saved in: "Hanoi_jax.log"
Compressed project saved in: "Hanoi_jax.zip"

Time used for analysis: 3 seconds.


Thanks for using JAX, a technology preview from IBM.
Please email your feedback to: jax@watson.ibm.com

JAX first outputs the version of JAX that is being used, the IBM internal and external websites where JAX information can be obtained, the name of the program, and the version of the Virtual Machine that is being used, and the expiration date of the license. JAX then prints the options that were used when JAXing Hanoi. Since no command line options were specified, the options shown are the defaults. Look at the Frequently Asked Questions for a brief description of the command line options. Below, we will discuss each option in turn.

Before loading Hanoi, JAX tries to find a Hanoi_jax.dlc file that contains the names of all classes that are loaded dynamically. Since the analysis performed by JAX is not capable of determining the classes that are dynamically loaded, the *_jax.dlc file provides a mechanism for the user to specify these classes. Below is an example of the contents of such a file:

com.acme.ClassOne
com.acme.ClassTwo
com.acme.ClassThree

where each line contains the name of a class that is dynamically loaded. Since Hanoi does not dynamically load any classes, no such file exists.

JAX then looks for a Hanoi_jax.fcn file with classes whose name must be preserved. Since this is not necessary in the case of Hanoi, no such file exists.

After all class files are loaded, JAX tries to find a Hanoi_jax.dim file that contains the methods that are called through Java's reflection API, and a Hanoi_jax.daf file that contains the fields that are accessed through Java's reflection API. Since Hanoi does not use reflection, these files do not exist either. However, for applications that use reflection such files must be created. Below is an example of the contents of such a *.dcl file:

com.acme.ClassFour specialMethod1 (I)V
com.acme.ClassFour specialMethod2 (III)I
com.acme.ClassFour (Ljava/lang/Object;)V

where each line specifies the method by listing (i) the class in which it is contained, (ii) its name, and (iii) its signature. A similar file can be provided for fields that are accessed using reflection.

Next, the output states the number of class files must be analyzed and saves them to the file Hanoi_big.zip that contains uncompressed program packaged in a zip file. The next phases of JAX are displayed as starting and finished messages. These phases consist of: (1) determining entry points, (2) determining reachable methods using RTA analysis, (3) method inlining, (4) class hierarchy transformations, (5) name compression, and (6) devirtualization of method calls.

The table that appears next in the output records the reduction in size of Hanoi after being JAXed. The before row specifies the statistics for the uncompressed program, Hanoi_big.zip, the after row specifies the statistics for the compressed program, Hanoi_jax.zip, and the savings row specifies the per centage of savings that occur in the compressed program. The first column, labeled zipfile, specifies the size of the zip files, the second column, methods, specifies the number of methods, the third column, fields, specifies the number of fields, and the forth column, classes, specifies the number of classes in the uncompressed and the compressed programs. The entry of 62% in the saving row for the zipfile column is the ESTIMATED overall reduction in program size (the "results" reported by JAX are estimates because it cannot tell which of the classes available on the ClassPath belong to your application). JAX, when it can, removes and merges classes; thus, the 29% reduction in the number of classes. JAX eliminates unreachable methods and unneccessary fields, hence the reduction in the number of methods and fields (reported 35% and 31% for Hanoi, respectively) .

JAX generates a log file:

The log file has additional information about the execution of JAX on a program.

Command Line Arguments

Command line arguments influence the execution of JAX. Each command line argument will be discussed in turn. The command

jax Hanoi -noobfuscate


will do as much analysis, extraction and optimization on JAX as it can, but will not change names of internal classes, methods, and fields. By default, JAX changes those names to short ones, saving space.

The algorithm to determine which methods and fields are live in Hanoi is a generalization of the RTA algorithm developed at IBM T.J. Watson Research Center and adapted for Java.

JAX performs advanced class hierarchy analysis to determine the relationships between various classes and interfaces, whether certain classes are instantiated or not, and whether classes have overlapping field and methods declarations. This information is used to decide whether or not classes can be removed or merged (by merging a subclass with its parent class and changing all references to the type of the subclass by its parent class). Such class transformations save in declaration space, reduce classloading time, and limit the stress on a Java VM. In some cases, applications rely on the class identity of objects. One example could be where the program logic interrogates an object to obtain its 'class' object, check its identity, and performs actions based on that. JAX analyzes the program to detect such cases (among other things, all calls to "instanceof" are detected). In such cases, the target class will not be merged with others. If for some reason, a program compressed with JAX behaves differently from its original, try JAXing it with:

jax Hanoi -notransform


That will instruct JAX not to merge any classes at all. The impact of class transformations can be quite big (for Hanoi it is 5%). Please refer to the FAQ for an overview of the other options.


Copyright IBM 1997-1999. All Rights Reserved
More info inside IBM
More info outside IBM