Speed up application start by adding own application classes to classes.jsa

Daniel picture Daniel · Jan 14, 2011 · Viewed 9.8k times · Source

To speed up the startup time of the JVM, the Sun developers decided it is a good idea to precompile the standard runtime classes for a platform during installation of the JVM. These precompiled classes can be found e.g. at:

$JAVA_HOME\jre\bin\client\classes.jsa

My company currently develops a Java standalone application which brings its own JRE, so it would be a fantastic option to speed up our application start time by adding our own application classes to this jsa file, too.

I don't believe the JSA file was created by magic, so: How is it created? And how can I trick the JVM into incorporating my own classes?

EDIT: I already found out the following:

The classes.jsa is created by the command

java -Xshare:dump

The list of classes to incorporate in the dump can be found in $JAVA_HOME/jre/lib/classlist.

I even managed to add my own classes here (and to add them into the rt.jar for java to find them), and to generate my own checksum below the classlist file.

The final problem is: Only classes in the packages java, com.sun, and org.w3c seem to be recognized, if I leave the same classes in their original packages, they won't be loaded. I searched the whole OpenJDK source for pointer about this, but it seems to have something to do with protection domains. If someone is interested enough in this topic and knowledgeable enough, please add some pointers for me to investigaete further.

Answer

Daniel Pereira picture Daniel Pereira · Jan 29, 2013

You were almost there, you only need a couple steps to make it work. To add your own classes to the clients.js you need the following steps:

  1. The qualified name your classes (you have it)

  2. The classpath of these classes (you have it)

  3. Know how to recalculate the checksum (you have it)

  4. Dump the new file, providing the classpath of the classes you are now precompiling with the Java classes.

  5. Run the program, providing the same classpath that you used to dump the new classes.jsa

To provide the classpath where are the classes you are adding to the classlist, use the -Xbootclasspath/a command. It will append the directories/JARs when JVM is searching the places where the boot classes are. The default space for the classes.jsa is quite small, if you need to improve it you can use the -XX:SharedReadWriteSize and -XX:SharedReadOnlySize commands. Your dump command you look similar to this:

java -Xshare:dump -Xbootclasspath/a:C:/myfiles/directoryA/;C:/myfiles/directoryB/;C:/myJars/myJar.jar;

The last step is just run the java application normally, rememebering of turn on the share mode. You also need to add the Xbootclasspath excatly as you added on the dump. It will look similar to this:

java myapp.java -Xshare:on -Xbootclasspath/a:C:/myfiles/directoryA/;C:/myfiles/directoryB/;C:/myJars/myJar.jar;

Now every class that you put on the classlist is being shared with other instances running in the same JVM.