401 Final Project FAQs
                          (Updated on June 21)

1) It is confusing since there are seem to be so many things to do. What
is the big picture, i.e., what is the objective of this project?

You want to implement RMI, assuming that you don't have the java.rmi.*
package.  You can use other Java packages, such as java.io.*, java.net.*,
and java.util.*, java.reflect.*, which provide sockets, streams, hash
tables, etc.

2) What do you mean by "implement RMI"?

In Java RMI, once a service is looked up by
remoteObject = Naming.lookup("serviceName")
then the client can invoke a method of remote server object remoteObject by
something like:
remoteObject.methodName(args)

In this project, the name look-up is provided by the SimpleRegistry service,
which you tested in Assignment 4.
So, there is nothing you need to do regarding the lookup service.
You need to implement the remaining parts, i.e., the modules shown in
Fig. 5.6 of the textbook, other than object A (client application) and
object B (server implementation), without using java.rmi package.

The client must generate a stub using the info contained in the ROR it gets
back from the SimpleRegistryServer, in response to a service name lookup,
and send a method invocation request to the server.

On the server side, the dispatcher, RRM, CM and the skeletons must be
implemented.  However, in the template given in this project, many of
them can be combined into a single program, called "yourRMI".

3) Can you elaborate on what needs to be done on the server side?

Let's find some analogy with what you already know.
You have experience using FindServer in Assignment 3.
The service in that exercise was provided FindServerImpl.class, which
was contacted by FindClient directly.

So you may think ZipCodeServerImpl, for example, is like FindServerImpl.
However, in the suggested implementation, clients send requests to
"yourRMI", which is a dispatcher. So, all requests are funneled through it,
and therefore, the address part of each ROR contains the address of "yourRMI".
Moreover, "yourRMI" creates an instance of ZipCodeServerImpl and registers
itself with SimpleResigtryService.

4) Can you elaborate on what needs to be done on the client side?

The project description says:
// You must write the stub class for ZipCodeServerImpl.java yourself.
// It won't be automatically generated by rmic as in the standard RMI.
// For each method in ZipCodeServerImpl.java, there should be a
// corresponding method in the stub class.
  ZipCodeServer zcs = (ZipCodeServer) ror.localise();

You need to fill in the "localise" method in the provided RemoteObjectRef.java.

ZipCodeClient
a) instantiates the stub for the remote object, ror, which it receives as a
  result of service name lookup, and then
b) invokes the appropriate methods on the stub.
 This stub will send each request to the dispatcher ("yourRMI") via the
 Communications Module (CM), by invoking CM's static method.

Thus, you also need to write the code for the CM on the client side.
The CM should be able to map the caller (i.e., a stub) to the
corresponding ROR, so that the invocation request can be forwarded to the
address (of "yourRMI") contained in the ROR.
5) Beside completing "yourRMI", what else do I have to do?

On the server side, you need to manually write the skeletons for
ZipCodeServerImpl and ZipCodeRListImpl, which are called in the while
loop of "yourRMI".

On the client side, you need to write one or more programs to implement
the functions of proxy modules, CM, and RRM (containing the table mapping
stub objects to the correponding RORs).  The CM and RRM should be general-
purpose, while the proxies are stubs for the particular servers,
ZipCodeServer and ZipCodeRList server.  As stated in 3) above, the
localise() method in RemoteObjectRef.java must be completed, in order to
convert an ROR into a stub object.

**Notes**
A) An important point to note is that all the three participants
(SimpleRegistry, the client and the server) understand the meaning of objects
(RORs) of class RemoteObjectReference, and exchange them with each other.
Each entry in the ROR tables maintained at the server and clients contains an
ROR as one of its components.

B) The project description often uses the term "marshal" and "unmarshal".
An object need not be Serializable to be marshaled. In fact, the solution
suggested in the project description uses no Serializable objects.

For example, consider the following two dimensional array:
city1, zipcode1
city2, zipcode2
 .....
If you send this array as a sequence of strings, i.e.,
city1, zipcode1, city2, zipcode2, .....
then you are marshalling the array.

To receive/send a line of text at a time over a socket connection, soc,
you can use the following chains:

 BufferedReader in =
	new BufferedReader(new InputStreamReader (soc.getInputStream()));
 PrintWriter out = new PrintWriter(soc.getOutputStream(), true);

and invoke their methods as follows:

 String line = in.readLine();
 out.println(line);

See SimpleRegistryServer.java and SimpleRegistry.java for how they are used.

C) If you are not familiar with Java's "this" reference, you should read about
 it.  It may come in handy for writing the CM on the client side.

(6) In Java RMI, in running the client, the required classes (such
as the stub class) are first searched locally, and if not found,
they are brought in from the remote codebase using an http server.
Don't I need to implement this?

No, not in this project. You can place the stub class manually in the client
machine.

(7) The author says "For marshalling and unmarshalling, you may use Java serialisation
  in some form, as noted above (but note you can not use it as it is, since *your* remote
  references are just treated as local references)."  Can you clarify this statement?

  I think by "*your* remote reference" he means a stub itself, i.e., not the data structure
  ROR that he uses.  If the client serialized its stub and sent it to the server, the server
  would have no idea what it is.