Applets often store their
.class
files in a JAR archive. This bundles all
the classes in one package that still maintains the directory
hierarchy needed to resolve fully qualified class names like
com.macfaq.net.QueryString
. Furthermore, since the
entire archive is compressed and can be downloaded in a single HTTP
connection, it requires much less time to download the
.jar file than to download its contents one file
at a time. Some programs store needed resources such as sounds,
images, and even text files inside these JAR archives. Java provides
several mechanisms for getting the resources out of the JAR archive,
but the one that we’ll address here is the jar URL. Java 1.2 introduces a new class that
allows you to use URLs that point inside JAR archives,
JarURLConnection
:
public abstract class JarURLConnection extends URLConnection // Java 1.2
A jar URL starts with a normal
URL that points to a JAR archive like http://metalab.unc.edu/javafaq/network.jar or
file:///D%7C/javafaq/network.jar.
Then the protocol jar: is
prefixed to this URL. Finally, !/
and the path to the desired file inside the JAR archive are suffixed
to the original URL. For example, to find the file
com/macfaq/net/QueryString.class
inside the
previous .jar
files, you’d use the URLs
jar:http://metalab.unc.edu/javafaq/network.jar!/com/macfaq/net/QueryString.class
or jar:file:///D%7C/javafaq/network.jar!/com/macfaq/net/QueryString.class.
Of course, this isn’t limited simply to Java
.class
files. You can use jar URLs to point to any kind of file that
happens to be stored inside a JAR archive, including images, sounds,
text, HTML files, and more. If the path is left off, then the URL
refers to the entire JAR archive; e.g., jar:http://metalab.unc.edu/javafaq/network.jar!/
or jar:file:///D%7C/javafaq/network.jar!/.
Web browsers don’t understand jar URLs though. They’re used only
inside Java programs. To get a JarURLConnection
,
you construct a URL
object using a jar URL, then cast the return value of its
openConnection( )
method to
JarURLConnection
. Java downloads the entire JAR
archive to a temporary file, opens it, and positions the file pointer
at the beginning of the particular entry you requested. You can then
read the contents of the particular file inside the JAR archive using
the InputStream
returned by
getInputStream( )
. For example:
try { //Open the URLConnection for reading URL u = new URL( "jar:http://metalab.unc.edu/javafaq/course/week1.jar!/week1/05.html"); URLConnection uc = u.openConnection( ); InputStream in = uc.getInputStream( ); // chain the InputStream to a Reader Reader r = new InputStreamReader(in); int c; while ((c = r.read( )) != -1) { System.out.print((char) c); } } catch (IOException e) { System.err.println(e); }
Besides the usual methods of the URLConnection
class that JarURLConnection
inherits, this class
adds eight new methods, mostly to return information about the JAR
archive itself. These are:
public URL getJarFileURL( ) // Java 1.2 public String getEntryName( ) // Java 1.2 public JarEntry getJarEntry( ) throws IOException // Java 1.2 public Manifest getManifest( ) throws IOException // Java 1.2 public Attributes getAttributes( ) throws IOException // Java 1.2 public Attributes getMainAttributes( ) throws IOException // Java 1.2 public Certificate[] getCertificates( ) throws IOException // Java 1.2 public abstract JarFile getJarFile( ) throws IOException // Java 1.2
The getJarFileURL( )
method is the simplest. It
merely returns the URL of the jar
file being
used by this connection. This generally differs from the URL of the
file in the archive being used for this connection. For instance, the
jar
file URL of jar:http://metalab.unc.edu/javafaq/network.jar!/com/macfaq/net/QueryString.class
is http://metalab.unc.edu/javafaq/network.jar.
The getEntryName( )
returns the other part of
the jar
URL; that is, the path to the file
inside the archive. The entry name of jar:http://metalab.unc.edu/javafaq/network.jar!/com/macfaq/net/QueryString.class
is com/macfaq/net/QueryString.class.
The getJarFile( )
method returns a
java.util.jar.JarFile
object that you can use to
inspect and manipulate the archive contents. The
getJarEntry( )
method returns a
java.util.jar.JarEntry
object for the particular
file in the archive that this URLConnection
is
connected to. It returns null if the URL points to a whole JAR
archive rather than a particular entry in the archive.
Much of the functionality of both JarFile
and
JarEntry
is duplicated by other methods in the
JarURLConnection
class. Which to use is mostly a
matter of personal preference. For instance, the
getManifest( )
method returns a
java.util.jar.Manifest
object representing the
contents of this JAR archive’s manifest file. A manifest file
is included in the archive to supply meta-information about the
contents of the archive, such as which file contains the
main( )
method and which classes are Java beans.
It’s called MANIFEST.MF
, placed in the
META-INF
directory, and its contents typically
look something like this:
Manifest-Version: 1.0 Required-Version: 1.0 Name: com/macfaq/net/FormPoster.class Java-Bean: true Last-modified: 10-21-1999 Depends-On: com/macfaq/net/QueryString.class Digest-Algorithms: MD5 MD5-Digest: XD4578YEEIK9MGX54RFGT7UJUI9810 Name: com/macfaq/net/QueryString.class Java-Bean: false Last-modified: 9-11-1999 Digest-Algorithms: MD5 MD5-Digest: YP7659YEEIK0MGJ53RYHG787YI8900
The name-value pairs associated with each entry are called the
attributes of that entry. The name-value pairs
not associated with any entry are called the main attributes of the archive. The getAttributes( )
method returns a
java.util.jar.Attributes
object representing the
attributes that the manifest file specifies for this jar entry, or
null if the URL points to a whole JAR archive. The
getMainAttributes( )
method returns a
java.util.jar.Attributes
object representing the
attributes that the manifest file specifies for the entire JAR
archive as a whole.
Finally, the getCertificates( )
method returns an array
of digital signatures (each represented as a
java.security.cert.Certificate
object) that apply
to this jar
entry, or null
if
the URL points to a JAR archive instead of a particular entry. These
are actually read from separate signature files for each
jar
entry, and not from the manifest file.
Unlike the other methods of JarURLConnection
,
getCertificates( )
can be called only after the
entire input stream for the jar
URL has been read. This is because the current hash of the data needs
to be calculated, and that can be done only when the entire entry is
available.
More details about the
java.util.jar
package, JAR archives, manifest
files, entries, attributes, digital signatures, how this all relates
to zip files and zip and jar
streams, and so
forth can be found on Sun’s web site at http://java.sun.com/products/jdk/1.2/docs/guide/jar/index.html
or in Chapter 15 of my previous book, Java I/O (O’Reilly & Associates, Inc., 1999).
18.223.172.252