- Special Edition Using Java, 2nd Edition -

Chapter 20

Applets Versus Applications


By Luke Cassady-Dorion

When Java first dove headfirst into the public eye, it was pushed mainly as a language for developing small applets which could enhance Web pages. These applets did little more than provide interesting animation. In fact, most applets did not even take advantage of Java’s event model! Fortunately, the Java team was not going to let years of development allow their language to do little more than “soup-up” Web pages. They pushed for acceptance of the language as one that can be used to develop large applications; that push has even extended to state that in most cases Java is a better language choice over C++ or SmallTalk.

(Sand)Boxed Applications

There is little doubt that a number of markets are preparing themselves for a deluge of applications written totally in Java. It should be noted that if your only exposure to Java has been towards applet development, that application development is a much different animal. The most obvious difference is the fact that applets are executed within the contents of a Web browser (HotJava, Netscape Navigator, Microsoft Internet Explorer), while an application exists as a stand-alone program. The second difference is tied to something called a security manger.

While there was much excitement surrounding Java applets when they initially appeared on the market, many people were nervous as to the security implications surrounding these applets. Programmers realized that most people feel comfortable downloading a Web page from an unknown source. Because Java applets are part of a Web page, then it follows logically that people will feel comfortable downloading Java applets from an unknown source.

Java applets are basically applications with a few restriction attached on, and like any application, they could potentially execute malicious code on any host machine and cause severe damage. To eradicate this situation, applet programmers are forced (by the Web browser) to program within a tightly-monitored sandbox. This sandbox surrounds applets and only lets “safe” code execute within its walls. If an unsafe method attempts to execute, a security exception is immediately thrown.

Rules of the Sandbox

There are currently five web browsers which will run Java applets. Because the JVM is responsible for administering security rules, and because each browser has its own VM logic states, each browser is in charge of administering security rules. Concrete standards dictate how a browser needs to implement security, but unfortunately bugs have been found. VM vendors work day and night to fix bugs once they are found, and the near future should prove to be a time where all VMs impose an identical level of security.

While there is a big push to force all browsers to use the same security model, there is also a big push to let the user control this level of security. Of all browsers which will run Java applets—including Netscape’s Navigator, Apple’s Cyberdog, Oracle’s Powerbrowser, Sun’s HotJava, and Microsoft’s Internet Explorer—only HotJava allows the user to select the level at which the security manager starts to enforce his rules. The following table shows in detail at features which HotJava allows the user to configure.

Access Model Settings
Network Access This is the situation supported by Navigator and Internet Explorer. Applets can only access files on the computer which served the applet. This model can be taken in two directions. One will disallow all network access, and the other will allow applets unlimited network access
Class Access This setting specifies where applets can load classes from. Restricted means an applet can only load classes from the which served it. This is the model supported by Navigator and Internet Explorer. Unrestricted means an applet can load classes from any location on the Internet.

As the table indicates, HotJava does allow for user configurable security measures. This is really great if you are developing applets for an intranet, or for personal use. However, you can bet that individuals who are looking at applets from an unknown source will place HotJava in a security mode which uses the same rules as Navigator or Internet Explorer.

For this reason, if you are designing applets for public viewing, you will want to conform to the rules of the applet sandbox. The discussion on applet security in this chapter assumes that developers are developing for this lowest-common denominator of security models.

Inside the Box

There’s no question that applet model is a great distribution model. People are comfortable with the browser, and by integrating your applet into the browser, you are able to take advantage of something known.

As a Java developer, you have to decide whether your project is best suited for applet development, application development, or both. Making this choice up front will make a big difference in determining which restrictions you have to put on your program, and if those restrictions are worth the trade-off for the applet model. You need to decide when security restrictions are too tight, or when the browser model does not properly suit your Java application.

Later on I convert an applet to an application, and add some code to the application which would have thrown a security exception as an applet. See Chapter 21 for installing applications, and coverage of a few cases where C++ or SmallTalk make better languages than Java for developing applications.
 

 

See “Installing Java Applications,” Chapter 21 for more information.
 

Many applet developers—including myself—have become quite frustrated at the applet security model. The rules of the sandbox keep the user of the applet safe, but—the point that I keep returning to—they limit what you as a developer can do. These limitations can come in infinite forms—limited only by the depth of your projects. I concentrate on the most common ones, so you should be able to apply it to any problem that you may come across.

Applets are Read-Only

Applets do not have the ability to write to the user’s hard drive. If you are puzzled by this rule, think how easy it is to write a small piece of code which would hide itself for a week, and then come to life and erase the host’s hard drive. By knowing how to do this, you develop an applet that looks like a Tetris clone, but also writes this malicious code to the user’s drive.

While I do support this restriction, I did find myself banging my head against a wall in annoyance over it. I was hired by a large oil company to develop an applet that new employees would use to learn about the company. There were some animations, and a few brief questions that taught the new employee how the company operated.

The people in charge wanted to know when an employee answered all questions correctly, and also wanted to know how many tries it took the employee to get the answer correct. New employees were asked to answer the questions only once per week. The problem arose when I found out the employer did not want to be notified of the employee’s progress on a weekly basis, but rather wanted to be notified when the employee got everything correct.

This would have been great if I were able to write a log file to the user’s drive, so my initial reaction was to develop the applet as an application. Unfortunately, the company said no; they wanted to take advantage of the user’s familiarity with the browser. The workaround that I developed was to write a server-side application in Java, and to send the data at the end of the user's session to the application. The application would then write the answers to a log file (due to the small number of users, a large database was not needed), for retrieval the following week.

Not only is writing to a host disk prohibited, but also is reading or deleting from a host disk.
 

Applets are not Native

The second restriction placed on developers by the applet security manager is the inability to execute native methods. One of the largest security holes opened up by allowing Applets to execute native methods would be that applets would be able to use pointers to access any memory address. Unlike C++, Java does not give you the ability to peek and poke at memory locations throughout the environment. Where Java is strict in what it lets you do, C++ allows you to do practically anything, anywhere, at any time. While some developers love the freedom which C++ gives, everyone will admit that this freedom makes C++ a language which is chock full of security holes if used for applets.

Once you get used to Java, you will probably prefer this model. Both languages can produce the same product, but debugging is much easier in Java due to the fact that errors are usually caught at compile time, and not runtime.
 

Because native methods allow you freedom that you don't have in Java, it is possible to make create code which is quite malicious. Because C++ allows you the freedom to look at any location in memory, it also allows you the freedom to move the contents of any memory location do a different one. Given this fact, think about how simple it would be to create a C++ application which in effect scrambled the contents of your memory; any data stored in RAM would then become worthless.

Piecing together the logic introduced so far provides concrete reasoning behind earlier coverage of the fact that native methods were not supported by applets. This logic is of course: because C++ methods allow for random manipulation of memory addresses, and because Java applications offer support for execution of C++ code, then Java applications offer support for random manipulation of memory addresses.

Due to the fact that C++ code allows you to do basically anything (and because C++ code can be built into Java applications), it is possible to see that Java applications are not really that secure. Because an application needs to have freedom if it is going to be powerful, Java allows applications the ability to do anything. However, applets are another story, and the browser will put great restrictions on the applet to keep the user “safe.”

The ability to execute native code will often be a major factor when deciding to develop an applet or an application. If native is the only way to go, then you have no choice but to develop your project as an application. You should note that things are changing and the abilities of Java are constantly begin stretched. I do believe that a day will come where reliance on native code is minimal.
 

One-on-One Defense

A third, less understood limitation of the Applet Security Manager is the inability to make network connections to a host other than the one that served the applet.

To determine the originating host, the security manager first looks at the CODEBASE parameter. If that is not present, it looks at the host that served the applet.
 
When attempting to connect to an URL from an applet, you must form the URL in the same manner from which it is formed in the URL that served the Web page. Thus, if your Web page is served from java.luke.org, applets making network calls must use URLs in the form java.luke.org, not luke.org.
 

 

See “Java and URLs,” Chapter 22 for more information.
 

The reasoning behind this is a little less clear than some of the other security rules discussed earlier. In fact, when I first heard of this restriction, I was actually a little puzzled.

A Web browser allows you to connect to any URL which is made available to you. Why then shouldn’t you be able to write an applet, for example, that retrieves information from a variety of Web pages, parses it, and displays it in an organized fashion? The answer to this lies in the fact that a Web browser displaying standard HTML is already a safe environment. The browser only has the ability to understand files of text format, and if a URL contains a document other than one of text format, the file is downloaded to your hard drive (graphics file, for example).

There is a slight security issue at hand here, but it is nowhere as large as the applet security issue. Pretend for a moment that I wrote a malicious application that would stay dormant on a host system for one week, and then come to life and erase the entire host system. I could place this application on my Web site, and post a link to it, titling the link something like “Free Money”. When a user clicked the link, a file transfer would begin, and the malicious application would begin transfer to the user’s machine. He of course would realize that he was not receiving free money, would cancel the transfer, and erase any partial download that occurred. The security hole is small because he is fully aware of the unexpected file transfer.

But a Java application has the ability to dynamically load classes from anywhere! Your applets are allowed to load classes that reside on the same server as the initial class, but imagine the dangers associated with loading classes from anywhere. You could easily load a class from a remote location, and instantly cause severe damage to the host machine.

This leads to the following question: how can one prevent a class from the original server from executing malicious code on the local system? The short answer is that, assuming a developer finds a way to work around the other strict security measures, you can’t. But when a user loads a Web page with a Java applet on it, he knows that the loading is happening, and knows where the classes are loading from. If you don’t trust a site, you have the ability to cancel the load. However, if that an applet has the ability to load a class from any random site, then you lose the security which you gain from knowing the source of the class.

While this restriction can often be very restricting (hence the term restriction) it is in place to protect the user. If your project needs to pull in (or put out) information from a variety of remote sources, then you will not be able to write that project as an applet. However, it is possible to work around this restriction by having an applet and an application work together. The application will be a proxy server which will sit on the server and grab information from a variety of remote sources and then send it out to the applet. As far as the applet is concerned, it only received information from one source—the proxy server.

Local Control

One final security restriction is the inability to cause applications on the host system to begin or stop execution. I doubt that much time needs to be spend covering this topic, as I am sure that the reason behind this is quite obvious. A user does not want to give up control of his computer, and by allowing a remote application to control the execution of local applications, he in effect gives up control of this machine to the remote application.

When I state that applets cannot cause any client-side application to quit, this does include the Web browser itself. If you make a call to system.exit(), a security exception will be thrown. There was a bug in early versions of Internet Explorer that allowed this code to properly execute, but this has since been patched.
 

Total Interface Control

While the Applet Security Manager is a major deciding factor in your development route, you also must consider the other facets of application development that are not given to applet developers.

When you develop an application on your own, you become the master of your own domain. You are allowed to create menus where you want them, and give them whatever name you want. For example, if you were developing an application you could put Copy and Paste under the File menu, while placing Quit under the Edit menu (in fact, you do not even have to have a File menu; you could call if Document). While you will never want to go to extremes such as violating common user interface standards, the point is that you can. This of course extends to allowing you the freedom to customize and tweak every last detail of the application’s user interface. This “total control” can be very arousing, but at the same time it can be very dangerous. I have seen many powerful applications fail because they were too hard to use. This “hard to use” feature is often defined as having a poor user interface.

When you write an applet, that applet exists inside a Web browser and thus you are able to take advantage of the great user interface that has been developed by the engineering team behind the browser. The downfall here is that you might want to alter the user interface in a manner not allowed by the browser.

The user interface issue—for many developers—will be a deciding force when they choose between application and applet development paths. You will have to give it much thought, and the final decision will be a rather important one.

Distributing Your Application

The distribution model discussed earlier is also an issue. It is great to take advantage of the Web page distribution model which most people are familiar (and comfortable) with, but—believe it or not—not everyone is hooked up to the Internet. Additionally not everyone is plugged into a T1 line, and if your project is quite large, download time can be frustrating to those individuals on 28.8K or 14.4K modems. For this reason, you may decide to distribute your project on CD-ROM or floppy disk. You could attempt to distribute a Web browser on that CD-ROM, but that would then mean involved licensing and probably royalty payments. In cases like this, you will almost always want to develop your project as an application.

Developing an Application

Now that you have the knowledge to decide which development path to take, it would help to give you the knowledge to actually do the application development.

If you are familiar with applet development, you know that every applet that you develop must extend java.applet.Applet. To provide integration with the browser, your applets are forced with work within a structure defined in their parent class. This includes overloading init() to provide startup code, overloading paint() to provide on-screen drawing, and so on.

Because an application exists on its own and does not rely on a browser, it is given the ability to create its own structure. The only restriction is that you must provide a method titled main which identifies itself as a starting point for execution.

Often you will want to extend another class, and in those situations, you are often be forced to work within that framework. The most obvious example of this involves developing multi-threaded applications. Here you will almost always write your classes to extend java.lang.Thread, and are forced to work within the framework provided my java.lang.Thread (you have to override run(), and so on).
 

Take a look at this code in listing 20.1. It provides an example of a main method which simply calls another method called beginThisApplicationStimpy(). beginThisApplicationStimpy() would then be given charge of calling other methods associated with the execution of the application.

Listing 20.1 An example of a main method which simply calls another method.

public static void main( String args[] ) {
beginThisApplicationStimpy();
}

If you are not used to programming on command-line systems (such as UNIX, Be, or DOS), the parameter String array being passed to main may be a little confusing. This could be especially true to users of the Macintosh who have only launched applications by double-clicking them. On command-line systems, applications can be launched from the command line (hence the name) and can be passed various parameters which control the execution of the application.

For example, the application vi (for non UNIX folks out there, vi is a text editor superior to another text editor called emacs) can be launched by typing vi. Simply typing vi would bring up an untitled document that is named when you saved it to disk. However if you enter vi sillyGit, then vi is launched and either opens or creates (depending on the prior existence of the file) a document called sillyGit. The word sillyGit would be contained in the 0th position of the String array titled args[].

Remember that static methods cannot make references to non-static variables. This means that your main method cannot do any manipulation on variables that are non static.
 

Because you may want to develop either an application that doubles as an applet or a stand-alone application, I first show you a simple formula for converting an applet into an application, and then I demonstrate some of the jobs you can do in an application, but would be forbidden to do in an applet.

Converting an Applet into an Application

The first applet to convert to an application is in listing 20.2. The output (see fig. 20.1) is a multi-threaded applet which changes colors every 1/10 of a second. The source is well-commented; however, if something does not make sense to you, look through some of the beginning chapters on applet development.

Listing 20.2 The source to a simple applet which changes colors every 1/10 of a second.

import java.awt.*;
public class appletVersion extends java.applet.Applet implements Runnable {
/* MEMBER DATA */
//the canvas where color changes will occur
private Canvas colorCanvas = new Canvas();
Thread changeARoo = null;


/* PUBLIC METHODS */
//init(): takes care or set-up
public void init() {
this.setLayout( new BorderLayout( 10, 10 ) );
this.add( "North", new Label( "Color Changing Applet" ) );
this.add( "Center", colorCanvas );
}


//start the color changing
public void start() {
changeARoo = new Thread( this );
changeARoo.start();
}

//all done, feel free to stop
public void stop() {
if( changeARoo != null ) changeARoo.stop();
changeARoo = null;
}


//the body of the changing thread
public void run( ) {
int i = 0;
int j = 1;
int k = 2;

while( true ) {
i += 1;
j += 1;
k += 1;
colorCanvas.setBackground( new Color( i, j, k ) );
try{ Thread.sleep( 100 ); }
catch( InterruptedException e ) {}
}
}
}

FIG. 20.1

Not an earth-shattering applet, but the conversion process is quite interesting.

Without any objection, I am sure that you will agree that the first step in conversion is to change the applet’s inheritance. Basically, the only valid children of java.applet.Applet are applets, and an application obviously is not an applet. Changing inheritance is far from difficult, and can be accomplished by simply removing the extends java.applet.Applet part of the class signature. Listing 20.3 shows the signature both before and after the “application-ization.”

Listing 20.3 Changing an applet’s signature to begin the transition to application.

public class appletVersion extends java.applet.Applet implements Runnable {
public class applicationVersion implements Runnable {

Earlier in this chapter, I made a point of discussing how as applet developers, you are forced to work within the constraints of a framework defined by the class which you are extending. This of course is the reason that init is called when a Java applet is loaded. I also went on to discuss how an application is required to implement a main method, and this method is charged with developing a “framework” for the rest of the application. Listing 20.4 shows the main method that must be added to your color-changing applet to facilitate the change into an application.

Listing 20.4 This method can be added to an applet to assist in transformation to an application.

public static void main( String args ) {
//create a new frame to house the application. Remember while a Web page
//provides a window to display your applets in, applications are charged
//with this themselves.
Frame f = new Frame( "Application Version" );
applicationVersion theAppVersion = new applicationVersion();
f.add( "Center", theAppVersion );

//resize the frame
f.resize( 300, 500 );

//show the frame
f.show();

//run the methods normally run by the browser
theAppVersion.init();
theAppVersion.start();
}

Before you jump into the listing, let’s cover a few points of applet to application that are addressed in this method. The first change that you notice is that you are using a frame to house the application in. This requirement can often cause some confusion for beginners. The addition of the main method is obvious, but why would an application need to be housed in a frame when the applet does not face this requirement? The answer is that the applet does face this requirement; however, this is provided for the applet by the Web browser. Any entity that desires to exist in any modern GUI needs to be housed in some sort of container, and with Java applets this container is a the Web browser. Applications are forced to create a Frame of their own.

Applets can and usually do take advantage of the browser window (Frame), but are permitted to create their own Frame if they want to. This Frame always carries a banner that alerts the user to the fact that it has been created by a Java applet. Applications also may opt to not exist in a Frame. The discussion was meant to cover the usual case, and not the extreme case.
 

Once the Frame is created, you now have to create an instance of your applicationVersion object to be placed in the Frame which you just created. Because the Frame class supports the add( Object ) method, this step is simply a matter of creating an instance of the applicationVersion object and placing it in the application Frame ( f ).

While an applet’s size is determined by the HEIGHT and WIDTH parameters passed into the applet at load, the size of f is currently undetermined. The resize() method is called on the Frame to simulate the parameters which you do not currently have. In this example, you simulate a HEIGHT parameter of 300 and a WIDTH parameter of 500 with the line f.resize( 300, 500 );.

The last step in this process is simulating the behavior that your applet’s parent provided for it. This of course is the framework that called the init() method at load, and then called the start() method. Here you create that framework with two very simple lines of code:

theAppVersion.init();
theAppVersion.start();.

Well, there you have it—a very simple formula for turning an applet into an application. If you design your applets right, you can follow this system to convert any applet right into an application.

Developing a Stand-Alone Application

You now understand a basic formula for converting your applet into an application. However, you have not yet created an actual application. The applet-to-application conversion often occurs when Web distribution is not a viable situation; however, very often you will have a project which would not be viable as an applet. In these situations you would develop your project from the ground up as an application. Such projects are those which need to read or write local files, execute native methods, or create network connection to servers other than the Web server.

To demonstrate how this need can be filled, I create a small application that reads in employee data from a file on the host system. If this application were written as a applet, all data would have to be stored server-side, and the applet would have to download it every time the applet was invoked.

The application consists of two classes: EmployeeRecord contains information for a single employee, while Application creates and manages the employee files.

While this application is far from monumental, it is important to note that it would be impossible to build as an applet.
 

In listing 20.5 is the EmployeeRecord class. Its constructor supports automatic creation of the employee name and ID fields when the object is created initially. There are also additional methods for getting and setting the data fields.

Listing 20.5 A class for storing employee data.

//class to contain information about an employee
class EmployeeRecord {
private String name;
private String id;

public EmployeeRecord( String theNewName, String theNewId ) {
name = theNewName;
id = theNewId;
}

public void setName( String theNewName ) {
name = theNewName;
}

public void setID( String theNewId ) {
id = theNewId;
}

public String getName() {
return name;
}

public String getID() {
return id;
}
}

The class in listing 20.5 is no feat of programming, and—in fact—could be used in an applet. What cannot be used in an applet is the class in listing 20.6. It is in this class where you actually read in data from a file. The file contains pipe-deliminated data, and you use a combination of the FileInputStream, DataInputStream, and StringTokenizer classes to read in and parse the data file.

Listing 20.6 The Application class actually reads in data from the client machine. Due to the fact that local file i/o is required, this class could not be part of an applet.

import java.io.*;
import java.util.*;
public class Application {
Vector myEmployees; //Vector to contain all employee records
FileInputStream employeeFile; //the physical file which contains employee data
DataInputStream inFile; //Stream to facilitate reading in of data

//Constructor
public Application() {
try { myEmployees = new Vector( 10 );
employeeFile = new FileInputStream( "data.txt" );
inFile = new DataInputStream( employeeFile );

this.createEmployees(); //fill the vector
this.displayEmployees(); //display all info
}
catch( FileNotFoundException fnfe ) { System.out.println( "err: "+fnfe ); }
}

public void createEmployees() {
String temp1;
String temp2;
String temp3;

//loop until end of file condition is reached
try{
while( inFile.read() != -1 ) {
//read in the next line
temp3 = inFile.readLine();

//test for eof condition
if( temp3 == null ) { return; }

StringTokenizer tokenizer = new StringTokenizer( temp3, "|" );
//read in the name
temp1 = tokenizer.nextToken();
//read in the id
temp2 = tokenizer.nextToken();
//create a new record and add it to the vector
EmployeeRecord newRecord = new EmployeeRecord( temp1, temp2 );
myEmployees.addElement( newRecord );
}
}
catch( IOException ioe ) { System.out.println( "err: "+ ioe ); }
}

//method to display data
public void displayEmployees() {
int elementCount = myEmployees.size();

for( int i=0; i<elementCount; i++ ) {
System.out.println( (i+1) +"."+ ((EmployeeRecord)myEmployees.elementAt( i )).getName() );
System.out.println( (i+1) +"."+ ((EmployeeRecord)myEmployees.elementAt( i )).getID() +"\n" );
}
}

public static void main( String args[] ) {
Application myApplication = new Application();
}
}

If you compile the classes, create a pipe-deliminated data file and execute the application, you will see an example of the possibilities of Java applications! If on the other hand you simply want to place your trust in my code (a wise choice), then take a look at listings 20.7 and 20.8. Listing 20.7 contains a sample data file, and listing 20.8 is the output of the application.

Listing 20.7 A sample data file for use in the application in listings 20.5 and 20.6.

|Luke Cassady-Dorion|ADE-DFE
|Paul Dorion|IJN-DOQ
|Patricia Cassady|BEX-TQX
|Gabe Lavella|QKQ-NGE
|Matty Degen|GDC-EEE

Listing 20.8 The output generated by the application.

1.Luke Cassady-Dorion
1.ADE-DFE
2.Paul Dorion
2.IJN-DOQ
3.Patricia Cassady
3.BEX-TQX
4.Gabe Lavella
4.QKQ-NGE
5.Matty Degen
5.GDC-EEE

The Future of Application Development

As computing progresses, the reasons that we develop applications are bound to change. Additionally, you can expect to see new ways to actually develop applications. One major player in this whole new area of computing is distributed computing.

Distributed computing is a process by which objects on different servers (and different platforms) communication to achieve a common goal. This is useful for two main reasons.

First of all, computers are only so powerful, and the most powerful computers cost more money than most people can handle. With distributed computing, you can develop objects that only work on a very small part of a very large project. As an example, imagine if you were told to count the number of gold pieces in Scrooge McDuck’s Vault. You could do it all yourself (and spend years), or you could give a group of friends a handful each. You would tell them to count the amount of gold in their hands, and report the total. You would then be in charge of tallying up their totals. This model could even be expanded further to a point where you would have 10 different people who would collect everyone’s gold totals, and they return their totals to you. The positive effects of this situation are obvious (you could wrap things up in a day instead of a year).

The second positive effect of this situation involves methods in which you can sell the use of your software, but never the software itself. This can be great for developers who want to write code to take advantage of a highly optimized algorithm for rendering what you have developed. You would allow the developer to have access to an object that resides on your server, and he could write code which would ask your object for instructions on rendering.

As you definitely can see, the possibilities for application development are endless. The next 6–8 months of computing will bring you more and more application written totally in Java!


Previous Page TOC Next Page

| Previous Chapter | Next Chapter |

| Table of Contents | Book Home Page |

| Que Home Page | Digital Bookshelf | Disclaimer |


To order books from QUE, call us at 800-716-0044 or 317-361-5400.

For comments or technical support for our books and software, select Talk to Us.

© 1996, QUE Corporation, an imprint of Macmillan Publishing USA, a Simon and Schuster Company.