Chapter 35
JAR Archive Files

by Alan Liu

JAR files are a new feature introduced in JDK 1.1. The name JAR stands for Java ARchive and also deliberately resembles the name of the tar UNIX archiving format. The similarity between JAR and tar files ends there, however. While tar files are simple, uncompressed file archives, JAR files provide compression, backward compatibility to existing Java applets, portability, and security features. JAR files will soon become the standard, preferred way to distribute Java applets.

Why JAR?

The JAR file format brings several important advantages to applets. These include performance improvements and enhanced portability. JAR files also implement the JDK 1.1 Security Model, described in detail in Chapter 36, "Java Security in Depth."

JAR archives are not the first Java archive format to be supported. Since version 1.0, the JDK has used the uncompressed ZIP file classes.zip to store the JDK system class files as a single disk file. Netscape Navigator 3.0, following this procedure, allows the APPLET tag to load an applet from a similar ZIP file. Microsoft Internet Explorer 3.0 can load ActiveX controls from Microsoft's CAB files.

JAR files will probably replace these other mechanisms over time. They offer the following benefits which make them the preferred choice.

Bundling

A complex applet may consist of dozens or hundreds of Java classes, each stored in a separate class file (recall that each public class must be stored in a separate file). To run the applet, the Web browser makes an HTTP connection to load each file, as needed, from the server. Establishing an HTTP connection entails overhead, and if the class files are small, as they typically are, much of the time spent loading an applet can be spent establishing the multiple HTTP connections required to load all the class files.

The first and most obvious benefit of a JAR file is that it combines several class files into one archive file, which can then be transmitted from the server to the Web browser over a single HTTP connection. Furthermore, JAR files can contain not only class files but also audio and image files, allowing an entire applet to be downloaded in one transaction. This is useful not only for improved performance, but also because it simplifies applet distribution.

Compression

JAR files, like CAB files (but unlike classes.zip and the ZIP files used Netscape Navigator 3.0), are compressed using a variant of the standard Lempel-Ziv algorithm. For example, the JDK 1.1 TicTacToe demo is 20 percent smaller when archived as a JAR file, while the ImageMap demo is 5 percent smaller (it contains more image files, which are already compressed). By not only aggregating multiple files but also compressing them, JAR files can greatly reduce the time needed to download an applet.

Backward Compatibility

Because JAR archives preserve the directory hierarchy of their files, and because they can be loaded through a simple change to the APPLET tag, JAR archives can be used transparently with existing Java applets, with no change to the applet code.

Portability

Portability, in this case, refers to two things: portability between browsers, and portability between Web servers.

Browser incompatibility between Netscape Navigator, Microsoft Internet Explorer, and other browsers is a familiar bugaboo to anyone who has developed Web pages or Java applets. In terms of applet archives, this incompatibility is worse than ever: Navigator supports uncompressed ZIP files, but Internet Explorer doesn't support anything (CAB files are for ActiveX controls, not Java applets). Prior to JDK 1.1, a Web developer had no portable archiving mechanism.

JAR files solve this problem by providing a single, browser-independent archive file format. Since JAR support and tools are implemented entirely in Java, any browser supporting the standard JDK 1.1 library will be able to support JAR files.

The other side of the portability question becomes clear when you try to move an applet from one Web server to another. For example, imagine that you have developed an applet running on a Windows 95-based Web server. Your files have descriptive names such as NavigationBarAnimationPanel.class--a legal file name under Windows 95. Now you need to move your Web site to a Macintosh-based Web server. Unfortunately, you discover that Macintosh file names are limited to 31 characters, and you are forced to rename not only your Java source files, but also your classes within them (since file names must match the names of classes they contain).

(To see this firsthand, try downloading and installing the JDK 1.1 beta 2 documentation files on a Macintosh. Many of the file names will be truncated, and your browser won't be able to navigate links to those files.)

By storing an applet's various class files and other resource files in a single JAR file, you make the applet immune to any idiosyncrasies of the Web server's underlying file system.

Security

As of JDK 1.1, the Java Security Model has been extended. It is now possible, by using authenticated JAR archives, for the user to verify the origin of an applet, mark it as trusted, and give it additional privileges. This makes it possible for new types of applets to be written, such as word processors that store files on the local user's hard disk.

When to Use JAR Archives

You should consider using a JAR archive for your applet if any of the following apply:


TIP: JAR files are useful chiefly for applets. If you are developing a Java application, JAR files won't be as useful to you, although you may still use them as a general-purpose archiving format.


Using JAR Archives

In order to use JAR archives, you need to know how to create them using the jar tool, and you need to know how to load them using the APPLET tag.


TIP: There is nothing different about the way an applet in a JAR archive is written.


Here is a quick overview of the process:
  1. Create a JAR archive containing the applet's class, image, and audio files.


    The only requirement here is that the applet's files should all be located in a single directory, or in subdirectories of that directory. For example, you may have a directory containing all your class files, and two subdirectories named images and audio, which contain JPEG and AU files.

    From within the applet's main directory, use the command:

    jar cvf jar_file_name input_file_1 input_file_2 É

    Example:

    jar cvf Blinker.jar *.class images audio

  2. Copy the JAR archive to the Web server.

  3. Change any APPLET tag that refers to your applet to preload the JAR file.


    Add the ARCHIVES field to your APPLET tag as follows:

    <APPLET CODE=applet_name ARCHIVES=archive_name>...</APPLET>

    Example:

    <APPLET CODE=Blinker.class ARCHIVES=Blinker.jar>...</APPLET>

  4. Use a JAR-compatible browser.


    In most cases, this means a browser that implements JDK 1.1 or later.


NOTE: At the time of this writing, only HotJava 1.0 preBeta2 and the appletviewer tool of JDK 1.1 support JAR files. Netscape Navigator 4.0 will probably support JAR files in its final release. Microsoft has not yet committed to supporting all of JDK 1.1, so it's unknown whether Internet Explorer 4.0 will support JAR files or not.


jar Tool

The jar tool allows you to create, list, and extract files from JAR archives. It deliberately resembles the UNIX tar tool, both in function and in usage. Like other tools in the JDK, the jar tool is implemented as a Java application, making it portable to any platform supporting Java.

Creating a New Archive To create a new archive, use the options cvf. The c option tells jar to create a new archive. The v option tells jar to output verbose diagnostic messages to the console while it is working, so you can see what is being added. The f option tells jar to create an archive file of the given name. For example,

jar cvf Foo.jar *.class images

will create a new JAR archive named Foo.jar in the current directory. The archive will contain all the class files in the current directory, as well as the complete images directory and all its contents.

As an example, connect to the directory containing the JDK 1.1 demo TicTacToe.


NOTE: A better example might be the ImageMap demo, but because of a bug in the JDK 1.1 beta 2 appletviewer tool, use the TicTacToe demo. See "Compatible Browsers" later in this chapter.




A listing of the directory contents reveals a class file and two subdirectories containing audio and image files.

D:\java\demo\TicTacToe>dir
 Volume in drive D is NTFS20
 Volume Serial Number is 6C98-56B4
 Directory of D:\jdk1lb2\java\demo\TicTacToe
01/13/97  10:04a        <DIR>          .
01/13/97  10:04a        <DIR>          ..
12/16/96  11:29a        <DIR>          audio
11/19/96  12:34p                   139 example1.html
12/16/96  11:29a        <DIR>          images
11/19/96  12:34p                 3,454 TicTacToe.class
12/06/96  10:27a                 7,593 TicTacToe.java
               7 File(s)         11,186 bytes
                          1,575,772,160 bytes free

Create a new subdirectory that will contain the JAR file version of this applet.

D:\java\demo\TicTacToe>mkdir jar

Now create the JAR archive.

D:\java\demo\TicTacToe>jar cvf jar\TicTacToe.jar *.class audio images
adding: TicTacToe.class
adding: audio/beep.au
adding: audio/ding.au
adding: audio/return.au
adding: audio/yahoo1.au
adding: audio/yahoo2.au
adding: images/cross.gif
adding: images/not.gif

Notice that when directories are listed as input files to the jar tool, their contents are added to the archive and the directory names are preserved.

When the jar tool creates a new archive, it automatically adds a manifest file to the archive. In most cases, this will suffice. However, should you wish to create your own manifest file, and have the jar tool use that, you can do so by specifying the m option.

Listing Archive Contents
The jar tool can also list the contents of a JAR archive. For example:

jar tvf Foo.jar

will list the contents of Foo.jar.

To continue with the TicTacToe demo applet, connect to the jar subdirectory you created previously. Use the t option to obtain a listing.

D:\java\demo\TicTacToe\jar>jar tf TicTacToe.jar
META-INF/MANIFEST.MF
TicTacToe.class
audio/beep.au
audio/ding.au
audio/return.au
audio/yahoo1.au
audio/yahoo2.au
images/cross.gif
images/not.gif

Notice that a manifest file has been added to the archive automatically. See the section "Manifest File," later in this chapter, for more information about manifest files. You can obtain more information by using the v option.

D:\java\demo\TicTacToe\jar>jar tvf TicTacToe.jar
  1045 Mon Jan 13 11:52:18 PST 1997 META-INF/MANIFEST.MF
  3454 Tue Nov 19 12:34:26 PST 1996 TicTacToe.class
  4032 Tue Nov 19 12:34:26 PST 1996 audio/beep.au
  2566 Tue Nov 19 12:34:26 PST 1996 audio/ding.au
  6558 Tue Nov 19 12:34:26 PST 1996 audio/return.au
  7834 Tue Nov 19 12:34:26 PST 1996 audio/yahoo1.au
  7463 Tue Nov 19 12:34:26 PST 1996 audio/yahoo2.au
   157 Tue Nov 19 12:34:24 PST 1996 images/cross.gif
   158 Tue Nov 19 12:34:24 PST 1996 images/not.gif

Extracting Files from an Archive Finally, the jar tool can extract files from an archive file. For example, to extract the TicTacToe.class file, type the following:

D:\java\demo\TicTacToe\jar>jar xvf TicTacToe.jar TicTacToe.class
extracted: TicTacToe.class, 3454 bytes

If you are following along on your computer, remove the file you just extracted so that upcoming examples will work.

D:\java\demo\TicTacToe\jar>del TicTacToe.class


TIP: You cannot use the x option to extract a single file within a subdirectory of the JAR archive. Instead, specify the entire subdirectory and, after it has been extracted, discard those files that you do not need.


APPLET Tag

The APPLET tag embeds a Java applet into an HTML file. It has a number of attributes that specify the name of the applet to be loaded, the URL to use to locate the applet, and the size of the applet on the page. In addition to these attributes, any number of parameters can be specified. For example,

<APPLET CODE="FooMain.class" WIDTH=100 HEIGHT=120>
<PARAM NAME="color" VALUE="red">
<PARAM NAME="background" VALUE="blue">
</APPLET>

The CODEBASE attribute indicates the URL base from which to load the class file. If no CODEBASE is specified, then the URL of the referring page is used. For example, the browser will try to load the following applet from http://www.foo.com/applets/FooMain.class:

<APPLET CODE="FooMain.class" CODEBASE="http://www.foo.com/applets/" WIDTH=100 HEIGHT=120>
...
</APPLET>

Beginning with JDK 1.1, Sun has specified changes to the APPLET tag which allow the class to be loaded from a JAR archive, that is downloaded before the Java applet class is located.

Loading from a JAR archive can be specified in two ways: using an attribute or using a parameter. First, an attribute named ARCHIVES can be used. For example:

<APPLET ARCHIVES="Foo.jar" CODE="FooMain.class">
...
</APPLET>

When the browser reads this tag, it first downloads the Foo.jar file from the server, then tries to find the FooMain.class in Foo.jar. If the browser cannot find the class in the archive, it looks at the location specified by the CODEBASE, as usual.

Alternatively, the JAR archive can be specified as a parameter. This parameter should have the name ARCHIVES. The parameter's value is the name of the JAR file. For example:

<APPLET CODE="FooMain.class">
<PARAM NAME=ARCHIVES VALUE="Foo.jar">
...
</APPLET>

It's possible to specify more than one JAR archive to be loaded. To do so, insert the string " + " (a plus sign surrounded by spaces) between the archive file names, as follows:

<APPLET ARCHIVES="foo.jar + foo_images.jar + foo_sounds.jar" CODE="FooMain.class">
...
</APPLET>

Specifying a JAR archive in an APPLET tag is a performance optimization, instructing the browser to preload a specified archive and use that archive, if possible, when locating classes. If the JAR file is not found, or if a required class file is not found in the archive, then the usual search procedure, as defined by JDK 1.0, will be followed. Specifying a JAR file to preload does not prevent the usual search paths from being tried and used if necessary.


CAUTION:
If you have been using the Netscape Navigator APPLET tag, which allows loading of an applet from an uncompressed ZIP file, you should be aware of a subtle change in Sun's APPLET tag definition: Netscape's APPLET tag uses an ARCHIVE attribute, while the tag described here uses an ARCHIVES attribute--notice the different spelling.




As a final example, look at the APPLET tag used by the TicTacToe demo in JDK 1.1. The file example1.html, in Listing 35.1, contains this APPLET tag.

Listing 35.1example1.html Without JAR Archive Loading

<title>TicTacToe</title>
<hr>
<applet code=TicTacToe.class width=120 height=120>
</applet>
<hr>
<a href="TicTacToe.java">The source.</a>

Copy this to the subdirectory jar that you created previously.

D:\java\demo\TicTacToe>copy example1.html jar
        1 file(s) copied.

Now edit it to add the APPLETS attribute. It should look like Listing 35.2 when you're done.

Listing 35.2example1.html with JAR Archive Loading

<title>TicTacToe</title>
<hr>
<applet code=TicTacToe.class archives=TicTacToe.jar width=120 height=120>
</applet>
<hr>
<a href="TicTacToe.java">The source.</a>

Now you should be able to run the TicTacToe applet from the JAR archive created earlier.

D:\java\demo\TicTacToe\jar>appletviewer example1.html
loading d:\jdk1lb2\java\bin\..\lib\awt.properties

Compatible Browsers

By the time you are reading this, versions of Netscape Navigator or Microsoft Internet Explorer may be available that support JDK 1.1 and the JAR file format. However, if you are using Navigator 3.0 or Internet Explorer 3.0, you will find that they will not load JAR files. The reason is simple: These versions use JDK 1.0, not 1.1.

At the time of this writing, Sun has released version 1.0 preBeta2 of its HotJava browser which supports JDK 1.1 and JAR files. You can also use the appletviewer tool of JDK version 1.1 or later to test the loading of JAR files. Specify an APPLET tag, as described previously, in an HTML file, and then load that HTML file with appletviewer.

JAR Archives and Security

The Web allows content to be downloaded. The Java architecture allows executable content to be downloaded. While this opens up tremendous new possibilities, it also opens up new risks. While a static text or image file can do little to harm its receiver (Snow Crash notwithstanding), a piece of code can, potentially, do a lot of damage--witness computer viruses.

In order to protect recipients of downloaded code, Java implements a security model known as the "sandbox." This is a domain within which an untrusted piece of Java code may do whatever it wishes. By restricting the applet's activities to a well-defined area, a browser can run an untrusted applet while still protecting everything outside the sandbox--typically, the local machine's memory, files, and disks, and the network.

Running within the sandbox is not a hindrance to an applet that displays a clock, a stock ticker, or an animated navigation bar. But what about an applet that implements a word processor or a spreadsheet? For such an applet to be useful, it needs to interact with the user's local machine in order to read and write files (unless the applet wants to tackle the formidable task of maintaining user data files on a remote server). To do this, it needs to leave the sandbox. Under JDK 1.0, it was difficult for applets to do this. Under JDK 1.1, using authenticated JAR archives, applets have a standard way to easily gain trusted status.

Manifest File

The first entry in any JAR file is a collection of meta-information about the archive. The jar tool generates this meta-information automatically and stores it in a top-level directory named META-INF. This directory always contains what is known as the manifest file, META-INF/MANIFEST.INF (see Listing 35.3).

Normally, if no authentication is applied, the manifest file contains checksums for the other files in the archive. For example, you can extract the manifest file for the TicTacToe.jar archive, created previously, as follows:

D:\java\demo\TicTacToe\jar>jar xvf TicTacToe.jar META-INF
extracted: META-INF/MANIFEST.MF, 1045 bytes

Listing 35.3Manifest File MANIFEST.MF of TicTacToe.jar

Manifest-Version: 1.0
Name: TicTacToe.class
Hash-Algorithms: MD5 SHA
MD5-Hash: TsjcL1vWU7k4/HDkwOnvHg==
SHA-Hash: IGRKfYKD8Cpef7+or5ZKqYp3bh0=
Name: audio\beep.au
Hash-Algorithms: MD5 SHA
MD5-Hash: kZv279ZIA/H6mOw4t8W8XA==
SHA-Hash: JgfdUl4/uzNq5yUy3e07ZXwvNOc=
Name: audio\ding.au
Hash-Algorithms: MD5 SHA
MD5-Hash: 23oJDEp/LqCZC70AEIOsVQ==
SHA-Hash: dpRUB8DKzEP0Grc7DIrXclPMjJ8=
Name: audio\return.au
Hash-Algorithms: MD5 SHA
MD5-Hash: tBUwkF2qeyor/nmPeF81hg==
SHA-Hash: ABV7Ar1gRYQmpp7kSbkH3GN+YOA=
Name: audio\yahoo1.au
Hash-Algorithms: MD5 SHA
MD5-Hash: Bq9PhKz6zAWrgQvtGWS8zQ==
SHA-Hash: qUO3jWxRvJWIp25S9XRQk5lbLaY=
Name: audio\yahoo2.au
Hash-Algorithms: MD5 SHA
MD5-Hash: 6lhsclKkFy5iBu+km+DAVQ==
SHA-Hash: Gfc7hOmtTmM31JJlHJZgkMm2elo=
Name: images\cross.gif
Hash-Algorithms: MD5 SHA
MD5-Hash: gTJaDGQtdz1Y4W+hHWxjgA==
SHA-Hash: plA3I8zoS3u8XXj9+vutZupQo0U=
Name: images\not.gif
Hash-Algorithms: MD5 SHA
MD5-Hash: SJspO4DooHqq9ndFnn6S6w==
SHA-Hash: MmqEk9R8pMigNK3xDi2yK1cyyZ8=

The manifest file lists all the files in the archive, together with values labeled MD5-Hash and SHA-Hash. Listing 35.3 shows a typical manifest file. MD5 and SHA are message digests, also known as one-way hash functions. A hash function takes an arbitrary piece of input data and produces a piece of output data of a fixed size. MD5 hashes are 128 bits; SHA hashes are 160 bits. The term "one-way" refers to the fact that it is difficult to produce the same hash from two different inputs.

The message digests in this manifest can be used to confirm that the archive has not undergone accidental corruption: As a browser reads each file from the archive, it can compute its MD5 and SHA hash values and check them against those in the file. Deliberate corruption, on the other hand, cannot be ruled out, since anyone who intentionally corrupts an archive file can also modify the manifest file's corresponding hash.

It is possible, however, to detect deliberate corruption of the files in a JAR archive. To do so, the JAR archive must be "signed." This is analogous to signing a paper document with a pen. It indicates, with certainty, that the given JAR archive came from the indicated source. In fact, a digital signature is stronger than a physical one; it is harder to forge, it cannot be repudiated by the signer, and the signed document cannot be modified.

Private Keys, Public Keys, and Certificates

In order to sign a JAR archive, you must first create a private key, a public key, and a certificate. The public and private keys are paired pieces of data used to create digital signatures and to encrypt data. A certificate is a guarantee by one entity, usually a trusted public organization, that another entity's public key is valid. (In this case, more specifically, a certificate conforms to the X.509 standard published by CCITT.) The combination of a public key and a certificate can be used to confidently verify a digital signature.

javakey Tool

The javakey tool handles the creation and management of identities, public and private keys, and certificates. The details of key and certificate creation and management are beyond the scope of this chapter, but they are covered in Chapter 36, "Java Security in Depth."

Once you have a public key, a private key, and a certificate, you need one more thing to sign an archive. This is the directive file, which specifies the signer, certificate, and the name to be used for the signature file. The directive file consists of fields of name-value pairs. The required fields are given in Table 35.1. For an example directive file, see Listing 35.4.

Table 35.1 Required JAR Directive File Fields
Field Name Field Value
signer Name of the signer. This name must already be registered in the persistent database maintained by javakey.
cert Certificate number to use for the given signer. The first certificate is number 1.
chain Chain depth for a chain of certificates. This is currently not supported; use 0.
signature.file A name, 8 characters or shorter, to assign the signature and certif-icate files that will be created in the META-INF directory of the signed JAR archive.

Listing 35.4Example JAR Directive File LiuJDF.txt

signer=liu
cert=1
chain=0
signature.file=LIUSIGN

To sign a JAR file, use the javakey tool with option -gs and two arguments: the name of the directive file, and the name of the JAR archive file. For example, the following command signs the archive Foo.jar using the directive file LiuJDF.txt:

javakey -gs LiuJDF.txt Foo.jar

In response to this command, javakey would create two entries in the META-INF directory of the archive; the signature file LIUSIGN.SF and the certificate file LIUSIGN.DSA.


NOTE: Although a purported feature of JAR archives is the ability to sign individual files, the current release of the javakey tool does not seem to support this.


java.util.zip Package

New to JDK 1.1 is the package java.util.zip, which contains a number of classes that manipulate JAR archive files. Although you will typically not need to use these classes, it is helpful to understand them at a general level. You do not need to use these classes to create or load JAR files; you can use the jar tool and the JDK 1.1 APPLET tag for that.

The java.util.zip package defines the Checksum interface. The Checksum interface defines a protocol for a class that computes the checksum of a stream. java.util.zip provides two classes that implement the Checksum interface: Adler32 and CRC32.

Classes

The package java.util.zip defines of the following fourteen classes.

ZipFile
The class ZipFile represents a ZIP archive file. It provides methods that read the file's entries. As of JDK 1.1, this class does not allow you to create a new archive file or to edit an existing file's contents. You must use the jar tool for that.

ZipEntry ZipEntry represents an entry in an archive file and has methods that get and set various attributes of the entry, such as its name, modification time, and CRC checksum. In addition, by calling the method ZipFile.getInputStream() with a ZipEntry object, you can obtain an InputStream object that you can use to read the entry's contents.

Adler32 and CRC32 These classes implement the Checksum interface. They compute two different checksums of a data stream. CRC-32 is a standard industry algorithm; Adler-32 is a checksum developed by one of the ZLIB authors, Mark Adler, with similar characteristics but lower computational costs. To use these classes, you instantiate them and pass them to the constructor of CheckedInputStream or CheckedOutputStream. In fact, this is just what DeflaterOutputStream and InflaterInputStream do, using the Adler32 class.

CheckedInputStream and CheckedOutputStream These classes extend java.io. FilterInputStream and java.io.FilterOutputStream. They maintain a checksum of the data being read or written. The constructor for each of these classes takes a stream object, and an object implementing the Checksum interface, which allows the caller to specify different checksum algorithms for different streams.

Deflater and Inflater These classes implement general purpose compression and decompression using the standard deflate compression algorithm. For more information, see RFC 1951, available at http://www.internic.net/rfc/rfc1951.txt.

DeflaterOutputStream and InflaterInputStream These classes extend java.io. FilterInputStream and java.io.FilterOutputStream. DeflaterOutputStream compresses its output stream; InflaterInputStream decompresses its input stream. These classes form the basis for other compression and decompression streams that use other protocols including GZIP (GZIPOutputStream and GZIPInputStream) and ZIP (ZipOutputStream and ZipInputStream).

GZIPOutputStream and GZIPInputStream These classes extend DeflaterOuputStream and InflaterInputStream. They use the standard GZIP compression algorithm to compress the output stream and decompress the input stream. For more information, see RFC 1952, available at http://www.internic.net/rfc/rfc1951.txt.

ZipOutputStream and ZipInputStream These classes extend DeflaterOuputStream and InflaterInputStream. They use the ZIP compression algorithm to compress the output stream and decompress the input stream.

Reading a JAR File Programmatically

Typically, you will not use the classes in java.util.zip to read a JAR file; you will specify the archive to be read in your APPLET tag, and the browser will do the rest. However, should you need to read a JAR file yourself, this section will get you started.

First, enter the following file (Listing 35.5), named DumpJAR.java.

Listing 35.5Source Code for DumpJAR.java

import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.Enumeration;
class DumpJAR
{
     public static void main(String[] args)
     {
          String file_name = args[0];

          try

          {

               ZipFile zip = new ZipFile(file_name);

               PrintEntryNames(zip);

          }

          catch (java.io.IOException e)

          {

               System.out.println("Exception " + e);

          }

     }
     public static void PrintEntryNames(ZipFile zip)
     {
          for (Enumeration e = zip.entries(); e.hasMoreElements(); )
          {
               ZipEntry entry = (ZipEntry)e.nextElement();
               System.out.println(entry.getName());
          }
     }
}

Now compile it:

D:\java\demo\TicTacToe\jar>javac DumpJAR.java

If you run this application on the TicTacToe.jar file created earlier, you will see a listing of its contents. Notice that the entries are not shown in the same order that the jar tool produces. You should not depend on the order of entries returned by the ZipFile.entries() method.

D:\java\demo\TicTacToe\jar>java DumpJAR TicTacToe.jar

audio/return.au

audio/ding.au

TicTacToe.class

audio/yahoo1.au

audio/yahoo2.au

images/not.gif

audio/beep.au

images/cross.gif

META-INF/MANIFEST.MF

JAR File Format

The JAR file format is based on the general-purpose, freely usable ZLIB file format. This is a portable file format designed to store multiple files in a directory hierarchy. The ZLIB format is not specific to any single compression method; however, the deflate compression scheme is commonly used. This is the compression method used in JAR files. The deflate protocol is based on a variant of the Lempel-Ziv algorithm, LZ77, and features low compression overhead and well-defined runtime memory requirements. This makes it a good general-purpose compression protocol. For more information about ZLIB, refer to RFC 1950 and RFC 1951, available at ftp://ds.internic.net/rfc/.

In general, you won't need to concern yourself with the details of the JAR file format, since you'll interact with JAR files through the jar and javakey tools and possibly the java.util.zip package.