by Dr. Bryce Curtis
February 3, 1997
This paper discusses how to develop distributed applications on the internet using Java on both the client (applets) and server (servlets). Several client programming models will be identified and their issues will be discussed.
There are two types of Java programs: applets and applications. While both are written in Java, they have totally different distribution mechanisms.
Java applications can be compared to traditional programs such as C or Visual Basic programs. The program must be copied on to the client (via disk or network), or be accessible by the client through a shared network drive. Once it is made available, it can be executed using the Java virtual machine running on the client.
To solve the version update problem of a Java application, the application can have an automatic update method that is called whenever it is started, or by some other policy. This method would contact the distribution server and download the latest version of a class file.
Java applets are downloaded over the internet by getting an HTML page, then executed by a Web browser or the appletviewer on the client. Due to security concerns applets have a restriction that they can only talk to the host from which they obtained the HTML page and embedded applets. Thus, the distribution model is quite simple for applets. Namely, the HTML file, and any Java class files needed to run the embedded Java applets, are downloaded from the Web server. It is therefore the responsibility of the application developer to ensure the required Java class files are on the Web server in the correct directories.
Given the distribution of Java applets is from the Web server via an HTML page, four programming models for Java applets can be identified. They are:
Within each of these classes are several types. These types can be categorized by the following table:
Single HTML Page | Multiple HTML Pages | |
Single Applet per Page | Type 1: Applet contained in web browser (animation, scrolling text)
Type 2: Applet displays windows outside of browser (resembles a windowed application) |
HTML Navigation (each screen is a separate HTML page) |
Multiple Applets per Page | Type 1: Unrelated applets (animation and calculator)
Type 2: Each applet is a different screen of the application |
Several screens are on each page (expense account and calculator) |
In addition, there are global issues associated with the model such as the use of:
for program flow and control.
It should be mentioned before we begin a discussion of the strengths and weaknesses of the different models that all of these models are relevant to the Java programmer. Thus, it is not possible to recommend the use of only one model. There are, however, situations where one model works better than another, and for those cases, recommendations will be made.
One HTML Page with a Single Applet:
An applet can be placed into one of two categories. The first is an applet that uses the web browser as the presentation space. The second is an applet that has multiple screens or windows, which looks and behaves more like an application.
The first category is the simplest of the models to implement and maintain. It can be as trivial as an animation on an HTML page, or do real processing such as a calculator.
The second category can be used to implement a full-function Java application from the web browser. By using Java windows and dialogs the applet looks like a typical windowed application.
An effective way of using this model is to have the applet's main screen displayed in the web page, and have subsequent screens displayed using either the Java windows or dialog create functions. This provides the user the ability to immediately navigate to any screen the developer has provided a direct link to. The web page is similar in function to that of a main menu or toolbar in a windowed program.
A derivation of this would be to have the applet in the web page use a window to display its main screen with menu and toolbar. This would have more of the look-and-feel of a windowed program. The advantage of this approach is that the user can continue browsing to other web pages without having to return to the applet's web page to perform additional functions. This implies that the applet could also load related web pages or HTML-based help into the browser.
Of all the models discussed in this paper, this model works the best for typical web applications. The look and feel is that of a windowed application that many computer users have become familiar with. This is also the model that most closely matches the programming model used by application developers. In summary, the advantages are:
A disadvantage of this model is that the applet which controls the application could become large and unwieldy, giving rise to the ever-increasing memory and disk space problems that plague applications today. Another disadvantage is the displaying of HTML pages from the applet. When a window in the applet instructs the browser to load a new page, the window continues to run after the browser loads this new page. This is because the window is on a different thread than the one passed to the applet by the browser. If the window then instructs a new page to be loaded, the request will not be processed, since the web page that started the applet is no longer the current page shown. Only after navigating back to the current page will the browser load a requested page. An elegant solution is to have the applet load a new page in a new instance of the browser. This can be done by calling
applet.getAppletContext().showDocument(nURL, "_TOP");
from the applet program.
Summarizing, the disadvantages are:
In general, the Single Applet with Windows model should be used when the application requires frequent communication between screens and when several screens use the same information. This is a direct result of the time and network expense incurred when communicating between applets on different pages (as we will see in subsequent sections). Another time to use this model is when the windowed programming style is desired.
There are certain issues about the interaction of the applet and the web browser that must be considered. An applet contains four methods that are called at different stages in its life.
Below is the Simple applet from the Java Tutorial.
You should see " initializing... starting... " above, as the result of the applet being loaded. When an applet is loaded, the following happens:
For the full-function applet, most users will want to be able to use the application while going to other web pages. If windows or dialogs are displayed, they continue to run event after the browser has loaded another page. Only the class file that was specified in the web page will stop. This is because it is on one thread, while the windows are on another thread. If all of the application is to stop, then stop() needs to suspend all threads created by the application. This can be accomplished by hiding all windows in the stop() method, then showing them in the start() method. This was done with the following pieces of code:
// List of all windows opened by application static public Vector windowList = new Vector(); /** ******************************************************* * Show all windows. ******************************************************* */ static public void showAll(Applet applet) { Frame f = null; for (Enumeration en = windowList.elements() ; en.hasMoreElements() ;) { f = (Frame)en.nextElement(); f.show(); } } /** ******************************************************* * Hide all windows. ******************************************************* */ static public void hideAll() { Frame f = null; for (Enumeration en = windowList.elements() ; en.hasMoreElements() ;) { f = (Frame)en.nextElement(); f.hide(); } }
When a window is created, its frame should be added to the windowList using windowList.addElement(this). In the destruction of the window, it should be removed from the list using windowList.removeElement(this).
One HTML Page with Multiple Applets
There are two versions of this model. The first is an HTML page that has multiple, unrelated applets. For example, an animation and a calculator. The second is an HTML page for which some or all of the applets are related. That is, they perform a piece of what could be called the application. They can talk to each other by first finding the applet, then invoking methods on them.
This HTML document is an example of multiple unrelated applets on a web page. There is the Applet Lifetime applet running above, and a button applet running below.
A web application using a single HTML page with multiple collaborating applets could move up and down in the page to simulate showing different screens. The advantages are:
This introduces a unique concept in UI design that the user can view any screen without necessarily visiting the preceding one. Therefore, the applets must pay particular attention to prerequisites before either displaying or processing information.
Consider a bank application that allows a customer to check balances and transfer funds. It has three applets running:
The customer must " logon " by entering his name and PIN before the bank can verify the user, and can identify which accounts he has access to. Thus, the balance and transfer applets should refer the user to the logon applet if the user has not successfully logged on. It could do this by displaying a message indicating this, or jump to the correct location in the page where the logon applet is running.
There are some disadvantages to this model that should be considered.
This solution was prototyped using the following HTML page structure. As a result of this test two major deficiencies were identified. The first is that there is no good way to programmatically scroll the browser from one applet presentation space to another. An attempt was made to use the "name" tag in the HTML page, since it is commonly used to move up or down a page. The second deficiency is that this model consumes too many system resources to be practical.
---------------------------------------------------- | index.html | | | | href="index.html#Mail">Test to go to mail | | | | ---------------- | | |Twelcome.class | | | ---------------- | | | | ---------------- | | |Tlogin.class | | | ---------------- | | ... | | ---------------- | | |Reserve.class | | | ---------------- | | ---------------- | | |ReserveAir.class| | | ---------------- | | ... | | name="Mail" | | ---------------- | | |Mail.class | | | ---------------- | | | ---------------------------------------------------- Procedure: 1. index.html page loaded 2. Pressed link to #Mail 3. Scrolled up page using mouse ------------------------------------------------------------ 1. index.html page is loaded by Netscape - loads all applets then runs init() and start() ------------------------------------------------------------ Twelcome: Entering init()... Twelcome: Exiting init() Reserve: init(): Begin Reserve: init(): Thread = Thread[Thread-3,5,applet-COM/ibm/jaws/app/trsOne/Reserve.class] ReserveAir: init(): Begin ReserveAir: Thread = Thread[Thread-4,5,applet-COM/ibm/jaws/app/trsOne/ReserveAir.class] Reserve: init(): End Reserve: start(): begin Reserve: start(): Thread = Thread[Thread-3,5,applet-COM/ibm/jaws/app/trsOne/Reserve.class] Reserve: start(): End ReserveAir: init(): End ReserveAir: start(): begin ReserveAir: start(): Thread = Thread[Thread-4,5,applet-COM/ibm/jaws/app/trsOne/ReserveAir.class] ReserveAir: start(): End Reserve: paint(): Thread = Thread[AWT-Callback,5,main]Reserve: Enter update()... Exiting update() ------------------------------------------------------------ 2. Pressed linkTest to go to mail in index.html page - destroys Twelcome since it is pruned from memory (Not sure if Twelcome stop() was ever run!!!???) - stops all remaining applets ------------------------------------------------------------ # Pruning applet Welcome from http://swg/com/ibm/jaws/app/trsOne/index.html to save memory. Twelcome: destroy() Reserve: stop(): Begin ReserveAir: stop(): Begin ReserveAir: stop(): Thread = Thread[Thread-4,5,applet-COM/ibm/jaws/app/trsOne/ReserveAir.class] Reserve: stop(): Thread = Thread[Thread-3,5,applet-COM/ibm/jaws/app/trsOne/Reserve.class] ReserveAir: stop(): End Reserve: stop(): End ------------------------------------------------------------ 3. Began scrolling up page using mouse on Navigator scroll bar - starts pruning applets right and left as I scrolled up file - destroy() is called on applet that has been pruned - as I scroll up to ReserveAir, the Navigator realized it was destroyed so it created it again using init() on a new thread - as I scroll up to Reserve, the Navigator realized it was destroyed so it created it again using init() on a new thread - when I got back up to the top, Twelcome was init() again ------------------------------------------------------------ # Pruning applet TRS Login from http://swg/com/ibm/jaws/app/trsOne/index.html to save memory. # Pruning applet COM.ibm.jaws.app.trsOne.Reserve from http://swg/com/ibm/jaws/app/trsOne/index.html to save memory. Reserve: destroy() # Pruning applet COM.ibm.jaws.app.trsOne.ReserveAir from http://swg/com/ibm/jaws/app/trsOne/index.html to save memory. ReserveAir: destroy() ---> applet must have been pruned: 24372568 on http://swg/com/ibm/jaws/app/trsOne/index.html#Mail # Pruning applet COM.ibm.jaws.app.trsOne.SelectAir from http://swg/com/ibm/jaws/app/trsOne/index.html to save memory. # Pruning applet COM.ibm.jaws.app.trsOne.ReserveCar from http://swg/com/ibm/jaws/app/trsOne/index.html to save memory. # Pruning applet COM.ibm.jaws.app.trsOne.SelectCar from http://swg/com/ibm/jaws/app/trsOne/index.html to save memory. # Pruning applet Search for Hotel from http://swg/com/ibm/jaws/app/trsOne/index.html to save memory. ReserveAir: init(): Begin ReserveAir: Thread = Thread[Thread-19,5,applet-COM/ibm/jaws/app/trsOne/ReserveAir.class] ReserveAir: init(): End ReserveAir: start(): begin ReserveAir: start(): Thread = Thread[Thread-19,5,applet-COM/ibm/jaws/app/trsOne/ReserveAir.class] ReserveAir: start(): End # Pruning applet COM.ibm.jaws.app.trsOne.SelectHotel from http://swg/com/ibm/jaws/app/trsOne/index.html to save memory. ---> applet must have been pruned: 22785944 on http://swg/com/ibm/jaws/app/trsOne/index.html#Mail Reserve: init(): Begin Reserve: init(): Thread = Thread[Thread-20,5,applet-COM/ibm/jaws/app/trsOne/Reserve.class] Reserve: init(): End # Pruning applet COM.ibm.jaws.app.trsOne.ReserveList from http://swg/com/ibm/jaws/app/trsOne/index.html to save memory. # Pruning applet List of Trips from http://swg/com/ibm/jaws/app/trsOne/index.html to save memory. Twelcome: Entering init()... Twelcome: Exiting init() ------------------------------------------------------------
NOTES:
So, each time the applets in index.html are run, at least 9% of system and user resources are lost. After starting and stopping Navigator 3 times, the system must be reboot to recover lost resources.
From the above trace and notes it can be concluded that the single HTML page with multiple applets is not a practical application programming model . There is no efficient way to scroll between the applets and a disproportionate number of system resources are consumed.
Multiple HTML Pages, Each with a Single Applet
The Multiple HTML Pages, Each with a Single Applet model modifies the previous model by making each of the applets a separate HTML page. Implied is that each screen or view that is presented to the user has its own URL.
This hints at a new concept that an individual object (which is what an applet is) has its own associated URL. Of course, this implies that the object must be able to show itself to be viewable.
There would be a minimum granularity associated with this type of object. It could be a task such as a mortgage calculation, a piece of information such as an account balance, or any number of other functions. It would, however, be meaningless to take it to the extreme of having every string or array represented this way.
If we assume that a URL represents the view object , a bank account balances view object could be accessed by a customer. This solves the problem of downloading all applets used by the application in the previous model, since only the account balances applet is required.
Since the URL represents a view, another new concept based on Web browser functionality can be introduced: The view can be save and later visited again. If the URL is saved as a bookmark , the user can quickly return to the same account balance screen, but with the updated balances reflecting any changes since he last visited the screen. This allows the user to jump to any of the views of the application. As mentioned in the previous model, each applet must ensure the prerequisites have been completed before continuing.
Not only can the URL be saved as a bookmark, but it can be given to someone else who might need to see the same view. As an example, consider a trip expense account applet on which an employee enters his expenses incurred during a business trip. While on the trip, he could enter expenses by going to its URL. Then, once all expenses have been entered, the URL could be sent in an e-mail note to accounting for processing and payment.
Obviously, HTML pages can contain more than just an applet. They can have text, pictures, and links to other pages. However, by combining this information with the applet can become very powerful. By putting information and links on the expense account applet, the employee could have access to corporate guidelines about travel, allowable daily allowances for food and hotel, restaurants in the area, directions on how to get back to the airport, ...
The application developer has the flexibility to hide " view " objects from the user by not giving him a link to the URL or by placing the HTML page in a protected directory. This could be used to restrict customers from seeing the list of all customers and accounts that a teller may need, or to allow the developer to develop and test new functions (with new screens) before making them available to the customer.
By associating an applet with a URL we obtain several advantages:
The user gains flexibility and some new capabilities from the Web browser model. However, the application developer is presented with a new set of challenges. They are:
In general, the Multiple HTML Pages, each with a Single Applet model could be used when each screen in the application sends requests to the web server for processing, then displays the results. This is similar to the way HTML forms are used to obtain user input for processing by a CGI-BIN program. If different screens need to share information between them, then this model will not run efficiently.
There are provisions in the Web browsers to enable applets loaded from the same HTML page to communicate with each other and call each other's methods. If the applets are on different pages, then only the applet on the current page is running. The others stopped running when the browser left the HTML page. Thus, there is no way for the running applet to call a method on a previous applet. Even if a previous applet is allowed to run after leaving the HTML page (by overriding the stop() method), the current applet cannot locate a previous applet.
Suppose you don't really need to call a method of a previous applet, but you just want some information that the user entered on it, such as the customer name. At first glance, it appears that several methods could be used to save a parameter, then read it by a different applet. However, given the security restrictions on applets,
Currently, there are only two ways for applets to get information from a previous applet. The first way is to go through the server. The server could save this information locally or on another server as a database entry or as part of the state of an object that both applets talk to. The second way is to use a static public class that resides on the client's hard file.
This first method was tested using a Java object on the server (implemented as a servlet). A state object was started on the server and remained active until the server was shut down. Thus, every client talked to the same instance of the object. A hash table with the client address plus parameter name as the key, and the actual parameter as the data was used to store the parameters and capture the state of the application. This permitted several different clients to access their own version of the same parameter name.
Another approach would give each client its own instance of the hash table and have the server access the correct instance based on a unique identifier from the user. This could be thought of as the application state object that binds the applets on different HTML pages together. This object would be responsible for enforcing application policies such as " you must logon before viewing this URL. "
Prototyping of this method revealed that using the server to save the application state was quite slow. The applets would create the remote connection to the object and initialize required variables during init(), load the state variables during the start() method, and save the state variables back during the stop() method. Testing with both IIOP and HTML as the method of remote object access, it was discovered that this process took from 10 to 30 seconds. Much of this time was consumed by the loading of class files needed by the applet and IIOP (tested using Navigator 3 beta 6). While class files appear to be cached efficiently in the final version of Navigator 3, times from 2 to 30 seconds were still observed, with the longer times being less frequent.
A problem resulting from this inconsistent timing behavior was discovered. The applet being stopped and the new applet being started are on different threads, thus the reading of state from the new applet frequently occurred before the saving had even begun. Since there is no way to share information between the two applets, the web server read the state before the write had occurred. (The object is synchronized, but not the request from the browser to the web server.)
Communication Via a local class file
The second method makes use of a static public class file located on the client in Netscape's java\classes directory. Anytime an applet uses that class, the loader first checks to see if it is local before attempting to download it from the server. By placing the class on the client, the applet always gets it locally. By making it static, the applet always gets the same instance. Thus, there is an effective way to save the application state and any other global variables. This worked quite well in the prototype. The only problem is that this breaks the applet distribution model of automatically downloading all classes from the server. Not to mention reintroducing the problem with version control that applets nicely solve. To use a new version the user must explicitly copy the static public class file into the java\classes directory. (The class could have built-in version control to get the latest class file from the server using the same technique as discussed for a Java application under the Distribution Model section.)
Multiple HTML Pages, Each with Multiple Applets
This model is obtained from the previous model by adding more applets to an HTML page. There aren't really any new issues to be resolved. The question is, what can be gained by doing this?
If the travel expense account applet is considered, a productivity enhancement might be to add a calculator to the bottom of the page. This would allow the employee to tally several expenditures or just check to make sure his credit card isn't " maxxed out ".
There are several issues that affect all of the models described above. Many of them have more to do with programming style rather than necessity. Regardless, they should be discussed since many conventional applications today use them.
Many times images can be used to enhance user understanding and interaction over a " text and button " interface. Web surfers are familiar with clicking on images embedded in HTML pages to navigate. The drawback is that these images are static, with the x,y location of the cursor shown in the status line of the browser. This experience can be greatly enhanced by an applet that monitors the mouse position and movement to provide feedback to the user. It can be in the form of status on the status line of the browser, bubble help at the cursor, changes to the image, or automatic playing of sounds.
Toolbars are quite common today. Just about every program utilizes one, so much so that users have come to expect them as standard. Toolbars can be easily implemented by placing a separate toolbar applet at the top, bottom, or side of an HTML page. As an applet, it can be written once, then used simply by embedding it in the HTML page. A toolbar could do some processing, but in the browser paradigm it would most likely load a new URL, maybe placing some pre-initialized data in the state object. Since the toolbar is really an applet, the toolbar could be utilize buttons, choices, icons, images, or any other Java component.
Once browsers add the functions necessary to enable applets to add icons to the browser toolbar, the application and the browser will begin to look more like a single program, rather than separate entities.
As discussed in the Multiple HTML Pages, Each with a Single Applet model, applets can be surrounded by URL links to other Web pages. When effectively applied, the user can gain tremendous productivity by having all the information he needs without trying to remember, " Where did I see that? ". Without it he would spend time looking for it, or possibly make a bad decision because he didn't have the time.
There are issues about the interaction of the applet and the web browser that must be considered when developing a Java web application. They are the applet life cycle, threads, backward, forward and reload buttons, and cache.
As discussed in the Applet Life Cycle section under the programming models there are four stages in the life of an applet. To summarize, they are:
Backward, Forward, and Reload Buttons:
The backward button on the browser is used to display previous web pages that the user has viewed since the browser was started. As a previous page is displayed, the cached page is retrieved, and no check is made with the server to see if the web page has changed. If the web page has an applet, the current applet's stop() method is called, and the previous page applet's start() method is called. There is a possibility that the previous page's applet has been purged from memory. In that case the applet is restarted by running its init() and start() methods. If the backward button is pressed enough times, the user will reach the first page loaded when the browser was started. Then this button will be disabled.
The same basic operation holds true for the forward button, except for the obvious exception that the next web page is displayed. The only time the forward button is enabled is when the backward button was pressed and there is still a next page that the user has previously viewed. The user can navigate backward to the first page viewed, and forward to the last page viewed as long as no links from any of the pages are pressed. Once a new link is pressed or a URL is loaded, all forward pages are lost and the forward button is disabled. Once this occurs, all applets on the lost pages are destroyed. Any reload of a lost page causes the reload of the applet (or a cached copy) and the init() and start() methods to run.
The reload button checks to see if the web page has changed and reloads it from the server if it has. Otherwise, the browser reloads the same page from the cache. If the applet in the page has changed, but the page has not, no check is made to see if the applet needs to be reloaded. According to Netscape, holding down Shift while pressing reload should cause the page and applet to be reloaded. However, the observed behavior does not always follow this rule. Once a reload is performed, all forward pages are lost.
The browser uses a cache to save previously loaded web pages and applets. The intent is to increase performance by eliminating data transfers from the server when the required data has recently been downloaded.
The Verify Documents option determines how often the browser will check with the server for changed web pages. The options are:
There are two caches used by Netscape: a memory cache, and a disk cache. The most recently used pages are saved in memory and on disk until they drop off the list or are purged. Since the disk cache is usually larger than memory, they remain in the disk cache even after being purged from memory. It appears that the best way to force a reload of an applet from the server is to clear both caches, then reload the page. This will get a new copy of both the page and applet from the server.
A standard applet has two threads that all methods within it use. The first thread is used for init(), start(), stop(), and destroy(). This is the thread that most of the applet's work will be done on. The second thread is a callback thread from Java that is used for the paint() method and any action() or event method. Both of these threads are stopped when stop() is exited. That means that even though the page and applet are no longer visible, they continue to execute until all processing in the stop() routine has been completed.
Additional threads can be created using the Thread() constructor in Java or by creating a window or dialog frame. Explicitly created threads must be stopped and disposed of when they are no longer needed or before the applet is disposed of, otherwise the program will leave executing threads lying around, consuming resources. Threads created as a byproduct of creating frames remain as long as the frame hasn't been destroyed. Once destroyed the threads are disposed of. Of course, if the frame uses a create threads constructor, it must first free all of its threads before being terminated. There is no start() and stop() methods called when a window or dialog frame is destroyed, so the threads need to be freed when a window destroy event is received by the event handler method.
Application help can be provided in the form of an HTML web page. This provides a generic, cross-platform help format that any browser can display. Since help usually consists of links and images, HTML is well suited for implementing the help function.
Help can be displayed as part of the applet's HTML page, surrounding the applet or be located below it. It can also be contained in its own HTML page or pages. An applet also has the capability of launching a new instance of the web browser. This was utilized in our prototype to display help on different topics. The HTML help file loaded could depend upon the topic passed, or could represent an index into a single file as shown below.
/** ******************************************************* * Show help. ******************************************************* */ static public void help(Applet applet, String topic) { try { URL nURL = new URL(applet.getDocumentBase(), "Help.html#" + topic); applet.getAppletContext().showDocument(nURL, "_TOP"); } catch (MalformedURLException ex) { System.out.println("Error in URL"); } }
One feature that is difficult to accomplish in an HTML implementation is that of " Help Search ". To solve this problem, both a table of contents and index of all key words can be generated. This would be much easier to perform with a tool that automatically builds these two HTML pages.
The client (applet running on the web browser) can use local or remote objects in the Java web application programming model. Instances of local objects can only be accessed by applets on the same page. Remote objects can be persistent so the same instance of the object can be reactivated at a later time. Persistence ranges from the object that remains available as long as the web server is up (transient), to the object that remains until it is explicitly destroyed (saved in an object store).
To use local objects, the applet need only call a method in a given class file that is located on the client, or that can be downloaded from the web server. Because of the applet limitations discussed in the two Multiple HTML Pages models , a given instance of these objects can only be used by applets that are on the same page. The only situation where the instance can be shared across multiple pages is when the class file has been copied to the client, not just downloaded from the server.
An example is shown below which allows an object to be shared between applets on the same page:
public class RCommon extends Object { // Determines if initialize was already run static public boolean initRun = false; // Global/program state variables static public String userId = ""; static public String rTripName = "Trip to Olympics"; static public Date rLeaveDate = new Date(); static public Date rReturnDate = new Date(); static public String rLeaveCity = "Austin, TX"; static public String rReturnCity = "Atlanta, GA"; ... rest of variables //****************************************************** // Initialize structures if not already done so. // // This method must be explicitly called by each applet // in case the user jumps to a middle trs page without // going to the index.html main page. //****************************************************** static public void initialize(Applet applet) { if (initRun == false) { initRun = true; ... initialization code for all variables } } ... add all other methods as "static public" }
The objective of remote object programming is to make the client programming model be remote/local transparent, not necessarily local/remote transparent.
Local/remote transparency implies that the applet can be written without regard to remote issues. By setting a compile flag or by making a remote initialization call, the object is then remotely accessed. The problem with this is that there must be a structure imposed on the applet to enable this to work. There are activation space, persistence, and instance issues, to name a few.
A better approach to remote object programming is to access all objects as if they were remote. This implies that instead of doing new's, a create method is called. If the object framework is correctly implemented then remote/local transparency can be obtained. This means that the object can be on the client in another process, or on another system. Either way, the applet will run without modification. Prototypes using the Managed Object Framework (MOFW) and IIOP have shown that this is indeed possible.
To use a remote object the client needs a proxy or stub of that object. The stub's purpose is to marshall the request onto the network stream. A server-side skeleton is needed to demarshall the request, process it, calls the actual object, obtains the result, and marshalls it back to the client. MOFW has an emitter that generates these stubs and skeletons from a Java source file for the IIOP protocol. At a minimum, three files are needed:
MOFW introduces another object called a managed object that provides persistence, collections, transactions, and security. It also needs a stub and skeleton if it is to be remotely accessed.
There are four different ways to create objects that can be associated with various models found in OOA/OOD. They are:
Class Level - Using a Specialized Class:
This is the simplest of the remote object types since the client needs no active instance prior to making the create call. It is the most useful in cases where a single object is being created in the client space.
The penalty for this simplicity is that a location parameter must be passed in to the create method on a class, where the location logically names a " factory " even though no such factory may actually exist.
Client Code: // Creates a user and returns a user reference User u = User.create("UserList", "John Doe");
Static - Using a Specialized Factory:
This method is a two step process that locates a factory, then uses the factory to create a new object. It works well when the client creates multiple objects, since the server must determine how to locate a factory only once. After that, creates can be performed quickly and efficiently.
If the factory only knows how to create users, then another factory would be required to create other objects. This would double the number of classes required. On the other hand, if the factory were able to create other objects as well, then only one class would be added. However, this class would have to change every time a new object type is added to the list of objects the factory knows how to create.
Client Code: // Find factory that knows how to create users UserFactory factory = getUserFactory(); // Choose a constructor on the factory based on parameters User = factory.createUser("John Doe");
Dynamic - Using a Transient Copy:
This method and the next method require a collection to locate a specific object instead of a factory. The dynamic method first locates a collection, then adds a local transient copy of the object to the collection. Thus, there are two active instances.
There are several advantages to this method. The first is that the client can make method calls on the transient copy prior to finally making it a managed remote object. This gives the client the opportunity to initialize its state before making it remote. Another advantage is that fewer classes are required on the client, since the collection is generic. Finally, if this method is used exclusively, there is no need for the object class to have a create method or an associated factory class.
The disadvantage is that there are two copies of the instance: one on the client, and the other on the server. The programmer could easily confuse which object was being used or fail to update the remote object if changes were made to the local instance.
Client Code: // Find the appropriate collection that contains users Collection c = getUserCollection(); // Create a transient user object User tu = new User(); tu.name = "John Doe"); ... // Make the transient copy remote User u = (User)c.createFromCopy(tu, "User");
Message - Using a Data Stream:
The message method is the most abstract and difficult to use. It requires programming to two generic types of objects in order to effect the create. The advantage is that there are only two classes on the client, and that these can be implemented very efficiently. Also, all of the methods above can be implemented in terms of this one. The disadvantage is that the stream must be assembled correctly so the object can be initialized. Also, depending upon whether the stream class includes type casting, type cast checking may be lost. This could engage the programmer in a challenging debug session.
Client Code: // Find the appropriate generic collection Collection c = getCollection("User") // Create a stream to hold data Stream s = new Stream(); s.writeString("John Doe"); // Create a remote object straight from the data in the stream User u = (User)c.createManaged(s, "User");
While network transfer speeds are quite fast, remote object method calls still cannot respond as quickly as accessing the object locally. As the frequency of the number of methods called on an object increases, the remote latency will become more obvious to the user. Added to this the possibility that the web server may be accessed through a slow link such as a modem, significant latency could be observed.
Given an object that infrequently calls other objects, yet its own methods are frequently called by the client, a simple caching model that explicitly copies the remote object from the server to client, and updates the remote object can be quite useful.
If an object has two routines, one to get and one save its internal data, then this can be easily implemented. The saveData method takes a string that has all of the variables encoded in it. The getData method generates one of these strings. This is basically a type of object pass-by-value .
Object: Class User { public String name; ... public String saveData(String value) { ... initializes the variables } public String getData() { ... creates a string from all variables } } Client Code: // Create a remote object User uRemote = User.create("UserList", "John Doe"); // Create a local object User uLocal = new User(); // Get local cached copy uLocal.saveData( uRemote.getData() ); // Do some processing on local copy ... // Save local copy back to server uRemote.saveData( uLocal.getData() );
This type of caching worked well for the Multiple HTML Pages with Single Applet model. The program state was saved in a remote object. During start() the state was retrieved, then it was saved back to the server during stop(). Between these two times, the state variables could be accessed and modified without having to go back to the server.
To be more useful, caching should be built in to a managed object framework that hides this from the client programmer.
We have discussed four general classes of client programming models. For web applications we found the Single Applet with Windows , Single HTML with Multiple Applets , and Multiple HTML Pages, Each with a Single Applet models to be the most interesting. The Single Applet with Windows model works best for applications that require frequent communication between screens, or that share information between them. The Multiple HTML Pages, Each with a Single Applet model can be used as an extension of the HTML forms model, where each screen obtains its information from the server without interaction with, or dependencies on other screens. Finally, it was determined that the Single HTML with Multiple Applets model does not work well for applications due to large resource consumption and unusual resulting program structure.
Last update on February 3, 1997
The owner of this document is Bryce Curtis (bcurtis@austin.ibm.com)