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 Javas 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.
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.
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 appletsincluding Netscapes Navigator, Apples Cyberdog, Oracles Powerbrowser, Suns HotJava, and Microsofts Internet Exploreronly 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.
Theres 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.
Many applet developersincluding myselfhave become quite frustrated at the applet security model. The rules of the sandbox keep the user of the applet safe, butthe point that I keep returning tothey limit what you as a developer can do. These limitations can come in infinite formslimited 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 do not have the ability to write to the users 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 hosts 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 users 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 employees 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 users 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 users 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.
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.
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.
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.
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 shouldnt 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 users 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 cant. 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 dont 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 sourcethe proxy server.
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.
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 applications 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 issuefor many developerswill 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.
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, butbelieve it or notnot 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.
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.
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[].
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.
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 ) {}
}
}
}
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 applets 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 applets 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, lets 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.
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 applets 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 applets 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 ita 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.
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.
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, andin factcould 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
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 McDucks 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 everyones 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 68 months of computing will bring you more and more application written totally in Java!
| 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.