TOC
BACK
FORWARD
HOME

Java 1.1 Unleashed

- 36 -
JAR Basics

by Mike Fletcher

IN THIS CHAPTER

  • What Are JAR Files?
  • Manipulating JAR Files with jar
  • An Overview of java.util.zip
  • Using JAR Files


Java Archive (JAR) files provide a way to bundle all the resources for an applet into a single file. This chapter introduces JAR files, explains how you can create them, describes the java.util.zip package, and provides a quick example of how to use JAR files with applets. More detailed information on JAR-related topics is given in Chapter 37, "Code Signing and JAR Security."

What Are JAR Files?

In versions of the JDK before version 1.1, if an applet was made up of several different class files or had resources such as GIFs or audio files, you had to download each resource individually. In addition to forcing the user of the applet to wait while the applet's pieces downloaded, this arrangement put an extra load on the HTTP server. To address this problem, Sun introduced JAR files. Based on the widely used ZIP file format developed by PKWare, a JAR file allows multiple resources (Java class files, graphics files, and others) to be bundled into a single, compressed archive file. In addition to making the server's job easier, applets and resources download quicker when they are compressed. A new package, java.util.zip, contains classes to manipulate JAR files (as well as normal ZIP files). You can simply store files in a JAR file, or you can compress them before storing to save space.

JAR files include a manifest file in the archive. This manifest (named META-INF/MANIFEST.MF) gives message digests of the component files in the archive. Additionally, digital signatures of component files can be included in the META-INF directory of the archive. Code signed by a trusted entity can be granted extra privileges (such as writing files). Code signing and related issues are covered in detail in Chapter 37.

Manipulating JAR Files with jar

Included with the JDK 1.1 is a tool to create and manipulate JAR files. This tool is called, logically enough, jar. The jar tool runs from the DOS command line or UNIX shell prompt (represented in the examples below by the % character). The following examples show how to use jar to create a JAR file, how to list the contents of an archive, and how to extract a file from an archive. In all cases, two extra options can be used with jar to change how it operates:

Option Description
v Tells jar to generate verbose output about the actions it is performing.
f Specifies the filename to manipulate. If this option is not given, jar writes to standard output.


If you happen to forget how to use jar, you can run it with no arguments to generate a usage listing.


NOTE: Because JAR files are stored in the standard ZIP format, you do not have to use jar to create JAR files. You can use any application that can create ZIP files--as long as you generate your own manifest file and name it correctly (META-INF/MANIFEST.MF). You can find information about the manifest and signature file formats at this site:

http://www.javasoft.com/products/JDK/1.1/docs/guide/jar/manifest.html

Free ZIP and unZIP programs are available from the Info-ZIP group. Source code and binaries for many platforms are available from this site:

http://www.cdrom.com/pub/infozip/Info-Zip.html


Creating a JAR File

To create an archive, you use jar with the c flag. Suppose that we want to create a JAR file with three files: sampleApplet.class, a Java class file; sampleGraphic.gif, an image file; and sampleSound.au, an audio file. The following command places these three files into an archive named sample.jar. The options cvf specify that we want to create an archive, we want verbose output, and the archive filename should be sample.jar.

% jar cvf sample.jar sample.jar sampleApplet.class sampleGraphic.gif sampleSound.au

Here's what jar shows you as it's creating the archive:

adding: sampleApplet.class in=4480 out=2065 deflated 53.0%
adding: sampleGraphic.gif in=506 out=419 deflated 17.0%
adding: sampleSound.au in=5529 out=1088 deflated 80.0%

For each file, jar specifies the input size before compression and the output size after compression, as well as a ratio showing how well the file was compressed.

Listing the Contents of a JAR File

Next, let's list the contents of the archive file we just created. The t option tells jar that we want a table of contents for the JAR file; the vf options specify verbose mode and the filename for which we want information:

% jar tvf sample.jar

Here's the output from jar:

   402 Tue Feb 18 23:12:10 EST 1997 META-INF/MANIFEST.MF
  4480 Mon Feb 17 02:03:46 EST 1997 sampleApplet.class
   506 Tue Feb 18 22:24:52 EST 1997 sampleGraphic.gif
  5529 Mon Feb 17 00:16:02 EST 1997 sampleSound.au

Notice that there is an extra file named META-INF/MANIFEST.MF in the JAR archive file. This is a manifest of all the files contained in the archive and a message digest of the contents of each file (see Chapter 37, "Code Signing and JAR Security," for more information about message digests). The jar tool automatically generates a manifest file; alternatively, you can generate one yourself and pass the m flag to jar when you create the archive.

Extracting a File from a JAR File

Now let's extract sampleGraphic.gif from the sample.jar file. In the following command, the vf options are the same as they were in the preceding section (verbose mode and the filename from which you want to extract a file). The x option specifies that we want to extract files. If no extra arguments are given, jar extracts the entire contents of the archive. If arguments are given after the archive name, jar takes those as the names of the files to extract.

% jar xvf sample.jar sampleGraphic.gif

Here's the response from jar concerning the extraction request:

extracted: sampleGraphic.gif in=419 out=506 inflated 17.0%

An Overview of java.util.zip

The java.util.zip package contains several classes that facilitate the manipulation of compressed files.

The ZipFile Class

The ZipFile class provides a way to read the contents of a ZIP archive. There are two constructors: one that takes a String specifying the filename of the archive to open and one that takes a java.io.File object. The getName() method returns the path name of the ZIP file represented by the ZipFile object.

Two methods are provided to obtain ZipEntry objects representing the contents of the ZIP file. The getEntry() method takes a String and returns a ZipEntry for the corresponding file; it returns null if no such file exists in the archive. The entries() method returns a java.util.Enumeration of ZipEntry objects for all the entries in the ZIP file. The getInputStream() method is used to obtain an InputStream for the entry represented by the ZipEntry given as a parameter.

The ZipEntry Class

Each file in a ZIP archive can be represented by a ZipEntry object. ZipEntry objects can be obtained for an existing file from a ZipFile or ZipInputStream object; they can also be created when you make a new ZIP archive with a ZipOutputStream. The ZipEntry class provides methods to retrieve information about the entry (for example, the filename, the compressed and uncompressed size of the file, and the compression method used for the file). The isDirectory() method is provided to determine whether the entry in question is a normal file or a directory.

ZIP Stream Classes

In addition to the ZipFile class, the java.util.zip package has two stream classes that handle compressed data. The stream classes in java.util.zip extend either InflaterInputStream or DeflatorOutputStream as appropriate. These two filtered streams provide a generic interface for handling compressed data.

ZipInputStream reads data in the ZIP format from an InputStream. The getNextEntry() method returns a ZipEntry for the next component in the ZIP file and places the stream at the beginning of the data for that component. The closeEntry() method closes the current entry and advances the stream to return the next entry in the archive. Both methods throw a ZipException if a ZIP-related exception occurs.

The ZipOutputStream provides OutputStream functionality for writing compressed data. The putNextEntry() method takes a ZipEntry as a parameter. A new entry is created in the ZIP file and any data written to the stream goes to the current entry. Two methods are provided to control the compression used to store entries: setMethod() takes as a parameter either ZipOutputStream.DEFLATED (to specify that the next entries should be compressed) or ZipOutputStream.STORED (to specify that any subsequent entries should simply be stored with no compression). The setLevel() method takes an integer from 0 to 9, inclusive, with higher numbers indicating more compression (which takes longer to compress). The setComment() method allows the ZIP file comment to be set.

GNU Zip Stream Classes

In addition to classes for the ZIP compression format, the java.util.zip package provides two classes that support reading and writing files in the GNU Zip format. GNU Zip is a widely used compression format for UNIX. Unlike the ZIP format, the GNU Zip format handles only one file at a time, rather than multiple files and a directory structure. GNU Zip is most often used as a replacement for the UNIX compress utility, so there is no getNextEntry() method for the GZIPInputStream class. In addition, the GZIPOutputStream has no way to specify filenames for entries.

Using JAR Files

A new attribute has been added to the HTML <applet> tag: archives. This tag specifies one or more JAR files that should be downloaded with the applet (obviously, these JAR files contain components needed by the applet). You should still specify the code attribute, even if you give the archives attribute because code is used as the name of the applet class to load. Whenever the applet requests a class, image, or sound file, the archives specified are searched first. If the necessary resource is not contained in one of the JAR files downloaded, the applet contacts the server and searches for the resource as it did with the JDK version 1.0.2. You can specify multiple archive files by separating the filenames with + (a plus sign). A sample applet tag is shown in Listing 36.1.

Listing 36.1. A sample <applet> tag using JAR files.

<applet code="sampleApplet.class"
    archives="sample.jar + icons.jar + commonClasses.jar"
    width="550"
    height="300">
<param name="animal" value="lemur">
<param name="server" value="qa.nowhere.com">
</applet>

Summary

JAR files provide a way to simplify applet distribution. Along with the new code-signing facilities, JAR files should greatly increase the usefulness of applets by making them easier to distribute and allowing trusted code to step outside the narrow limits of the sandbox. Additionally, the java.util.zip package provides support for manipulating ZIP and GNU Zip archives in any Java program.

TOCBACKFORWARDHOME


©Copyright, Macmillan Computer Publishing. All rights reserved.