Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Java Tip 49: How to extract Java resources from JAR and zip archives

Are you new to the JAR file scene? This new class will help you out!

  • Print
  • Feedback
Most Java programmers are pretty clear on the advantages of using a JAR file to bundle up all of the various resources (that is, .class files, sounds, and images) that comprise their Java solution. (If you're not familiar with JAR files, check out the Resources section below.) A very common question asked by people who are just starting to incorporate JAR files into their bag of tricks is, "How do I extract an image from a JAR?" We're going to answer that question and provide a class to make it super simple to extract any resource from a JAR!

Loading a GIF image

Let's say we have a JAR file containing a bunch of .gif image files that we want to use in our application. Here's how we could access an image file from the JAR using the JarResources:

    JarResources jar = new JarResources ("Images.jar");
    Image logo =
    Toolkit.getDefaultToolkit().createImage (jar.getResource ("logo.gif");


That code snippet shows that we can create a JarResources object initialized to the JAR file containing the resource that we're interested in using -- Images.jar. We then use the JarResources' getResource() method to provide the raw data from the logo.gif file for the AWT toolkit's createImage() method.

A note on naming

The JarResource is a reasonably straightforward example of how to use various facilities provided by Java 1.1 to manipulate JAR and zip archive files.

A quick note about naming. Archiving support in Java actually started out using the popular zip archiving format (check out "Java Tip 21: Use archive files to speed up applet loading"). So, originally, in implementing Java support to manipulate the archive files, all of the classes and whatnot were placed in the java.util.zip package; these classes tend to start with "Zip." But somewhere in the move to Java 1.1, the powers that be changed the name of the archive to be more Java focused. Hence, what we now call JAR files basically are zip files.

How it works

The important data fields for the JarResources class are used to track and store the contents of the specified JAR file:

public final class JarResources {
   public boolean debugOn=false;
   private Hashtable htSizes=new Hashtable();  
   private Hashtable htJarContents=new Hashtable();
   private String jarFileName;


So, the instantiation of the class sets the name of the JAR file and then calls off to the init() method to do all of real work:

   public JarResources(String jarFileName) {
      this.jarFileName=jarFileName;
      init();
   }


Now, the init() method pretty much just loads in the entire contents of the specified JAR file into a hashtable (accessed via the name of the resource).

This is a fairly hefty method, so let's break it down a bit further. The ZipFile class gives us basic access to the JAR/zip archive header information. This is similar to the directory information in a file system. Here we enumerate through all of the entries in the ZipFile and build out the htSizes hashtable with the size of each resource in the archive:

   private void init() {
      try {
          ZipFile zf=new ZipFile(jarFileName);
          Enumeration e=zf.entries();
          while (e.hasMoreElements()) {
              ZipEntry ze=(ZipEntry)e.nextElement();
              if (debugOn) {
                 System.out.println(dumpZipEntry(ze));
              }
              htSizes.put(ze.getName(),new Integer((int)ze.getSize()));
          }
          zf.close();


Next, we access the archive through the use of the ZipInputStream class. The ZipInputStream class does all of the magic to allow us to read each of the individual resources in the archive. We read the exact number of bytes from the archive that comprise each resource and store that data into the htJarContents hashtable accessible by resource name:

  • Print
  • Feedback

Resources
  • Here is the class file JarResources.java http://www.javaworld.com/javatips/javatip49/JarResources.java
  • JARs http://www.javasoft.com/products/jdk/1.1/docs/guide/jar/index.html
  • For more on archiving support in Java, see "Java Tip 21Use archive files to speed up applet loading" http://www.javaworld.com/javatips/jw-javatip21.html