To jar or not to jar?

Get the lowdown on using Java Archive (jar) files -- including pros and cons

With browsers that support Java 1.1.x gaining in market share, more developers will be exploring the use of Java Archive (jar) files. Before you open a jar of worms, you should know some of the gotchas involved in using these files. These gotchas can affect most aspects of your project -- from how you write your code, to the service your end-users get.

Jar files are an excellent tool to help overcome some of the hurdles that Java faces, such as packaging software and making a program trusted. They also have drawbacks -- including potentially longer download times, the need to put in extra work to retrieve resources, and a lack of universal support. You need to know the pros and cons and what you want to accomplish with your Java program before you decide whether or not to use jar files.

The history of jar

The Java language makes it easy for the developer to pull together a great many resources and objects for building software. A Java developer can end up with a heavily populated directory structure that often must be made available over the Internet. Anyone familiar with the HTTP protocol knows that a separate HTTP request must be made for every file. This small overhead becomes a big performance issue as the number of files that must be downloaded increases.

From the beginning, a mechanism was needed to simplify deployment of these classes and improve performance. Sun settled first on the zip file format as defined by PKWARE, and the core Java classes are still distributed in zip format. Additionally there was a need for small, modular software components (now known as JavaBeans) that could be packaged into a single file and imported into an integrated development environment (IDE) -- such as Symantec's Visual Café, IBM's Visual Age, or JBuilder by Inprise (the company formerly known as Borland).

These IDEs needed a little more than just a bundle of resources in a zip file, however. They also needed to know more about the classes -- for example, which classes were beans, and which provided support. It was decided that a manifest file would be used for this information, and that the name of the zip file should reflect the availability of the manifest file. A zip file containing the file /meta-inf/ was used and dubbed the Java Archive file or jar -- the standard distribution format for JavaBeans.

Jar files also offered a solution to other vexing problems. Java was built on the philosophy that it's better to build an overly secure application and relax security as needed than it is to build a low-security system and try to patch it on demand. The sandbox model used by browsers is very restrictive, and doesn't allow developers to do some things that could be very useful, even very low risk things, such as reading and writing to a single file on the client machine. A mechanism was needed to allow certain code to perform these operations, so the idea of trusted applets was adopted. Since it would be extremely cumbersome to try to mark every class file as trusted, the logical choice was to wrap them all into one file and mark that one file as trusted. That file has the sig extension -- the digitally signed version of jar.

When and how to use jar

To decide whether or not jar is for you, consider the following:

  • Your target market
  • Security
  • Performance
  • Separate packaging

Target market

The first step in deciding whether to use the jar format is to know your target market. Jar already enjoys universal support from IDEs that deal with JavaBeans. However, jar files are not universally supported by Web browsers. Jar files were introduced with the 1.1 version of Java. A developer should assume that any version of a browser that doesn't run a 1.1 Java virtual machine (JVM) will not understand jar files. A significant number of Internet users still use these older browsers. Many software products also have integrated browsers based on older software -- such as versions of America Online (AOL) and PointCast that use Microsoft's Internet Explorer 3.0. The browsers that currently support jar -- and its digitally signed counterpart, the sig file -- include the latest versions of Netscape's Navigator 4.0x and Sun's HotJava browser 1.1. Even Microsoft appears to fully support jar in its latest incarnation of Internet Explorer 4.0x, even though it has created a proprietary cab file format that serves the same purpose. If you know you need to have backward compatibility with older browsers, you will have to forego using jar files. Sorry.


The next consideration is security. If you're deploying an applet, your code will be restricted to the sandbox model. If you absolutely must have access to the client's file system, you'll have to run your applet as trusted. This requires you to apply a digital signature to a jar file. Your choice has been made.


The next important consideration is performance. Packaging your software in a jar file can either speed up performance or slow it down. Take, for example, Sun's popular Swing classes, a subset of the Java Foundation Classes (JFC), which are packaged in swingall.jar. Version 1.01 contains 1,305 files compressed to 3,657 kilobytes. Suppose you have an applet that uses swingall.jar -- even if you use only one class from swingall.jar, the entire jar file will be downloaded to the user before that one class will be extracted and loaded. In other cases, with small numbers of classes, it may take more time to get the file, uncompress it, and extract the contents than to simply fetch each file individually. As a general rule, if you have a large number of files and you can keep them in tight packages (just the files you need at runtime) you are better off using jar files for better performance.

Separate packaging

Next, you need to decide if all of your classes should be packaged together. You'll probably want to make some of your code available to the world, release some of it only to a certain group, and restrict the rest of it to the administrator's use. So package your classes separately. You may find that some packages need to be in jar files and others don't.

Consider all of these things when you're deciding on jar usage. Syzygy Technologies Inc., for example, is using jar files to develop a breakthrough computerized time and attendance system. In this new product, a server provides access to an employee database using Java database connectivity (JDBC). The client software allows employees to securely log into the system across the Internet and submit their hours using a Web browser. The client interface requires a large number of files, but Syzygy wanted to keep the start-up time to a minimum. In addition, the company wanted the option of running the client as a trusted applet in a future version without having to change the architecture. Syzygy also used some visual JavaBeans in this product. So, what did Syzygy decide to do?

It decided to make the client classes accessible through a Web server, but not through the server classes. It would have to package pieces of the software separately, and make a decision on how to package each piece.

To run as a trusted applet in the future, the client classes would have to be digitally signed. This meant they would eventually have to be packaged in a signed jar file, a transition that would be greatly eased if the classes were packaged that way from the beginning. Add to that the fact that the software relied on some key technologies in Java 1.1x, meaning backward compatibility had already been given up, and the decision to package the client classes in a compressed jar file was clear.

The JavaBeans were stripped down to the classes necessary at runtime and packaged by themselves in a compressed jar. This would allow an easy swap if the company's JavaBeans were to change. The new jar could be easily specified in the HTML file.

Since the server software would be installed once on the server machine, download time was not an issue. However, keeping all the resources in one file really simplified the install process. Because the server would rarely be restarted, overhead on startup (i.e., decompressing files) was negligible, so Syzygy decided to jar the server resources in compressed format as well. The company could have used a zip file, but going with the jar file meant that any Syzygy resource would be fetched from a jar, thus keeping resource retrieval consistent. This decision proved its merit -- in ease -- when the company had a server resource become a client resource.

Working with jar files

Creating jar files is easy. Packaged with the Java Development Kit (JDK) is a tool named jar. Unix users will immediately notice this tool's similarities to tar, a tape archive tool, but jar files are essentially zip files. In fact, you will find that on the command line, jar can unzip most zip files, and a program like PKZIP or WinZip can unjar jar files. Like a zip file, a jar file can store virtually any other file. The main difference between the zip file and the jar file is the manifest. This is used primarily for JavaBeans to let an IDE know which classes are beans. If you are not creating JavaBeans, you do not need to worry about the manifest file, as the jar tool in the JDK handles this automatically. The most common command for jarring your software is jar cvf. The c tells jar to create, the v tells jar to verbosely tell what it is doing, and f tells jar that the next argument will be the file name you want. Let's say you have your class files packaged under myStuff. You also have some images in an images directory. Your command would look as follows:

      jar cvf myStuff.jar myStuff/*.java myStuff/images/*.gif

You would need to use \ instead of / on a Windows system. By default, the contents of the jar are compressed. If you wanted your files uncompressed, you would just need to add 0 as follows:

    jar cvf0 myStuff.jar myStuff/*.java myStuff/images/*.gif

Now, to see what's in your jar file, you can issue the following command:

    jar tvf myStuff.jar

These commands can easily be added to a makefile or a Windows batch file to automatically build your jar files when your software is compiled.

So now you have your jar file and maybe three jar files from other vendors. You just drop them into your classpath and you're ready to go, right? Wrong. For JavaBeans, IDEs may have a directory into which you drop all of your jar files so they can be found. But the Java Runtime Environment (JRE) does not search every directory in your classpath looking for jar files. For Java applications, each jar file has to be specified in the classpath, just like zip files. When you specify your jar files in an HTML file, you need not worry; the browser software is smart enough to figure this out. All you need to do is place the ARCHIVE tag in the APPLET section, separating your jar files with commas:

<applet code="myStuff.myApplet" ARCHIVE="myStuff.jar, windows.jar, swing.jar, companyX.jar">

Now comes the tricky part. Let's say you've packaged everything inside your jar file along with your classes: image files, text files, sound files, and so on. How do you retrieve these resources from inside your program? Many programmers have had working software that they later decide to distribute in a jar file. They then discover that the software is broken because the resources aren't being retrieved. Here's the problem: The JRE looks for class files in the classpath, and it looks for resource files in the regular path. Since the jar file is located in the classpath, and your resources are in the jar, you now have to find your resources by way of the classes! Confused? Don't worry -- you can use java.lang.Class to get your resources for you.

First you need a reference to a Class object. You can use Class.forName(String) to get to a class in another jar file, but typically your resource is already packaged with the class you're in, so getClass() will do. getClass() is a java.lang.Object method, so it can be called from anywhere.

Now that you have a Class object, there are two methods you can choose from: getResource(String) and getResourceAsStream(String). Let's try getResource(String), which will return a URL. The String represents a file name, but remember that you're in the context of the class, so any file name you use will be automatically prepended with the package path. The following is a helper method to get an image file, a common resource in jar files.

 * extra work has to be done in order to get an image from a jar file.
 *  This is a convenience method to fetch an image out of the current
 *  jar file.
 * @param fileName the name of the image file inside the jar file.  
 *        NOTE: The package path of this class will be prepended to the
 *      filename. E.g., if the package-qualified name of this class
 *      is myStuff.myApplet and the resource file name
 *      is "images/myFile.gif", the ClassLoader will search the
 *      jar file for "myStuff/images/myFile.gif".
 * @return an image built from the file if found, null if the file
 *         was not successfully retrieved.
protected Image getImageFromJAR(String fileName){
   if( fileName == null ) return null;
   Image image = null;
   Toolkit toolkit = Toolkit.getDefaultToolkit();
      image = toolkit.getImage( getClass().getResource(fileName) );
   catch(Exception exc){
      return null;
   return image;
1 2 Page 1
Page 1 of 2