EricGiguere.com > Articles > Deploying Java Applets |
Screen-friendly version | Set your preferences |
by Eric Giguere
This document, written in 1998, discusses how to deploy your Java applets. Although it was written a few years ago, the information it conveys is still valid today. Read it and you should end up with a good understanding of how applet deployment works.
At some point I will revise the material to include a full discussion of the Java Plug-in and to remove all references to PowerJ, the Java development tool I was working on at the time I wrote this.
The key to understanding applet deployment is to understand web servers and web clients (a web browser is a type of web client, and we'll use the two terms interchangeably).
A web server is an application that runs on a machine connected to the internet or the company intranet (we'll refer to it as the web server machine). Its sole purpose is to listen patiently for connection requests from web server clients. The web server creates a TCP/IP port (port 80 is the default, although you can configure a web server to use a different port number) and services incoming connections.
The basic transaction between a web client and a web server works as follows:
A key concept here is that the client-to-server communication is a stateless communication the web client initiates a new connection each time it makes a request instead of keeping a single connection open. The web server doesn't keep track of individual clients, it merely services the requests as they come in and then "forgets" about them. This keeps network congestion down and allows the server to process many more requests from clients. If you want the server to remember who you are, you have to pass it some kind of "session" information browsers use cookies to do this, for example so that it "remembers" who you are from one connection to the next.
Clients make requests to the server using a simple, partly text-based protocol called HTTP. The most common request is to GET a file:
GET /products/powerj/index.html HTTP/1.0 |
The client sends the GET command, an absolute path to a file and the HTTP protocol version it supports (the server uses this information to tailor its response to the client). In the simplest scenario the web server simply fetches the requested file and returns it to the client. The client can send extra information along with the GET (on separate lines), such as the type of client (so the server knows if it's talking to a Netscape or a Microsoft browser, for example), cookies (for session information), and what kind of data it can accept back in response from the server.
An important thing to remember is that the server always deals with absolute paths, never relative paths. The client is responsible for converting relative path information to absolute paths before making a request. This has important implications for applet deployment, as we'll see later.
The web server is free to interpret the path the client sends it as it sees fit, of course. Usually there is a simple mapping onto the file system. For example, the root of the path might be mapped to c:\html, in which case the path
/products/powerj/index.html |
would map to
c:\html\products\powerj\index.html |
The mapping is configured by the web server administrator (the webmaster). Multiple mappings are possible with most web servers, so for example you might have mappings like this:
Thus the paths:
/products/index.html /scripts/foo.pl /products/powerj/index.html |
would map to:
c:\html\products\index.html d:\util\scripts\foo.pl c:\productinfo\powerj\index.html |
As you can see, interpretation of what a path means is completely up to the web server. Often, paths map directly to the filesystem. Sometimes they map into database entries. Other mappings may allow the web server to invoke extension programs (either as DLLs or as executables) to process the client's request whenever special processing is required.
After interpreting the request, the server sends back a response code, a MIME type, and a stream of bytes. The MIME type (for example, text/plain) tells the client how to interpret the stream of bytes coming back from the server.
As mentioned before, a browser is a type of web client, by far the most common type of web client. The browser deals primarily with HTML, a kind of tagged text. The tags describe either the structure of the document or the formatting to apply. The browser interprets these tags to format the text.
Let's walk through the typical use of a browser:
1. The user types in a URL describing the data to display. URL stands for Uniform Resource Locator and is a standard way of specifying where and how to get a "resource" a text file, image, movie, etc. The URL might be:
http://www.sybase.com/products/powerj/index.html |
The first part, the "http://", tells the browser that it has to use the HTTP protocol when talking to the given server. The rest of the syntax depends on the protocol being used. In this case "www.sybase.com" locates the web server machine and the "/products/powerj/index.html" is the absolute path of the file to fetch on that machine.
2. The browser opens a connection to http://www.sybase.com/ at port 80 (the port number is assumed since it wasn't specified).
3. The browser sends the request:
GET /products/powerj/index.html HTTP/1.0 |
to the server.
4. The server returns the file, say it's text like this:
<html> <body> <img src="gif/powerj_logo.gif" height=50 width=200> <h1>Sybase PowerJ</h1> PowerJ is a great Java development tool! <p> Return to the <a href="/index.html">main Sybase page</a>. </body> </head> |
The connection to the web server is severed after the file is sent.
5. The browser begins processing the text (actually, it usually starts processing the text as soon as it arrives instead of waiting for the connection to end), looking for tags. The <html> tag indicates this is an HTML document, and the <body> tag indicates the start of the body of the page. The first tag in the body is the <img> tag, which indicates that an image should be displayed at the current page location. The attributes in the tag give a URL for the image and its expected height and width.
6. The browser starts downloading the image in the background. It forms a second URL from the URL of the page and the relative path of the image: "http://www.sybase.com/products/powerj/index.html" and "gif/powerj_logo.gif" combine to form "http://www.sybase.com/products/powerj/gif/powerj_logo.gif". It connects to the server and sends
GET /products/powerj/gif/powerj_logo.gif HTTP/1.0 |
and waits for the image to be sent back from the server.
7. Meanwhile, the browser continues processing the page, having reserved space for the image. It changes to larger, bolded fonts and puts out the heading (between the <h1> and </h1> tags), switches back to the normal font and displays the two paragraphs of text (separated by the <p> tag). The second paragraph includes a link to a second page, denoted by the <a> and </a> tags.
8. At some point the image finishes downloading, the second connection to the server is terminated and the image is displayed.
The page display is complete and all communication with the web server has stopped. If the user clicks on the link, the URL "http://www.sybase.com/index.html" is formed and the process starts all over again.
Note how every image, sound, etc. turns into another GET from the web server. This will apply to applets as well, as we'll see below. (From a technological point of view, a browser is much more complicated to write than a web server. At its most basic, a web server mostly serves up files and only needs to support a few operations. A browser must be able to fetch files from servers using a variety of protocols, display or play images, sounds and movies in a variety of formats, process HTML tags, etc.)
Some browsers can run Java applets. They do this by having a full-fledged Java interpreter built right into the browser or loaded as a browser extension (or plug-in). Note that the Java interpreter used by the browser may or may not respect the settings of the CLASSPATH environment variable, depending on which browser you're using. This can affect what happens when you download applets.
A Java applet is embedded in an HTML page using the <applet> tag, as in:
<applet code="main.class" height="100" width="100"></applet> |
When the browser sees this tag, it does the following:
The tricky part in all of this is the downloading of the class file or files that define the applet: the key to understanding applet downloading is to remember that all downloading is done using GET requests to a web server, and that the browser can only send absolute path requests to the web server. To successfully load an applet, you must configure both the web server and the APPLET tag so that the browser will be able to retrieve each file required by the program.
Note: Browsers will not download (for security reasons) any classes whose package name starts with "java.". In other words, if your applet depends on java.awt.event.ActionListener, an interface introduced in Java 1.1, and your browser only supports Java 1.02, then your applet will not load in that browser no matter what files you put on the web server. (There are some techniques you can use, however, to make an applet "degrade" gracefully when running under Java 1.02 while still making use of features in Java 1.1 for browsers that support it. These are described on the Sun website at http://java.sun.com/products/jdk/1.1/compatible/index.html.)
The applet tag has four main purposes:
The first two items are the ones that really interest us, the CODE and CODEBASE attributes, since these are the two that get the applet from the web server onto the browser.
Let's start with the CODEBASE attribute. It specifies the root directory for the Java class files. If it's missing, then "CODEBASE=." is implied, which means that the root directory is the directory that the HTML file came from. This may make more sense with a few examples:
The last example shows you that you can actually set the codebase to point to a completely different web server, which means that your HTML pages can refer to applets that you didn't even write. This, however, has important security implications because untrusted applets are only allowed to connect to the host from which they were downloaded (as opposed to the host that the HTML page came from) keep this in mind if you're connecting to databases.
The root directory determines which server the GET requests for the applet files are sent to and is used to form the absolute paths for each file. Say the applet tag is:
<applet code="main.class" codebase="/java" height="100" width="100"></applet> |
and the HTML file came from http://www.sybase.com/index.html. The browser will then send the following GET request to www.sybase.com:
GET /java/main.class HTTP/1.0 |
Say the "main.class" file requires "Form1.class" to run. The browser would then send the request:
GET /java/Form1.class HTTP/1.0 |
to the server to fetch that file. This continues until all the files that the applet requires are fetched. If an applet depends on a class that has a package name, say powersoft.powerj.ui.ResizePercentLayout, then the GET request looks like this:
GET /java/powersoft/powerj/ui/ResizePercentLayout.class HTTP/1.0 |
In other words, the full package name of the class is used, but with the "." characters replaced with "/" characters to form a path (and ".class" is then appended). So when you put .class files on your web server you have to make sure that the directory structure reflects the package structure of the classes. Remember as well that case matters in Java and on some filesystems (such as Unix or Linux)!
Note that your applet won't run if any of the files that it requires are missing. You will usually see a message in the browser's status area about this, and you can use the browser's Java console (which we'll discuss later) to discover which class is missing. Sometimes this message appears after your applet starts running, because browsers only download class files as they're needed by the interpreter, and the interpreter only needs them when objects are created or static members are used/invoked.
One problem with Java applet downloading is that each class file is fetched using a separate GET request back to the web server. There is a lot of overhead involved in making and terminating connections to the web server, so a complicated applet with more than just a few class files can take quite a while to download. This is where ZIP, CAB and JAR files come into play.
The idea is quite simple: instead of individually downloading class files, package them up into a single file, download them, and then unpack the files on the client side. Only one connection back to the server is required, and by using compression you can reduce the size of the file to be downloaded.
Unfortunately, how you do this depends on which browser you're using! However, the concept in all cases is the same: a tool is used to package a set of Java class files into a single file for download by the browser and the <APPLET> tag is modified to refer to that file.
To support Netscape browsers 3.x and above you use the uncompressed ZIP format (built using PKZIP or WinZip) and the ARCHIVE tag in an applet, as in:
<applet code="main.class" codebase="/java" width="100" height="100" archive="applet.zip"> </applet> |
If the HTML page came from http://www.sybase.com/index.html, then this would turn into a GET request of the form:
GET /java/applet.zip HTTP/1.0 |
To support IE 3.x and above you use the CAB format (build using Microsoft's CAB development package) and a special "cabbase" parameter:
<applet code=main.class codebase=/java width=100 height=100> <param name=cabbase value=applet.cab> </applet> |
This would make the request:
GET /java/applet.cab HTTP/1.0 |
The contents of the CAB are compressed and can be digitally signed.
To support Java 1.1-enabled browsers (Netscape 4.x with patches, IE 4.x, HotJava, etc.) you can also use the JAR format, which is basically a compressed ZIP file:
<applet code="main.class" codebase="/java" width="100" height="100" archive="applet.jar"> </applet> |
Just as with the ZIP file, this would make the request:
GET /java/applet.jar HTTP/1.0 |
JAR files are built using the jar tool that comes with Sun's Java development kit. JAR files can also include digital signature information.
Note that if you use the ARCHIVE= attribute you can specify multiple ZIP/JAR files as in:
<applet code="main.class" codebase="/java" width="100" height="100" archive="applet.zip,powerj.zip"> </applet> |
However, the Netscape browsers currently only download the first ZIP/JAR file, whereas IE 4.x will download them all. Similarly, you can do the same thing for CAB files:
<applet code="main.class" codebase="/java" width="100" height="100"> <param name="cabbase" value="applet.cab,powerj.cab"> </applet> |
Note that if you want to cover all the bases, you can actually specify both ZIP and CAB files in the same applet tag:
<applet code="main.class" codebase="/java" width="100" height="100" archive="applet.zip"> <param name="cabbase" value="applet.cab"> </applet> |
Internet Explorer will ignore the ARCHIVE= tag in favour of the "cabbase" parameter and Netscape will use the ARCHIVE= tag (and pass the "cabbase" parameter to the applet, so be prepared to ignore it if your applet has to process parameters).
If a given class can't be found in an archive, or else if no archives are supported, the browser will simply ask the web server for the individual class files based on the CODEBASE, so you can actually cover all the bases by putting ZIP, CAB and class files up on the server (see below).
So what really happens inside the browser? When the browser processes the APPLET tag and notices that ZIP/CAB/JAR files are referenced, it requests the files from the web server, adds the contents of the files (uncompressing if necessary) to its internal CLASSPATH, and then goes about trying to run the applet.
Now that you understand how applet downloading works, you can easily install applets on your web server with a minimum of fuss. First you figure out how you want to package your applet:
Second, figure out what other pieces have to be included with your applet. For example, if your applet uses any of the classes in the PowerJ class library (the ones whose package name starts with "powersoft.") then you'll have to include those with the applet. Similarly, if your applet uses does any database access you'll have to include the appropriate JDBC driver classes.
How you include those extra pieces depends on how you're packaging your applet. You can, for example, combine everything together into a single JAR/ZIP/CAB file, or you can keep them as separate files. The JAR/ZIP/CAB targets in PowerJ can automatically package up all the necessary files with one important exception for you if you want. The exception is that classes that are dynamically loaded (JDBC drivers being the most common example) are not caught by this process.
The third step is to actually place all the necessary files on the web server in relation to the CODEBASE for the applet, using what you know from parts 4 and 5 of this article. Remember to account for any directory mappings that your web server does.
Again, a few examples might help. Let's say we have a Java 1.1 applet to deploy that depends on the Powersoft classes and on the Sybase jConnect 3.0 JDBC driver. In addition, the applet itself consists of class files that have the package name "mycompany.sample", as in "mycompany.sample.SampleApplet". Say the web server runs on a Windows NT machine and that the root directory of the web server ("/" in GET requests) maps to "c:\webserver\pages".
Example 1: Deploy an applet using ONLY .class files.
<applet code="mycompany.sample.SampleApplet.class" codebase="/applets"> </applet> |
Then the directory structure would look like:
c:\webserver \pages \applets \mycompany \sample SampleApplet.class etc. \powersoft \powerj \ui ResizePercentLayout.class etc. \db Transaction.class etc. \com \sybase \jdbc SybDriver.class etc. |
You have to manually extract the powersoft.powerj.* classes from powerj\java\powersoft\jdk11\release\lib\powerj.zip and copy the jConnect classes from powerj\java\jConnect\classes.
Example 2: Deploy an applet using ZIP files.
<applet code="mycompany.sample.SampleApplet.class" codebase="/applets" archive=SampleApplet.zip,powerj.zip,jconnect.zip> </applet> |
The directory structure is much simpler:
c:\webserver \pages \applets SampleApplet.zip powerj.zip jconnect.zip |
This assumes that you put your applet files into SampleApplet.zip and you collected the jConnect files into jconnect.zip. However, this example will actually fail in Netscape browsers because the browsers won't download more than one ZIP file. The next example shows how to cover all the bases.
Example 3: Deploy an applet using ZIP, CAB and .class files.
<applet code="mycompany.sample.SampleApplet.class" codebase="/applets" archive=SampleApplet.zip,powerj.zip,jconnect.zip> <param name="cabbase" value="SampleApplet.cab,powerj.cab,jconnect.cab"> </applet> |
The directory structure is the most complicated:
c:\webserver \pages \applets SampleApplet.zip SampleApplet.cab powerj.zip powerj.cab jconnect.zip jconnect.cab \mycompany \sample SampleApplet.class etc. \powersoft \powerj \ui ResizePercentLayout.class etc. \db Transaction.class etc. \com \sybase \jdbc SybDriver.class etc. |
The example above will support the maximum set of browsers.
At some point you will upgrade your tools (for example, if a new version of PowerJ is released) and build applets using those new tools. Chances are that the classes you depend on may have changed, but for various reasons you only want to use the new classes with new applets. With some care you can ensure that all your applets coexist peacefully on the web server, even with conflicting class versions.
All classes that are downloaded by a browser have a class loader associated with them. The class loader is an instance of java.lang.ClassLoader and is called by the Java interpreter whenever it needs a class loaded. Browsers use class loaders that know how to fetch classes from a web server by sending a GET request to the web server and then building the class from the byte stream the server returns.
Classes loaded using different class loaders are considered to be different classes by the Java interpreter, even if they have the same name, and even if the same physical .class file is loaded. This is the mechanism by which a browser can load and run multiple versions of the same class, by creating new class loaders for individual applets or groups of applets.
A new class loader is not created for each APPLET tag. Most browsers create new class loaders based on the CODEBASE attribute of an APPLET tag. In other words, if two applets share the same CODEBASE they will be loaded by the same class loader (among other things, this allows the applets to talk to each other via static methods or static data in shared classes). Not all browsers use this algorithm, for example the Netscape 3.x browsers create class loaders based on the document base (the URL of the HTML page).
So to deploy multiple versions of classes keep these two rules in mind:
A caveat: before trying to load a class from the network, the class loader always looks at the local classpath first. Most browsers allow you to install "trusted" classes into their local classpath you might put the powerj.zip on every client machine, for example, to make downloads even faster. If a class is found in the local classpath it is always used, regardless if the version on the web server is different. In general you should avoid installing classes in the local classpath unless you can guarantee that there will be no conflicts.
User groups have permission to reprint this article for free as described on the copyrights page.
Sponsored
Links |
Why are these ads here? |
|
![]() |
Copyright ©2003-2009 Eric Giguere | Send mail about this page | About this site | Privacy policy Site design and programming by Eric Giguere | Hosting by KGB Internet Solutions This site is Java-powered | Get Firefox! This page was last modified on Last modified on September 9, 2003 |