SADP 5th Module Notes
SADP 5th Module Notes
Module 5
We assume that although the client/server systems we build may have multiple clients,
they will have just one server. It is not difficult to extend the techniques to multiple
servers, so this is not a serious restriction. Figure 12.1 shows a system with one server
and three clients. Each client runs a program that provides a user interface, which may
or not be a GUI. The server hosts an object-oriented system. Like any other client/server
system, clients send requests to the server, these requests are processed by the object-
oriented system at the server, and the results are returned. The results are then shown to
end-users via the user interface at the clients
1. By using object-oriented support software: The software solves the problem by the
use of proxies that receive method calls on ‗remote‘ objects, ship these calls, and then
collect and return the results to the object that invoked the call. The client could have a
custom-built piece of software that interacts with the server software. This approach is
the basis of Java Remote Method Invocation.
2. By avoiding direct use of remote objects by using the Hyper Text Transfer Protocol
(HTTP). The system sends requests and collects responses via encoded text messages.
The object(s) to be used to accomplish the task, the parameters, etc., are all transmitted
via these messages. This approach has the client employ an Internet browser, which is,
of course, a piece of general purpose software for accessing documents on the world-
wide web. In this case, the client software is ignorant of the application structure and
communicates to the server via text messages that include HTML code and data. This
is the technique used for hosting a system on the Web.
The basic idea behind RMI is to employ the proxy design pattern. This pattern is used when it
is inefficient or inconvenient (even impossible, perhaps) to use the actual object. (Refer to
Fig. 12.3 for a description of the proxy pattern.)
The proxy pattern creates a proxy object at each client site that accesses the remote object.
The proxy object implements all of the remote object‘s operations that the remote object
wants to be available to the client. The set up is shown in Fig. 12.4. When the client calls a
remote method, the corresponding method of the proxy object is invoked. The proxy object
then assembles a message that contains the remote object‘s identity, method name, and
parameters. This assembly is called marshalling. In this process, the method call must be
represented with enough information so that the remote site knows the object to be used, the
method to be invoked, and the parameters to be supplied. When the message is received by it,
the server performs demarshalling, whereby the process is reversed. The actual call on the
remote method of the remote object is made, and any return value is returned to the client via
a message shipped from the server to the proxy object
1. Define the functionality that must be made available to clients. This is accomplished by
creating remote interfaces.
Remote Interfaces
The first step in implementing a remote object system is to define the system functionality
that will be exported to clients, which implies the creation of a Java interface. In the case of
RMI, the functionality exported of a remote object is defined via what is called a remote
interface. A remote interface is a Java interface that extends the interface java.rmi.Remote,
which contains no methods and hence simply serves as a marker. Clients are restricted to
accessing methods defined in the remote interface. We call such method calls remote method
invocations
A remote interface must extend java.rmi.Remote and every method in it must declare to
throw java.rmi.RemoteException. These concepts are shown in the following example.
The remote interfaces are defined; the next step is to implement them via remote classes.
Parameters to and return values from a remote method may be of primitive type, of remote
type, or of a local type.
All arguments to a remote object and all return values from a remote object must be
serializable. Thus, in addition to the requirement that remote classes implement remote
interfaces, we require that they also implement the java.io.Serializable interface.
Parameters of non-remote types are passed by copy; they are serialized using the object
serialization mechanism, so they too must implement the Serializable interface.
Remote objects must somehow be capable of being transmitted over networks. A convenient
way to accomplish this is to extend the class java.rmi.server.UnicastRemoteObject.
Since it is a remote class, Book must be compiled using the RMI compiler by invoking the
command rmic as below.
Remote objects are thus passed by reference. This is depicted in Fig. 12.5, where we have a
single remote object that is being accessed from two clients. Both clients maintain a reference
to a stub object that points to the remote object that has a field named a. Suppose now that
Client 1 invokes the method setA with parameter 5.
As we have seen earlier, the call goes through the stub to the remote object and gets executed
changing the field a to 5. The scheme has the consequence that any changes made to the state
of the object by remote method invocations are reflected in the original remote object. If the
second client now invokes the method getA, the updated value 5 is returned to it.
The first argument takes the form //host:port/name and is the URL of the object to be
registered; host refers to the machine (remote or local) where the registry is located, port is
the port number on which the registry accepts calls, and name is a simple string for
distinguishing the object from the other objects in the registry. Both host and port may be
omitted in which case they default to the local host and the port number of 1099, respectively.
The process of creating and binding the name is given below.
The complete code for activating and storing the Book object is shown below
The Client
A client may get a reference to the remote object it wants to access in one of two ways:
1. It can obtain a reference from the Naming class using the method lookup.
2. It can get a reference as a return value from another method call.
In the following we assume that an object of type SomeInterface has been entered into the
local registry under the name SomeName.
After the above step, the client can invoke remote methods on the object. In the following
code, the getters of the BookInterface object are called and displayed.
While in the server directory. This command creates the stub file Book_ Stub.class. Copy the
client program into client and compile it.
Run RMI registry and the server program using the following commands (on Windows).
The first command starts the registry and the second causes the Book instance to be created
and registered with the name MyBook.
Finally, run the client as below from the client directory.
The first four lines are usually written as given for any HTML file. We do not elaborate on
these, but observe words such as html and head that are enclosed between angled brackets (<
and >). They are called tags. HTML tags usually occur in pairs: start tag that begins an entry
and end tag that signals the entry‘s end. For example, the tag begins the header and is ended
by. The text between the start and end tags is the element content.
In the fifth line we see the tag title, which defines the string that is displayed in the title bar.
The idea is that the string A Web Page will be displayed in the title bar of the browser when
this page is displayed.
The body contains code that determines what gets displayed in the browser’s window.
Some tags may have attributes, which provide additional information. For example, see the
line
The body contains code to display the string An Application in the font Lucida bright,
bolded, italicised, and in blue color.
This is accomplished by using what is called a form tag in HTML. The complete code that
allows us to enter some piece of text in the web page is given below.
Let us get a general understanding of the above piece of code. Consider the code that begins
with the line
The tag form begins the specification of a set of elements that allow the user to enter
information. The action attribute specifies that the information entered by the user is to be
processed by a Java class called ProcessInput.class, which resides in the package apackage.
There are two primary ways in which form data is encoded by the browser: one is GET and
the other is POST. GET means that form data is to be encoded into a URL while POST
makes data appear within the message itself. See Fig. 12.6 for the considerations in deciding
which of these methods should be used.
The first line states that the data is HTML and the second line begins the HTML code. The
complete code for the servlet is given below.
The architecture for serving web pages is depicted in Fig. 12.7. Assume that an HTML page
is displayed on the client‘s browser. The page includes, among other things, a form that
allows the user to enter some data. The client makes some entries in the form‘s fields and
submits them, say, by clicking a button. The data in the form is then transmitted to the server
and given to a Java servlet, which processes the data and generates HTML code that is then
transmitted to the client‘s browser, which displays the page.
2. Users are classified into two categories: superusers and ordinary members. Superusers are
essentially designated library employees, and ordinary members are the general public who
borrow library books. The major difference between the two groups of users is that
superusers can execute any command when logged in from a terminal in the library, whereas
ordinary members cannot access some ‗privileged commands‘. In particular, the division is as
follows:
(a) Only superusers can issue the following commands: add a member, add a book,
return a book, remove a book, process holds, save data to disk, and retrieve data from
disk.
(b) Ordinary members and superusers may invoke the following commands: issue and
renew books, place and remove holds, and print transactions.
(c) Every user eventually issues the exit command to terminate his/her session.
3. Some commands can be issued from the library only. These include all of the commands
that only the superuser has access to and the command to issue books.
4. A superuser cannot issue any commands from outside of the library. They can log in, but
the only command choice will be to exit the system.
5. Superusers have special user ids and corresponding password. For regular members, their
library member id will be their user id and their phone number will be the password.
Interface requirements It turns out that due to the nature of the graphical user interface, an
arbitrarily large number of sequences of interactions are possible between the user and the
interface
When the user types in the URL for the library, the system presents a log-in screen for
entering the user id and password. If the user types in a bad user id/password combination,
the system presents the log in screen again with an error message.
On successful validation, the system displays a menu that contains clickable options. The
Command State in Fig. 12.8 denotes the general flow of a command. When a certain
command is chosen, we enter a state that represents the command. How the transitions take
place within a command obviously depends on what the command is. All screens allow an
option to cancel and go back to the main menu. If this option is chosen, the system goes on to
display the main menu awaiting the next command.
When the exit command is chosen, the system logs the user out and presents the log in screen
again.
Add Book
The flow is shown in Fig. 12.9. When the command to add a book is chosen, the system
constructs the initial screen to add a book, which should contain three fields for entering the
title, author, and id of the book, and then display it and enter the Add Book state. By clicking
on a button, it should be possible for the user to submit these values to system. The system
must then call the appropriate method in the Library class to create a Book object and enter it
into the catalog. The result of the operation is displayed in the Command Completed state.
From the Command Completed state, the system must allow the user to add another book or
go back to the menu. In the Add Book state, the user has the option to cancel the operation
and go back to the main menu.
Add Member, Return Book, Remove Book
The requirements are similar to the ones for adding books. We need to accept some input
(member details or book id) from the user, access the Library object to invoke one of its
methods, and display the result. So we do not describe them here nor do we give the
corresponding state transition diagrams.
Save Data
When the data is to be written to disk, no further input is required from the user. The system
should carry out the task and print a message about the outcome. The state transition diagram
is given in Fig. 12.10.
Retrieve Data
The requirements are similar to those for saving data.
Issue Book
This is one of the more complicated commands. As shown in the state transition diagram in
Fig. 12.11, a book may be checked out in two different ways: First, a member is allowed to
check it out himself/herself. Second, he/she may give the book to a library staff member, who
checks out the book for the member. In the first case, the system already has the user‘s
member id, so that should not be asked again. In the second case, the library staff member
needs to input the member id to the system followed by the book id
After receiving a book id, the system must attempt to check out the book. Whether the
operation is successful or not, the system enters the Book Id Processed state.
A second reason for the complexity arises from the fact that any number of books may be
checked out. Thus, after each book is checked out, the system must ask if more books need to
be issued or not. The system must either go to the Get Book Id state for one more book id or
to the Main Menu state.
As usual, it should be possible to cancel the operation at any time.
This may be replaced by strings such as Book not found and Member added. Once the file is
read into a string, the RESULT string is replaced by the appropriate result of executing the
command. The following pseudocode gives the idea.
2. To reduce the number of mouse clicks, the user may be given the option to repeat the
command whose result is displayed by the commandCompleted.html file. For example, after
completing the Add Book command, we need to give an option to issue the command once
again so that the user can add another book. Since the code where control should go to
depends on the command that was just executed, some adaptation is in order. This is
facilitated by having the line
Configuration
The server runs with the support of Apache Tomcat, which is a servlet container. A servlet
container is a program that supports servlet execution. The servlets themselves are registered
with the servlet container. URL requests made by a user are converted to specific servlet
requests by the servlet container. The servlet container is responsible for initialising the
servlets and delivering requests made by the client browser to the appropriate servlet.
The directory structure is as in Fig. 12.13. We store the HTML files in a directory named
Library, which is a subdirectory of webapps, which, in turn, is a subdirectory of the home
directory of Tomcat. The servlets are in the package library, which is stored in Library/WEB-
INF/classes. The implementation of the backend classes such as Member, Catalog, etc. is in
the package basicImplementation.
Our implementation requires that the user create an environment variable named LIBRARY-
HOME that has as value the absolute path name of the directory that houses the HTML files.
The deployment descriptor elements are defined in a file called web.xml. While this file
permits a large number of tags, our use of them is limited to mapping the URLs to servlets.
To understand how this is done, first examine the following lines of XML code.
in the HTML file, the string login is mapped to the servlet name LoginServlet.
But the servlet name given by the tag is just a name that is mapped to the fully-qualified class
name of the servlet as below.
doGet are collected into a class named LibraryServlet. This class has the structure shown in
Fig. 12.14.
Execution flow Processing a request sometimes involves simply generating an HTML page,
which is quite straightforward. This is best understood by following a sample command. We
choose as example, the command to remove a book. A somewhat simplified sequence of
what takes place in the course of the execution of this command is shown in Fig. 12.15.
ASP, the difference being that we intersperse Java code with HTML code to create dynamic
web pages. Other technologies such as Ruby on Rails (RoR) are also available.
The code opens up a dialog box for entering a string. After inputting the data, the user can
click ―O.K.‖ The string is stored in response, which is parsed by the code
Integer.parseInt(response);
It returns the integer value stored in the string. (If the string does not have an integer in it, it
would cause an ―exception.‖)
JOptionPane.showMessageDialog(null, message-as-a-string);
Selection Statements
Java supports if else statements and switch statements. Both allow nesting. The syntax of the
if else statement is
Here is a program that accepts the age of a person and prints out whether the person is
eligible to vote.
The next example selects people younger than 20 and all females over 30.
The switch statement allows us to handle the situation when there are numerous cases. Here
is an example.
Loops
Java, like C and C++, allows three types of loops: for, while, and do.
The statement is executed as long as the condition is true. Before each iteration, the condition
is checked. If it is true, the loop is executed once and the condition is checked once again and
the process repeats until the condition is false.
1. Evaluate expression1.
2. Evaluate condition.
3. If the evaluation in (2) returns true, enter the loop and execute the statement, which can be
a block. Otherwise, exit the loop.
4. Evaluate expression2.
5. Go to (2) above.
do The do loop executes at least once. At the end of the first and succeeding iterations, a
condition is checked. If the condition is true, the next iteration is performed. The syntax is
The following example makes the user enter ―Yes‖, ―No‖, or ―cancel‖ (caseinsensitive).
Arrays
Java supports the creation of arrays of any number of dimensions. The process of creating an
array can be thought of as consisting of two steps:
1. Declare a variable that refers to the array. This is not the array itself, but eventually
contains the address of the array, which has to be dynamically allocated.
2. Allocate the array itself and make the variable declared in (1) above to point to this array.
The following code creates a variable that can serve as a reference to an array of integers
The new operator returns the address of the array; this is termed the reference in Java. We
make a hold the reference to the array by writing
The first cell of the array is indexed by 0. If the array has n elements, the last cell is indexed
n − 1.
The following code stores 1 in a[0], 2 in a[1], etc. and then prints these values.
The following program reads in a sequence of numbers and prints them in reverse. The
number of numbers is the first number read in. An array large enough to hold the sequence is
then allocated.
Multi-dimensional Arrays
Let us look at an example of creating multi-dimensional arrays, which will suggest how to
allocate arrays of higher dimension.