Tuesday, March 20, 2007

Pack Input Jar Files Dynamically

When host a web site which allows users to download reusable Java class files which are compressed into different jar files, to reduce the download time for the client and the band with usage for the server, it would be nice to provide users an option to be able to download highly compressed packed files. As shown in the snippet of a sample download page, users will select any jar files and choose download them in a highly dense format - pack200.



Pack Compressing Classes

The JSR 200 (Network Transfer Format for JavaTM Archives) specifies a "dense download" format to compress input jar files in pack format. JSR 200 is supported with Java 5. The run-time API to pack and unpack the data and files is abstract class: java.util.jar.pack200.

Pack200 is a abstract class and has one private constructor so it cannot be initialized directly. It provide two static methods to obtain new instance of the Packer engine:


Packer packer = Pack200.newPacker();


and
an instance of the Unpacker engine:


Unpacker unpacker = Pack200.newUnpacker();


Pack Jar Files at Runtime

The following example shows how to convert jar files into a pack format at run-time step by step:

1. Obtain an instance of Packer engine:


Packer packer = Pack200.newPacker();


2. Set up output file stream for output packed stream:


FileOutputStream fos = new FileOutputStream("/tmp/test.pack");


3. Read the input jar into a Jar File input stream:


JarFile jarFile = new JarFile("/path/to/myfile.jar");


4. Call the packer to archive jar file:


packer.pack(jarFile, fos);


5. Close input file streams:


jarFile.close();


If there are more than one input jar files, repeat step 3, 4 and 5.

6. Close output stream:


fos.close();


7. Set content type as "pack200-gzip". This indicates to the server that the client application desires a version of the file encoded with Pack200 and further compressed with gzip:

Unpack Paked Stream

The unpacker engine is used by deployment applications to transform the byte-stream back to JAR format.

The follow steps show how to unpack a packed files:

1. Create an instance of Unpacker engine:


Unpacker unpacker = Pack200.newUnpacker();


2. Read in input packed file and set up output file:


File infile = new File("/tmp/test.pack");

FileOutputStream fostream = new FileOutputStream("/tmp/test.jar");
JarOutputStream jostream = new JarOutputStream(fostream);


3. Call unpacker


unpacker.unpack(infile, jostream);


4. Close file stream:


jostream.close();


References:
  1. JDKTM 5.0 Documentation

  2. Network Transfer Format JSR 200 Specification



No comments: