Calling the Classloader
Now that the Classloader is in place, you need to learn to use it. The 'JarMaker' class is a program that will run another program through JMClassloader.
To see how JMClassloader works, you need to load a program through it. This article includes a sample program called 'CommandLine,' which you can use to test JarMaker. CommandLine is a simple Java shell which allows you to call methods in other classes by typing them in at the command line. Run it with the command:
% java Test
You'll see a command prompt, at which point you can enter a Java class name, method name, and arguments. For example:
$ commandline.calculator.Calculator add 3.4 4.5
This will load up a class called commandline.calculator.Calculator (also included with this article) and call its 'add' method with the arguments '3.4' and '4.5.' Calculator prints the result:
7.9
CommandLine is a great way to test the Classloader because it loads classes dynamically. The plan is to make a JAR file containing only the classes that needed to add 3.4 and 4.5.
% java JarMaker my.jar Test
Instead of running Test, I run JarMaker, passing the class name 'Test' as the second argument. The first argument, of course, is the name of the JAR file that I want to create. Entering the command runs the program as before, and, just as before, I need to enter the additional command:
$ commandline.calculator.Calculator add 3.4 4.5 7.9
This time, however, when I try to quit the program, by any means, it dumps a JAR file containing the necessary classes and lists them.
Starting dump.
adding commandline/CommandLineException.class
adding Test.class
adding commandline/CommandLine.class
adding commandline/calculator/Calculator.class
Dump done.
Now, I have a fresh new JAR file called 'my.jar' containing the listed classes.
Shutdown Hooks
There's just one more piece of the puzzle to look at. How did I create the JAR file after the program had run? I installed a 'shutdown hook'. A shutdown hook is something that you run when the program is finished. You do this by creatingbut not startinga thread, and passing that thread to the Runtime.addShutDownHook() method, as follows:
Thread thread = new Thread( this );
Runtime.getRuntime().addShutdownHook(
thread );
Take a look at the source code for 'JarMaker' in
Listing 2. The thread's run() method takes care of dumping the JAR file. This hook is guaranteed to run when the Java Virtual Machine (JVM) starts to shutdown, even when the shutdown is caused by an abrupt termination. Also be sure to have a look at the utilities in
Listing 3 and the command line test in
Listing 4.
Extending Your JarMaker
The pieces are now all in place. JarMaker is a utility program that lets you run another program under a kind of monitor. This monitor tracks the classes that are loaded, and when the program is done, it builds a JAR file from those classes.
It's important to note that you do not add files in the java.* class hierarchy to the JAR file. There are a couple of reasons for this. First, you don't need themthey are included in any JRE installation. Second, there are way too many of themthe resulting JAR file would end up being much larger than the original program.
You're not generally allowed to redistribute the core java classes yourself, according to the standard JRE/JDK licensing agreement. However, if you happened to have permission to distribute a custom JRE, you could use this system to create a JAR file containing only the java.* classes that you needed, rather than the entire set. You would have to modify the source code to include the java.* classes in the output JAR file and to look in the JRE libraries for classes to add to the JAR file, but it would be worth it. The JDK on my computer has over 27 MB of Java class files, most of which I rarely use. This method could substantially reduce that size