COMP 310
Fall 2016
|
HW07: Remote task
execution
|
 |
Today's example has a "compute engine" (ICompute) on the server which is served
out as a remote object. The client then sends a "compute task"
(ITask) to
the server for it to execute, returning the result to the client. The
key issue here is that the server does not know a priori what the client will
have it do.
Before starting this assignment, be sure that you
can run the demo from Lab08,
which includes configuring your computer for use with RMI.
This assignment, and all future assignments will use TCP
ports in the ranges: 2001-2002 and 2099-2102.
References:
Obtaining and Runnning the demo
The code is available by setting the svn:externals
property (under Team/Set Property) of your
src folder to "provided
https://svn.rice.edu/r/comp310/course/ComputeEngine/provided"
Be sure to set the working directory of both the
client and server launch configurations to your the "bin"
directory in your project.
Also, set both the client and engine (server) launch configurations to be
"shared" so that they will always be set correctlyu.
See
the Eclipse Resources page for directions
Ports that need to be opened (see the code for
the values):
- In-bound on Server:
- IRemoteTaskViewAdapter.BOUND_PORT_SERVER
-- Used by IRemoteTaskViewAdapter sent from
server to client to display back on server's view.
- ICompute.BOUND_PORT-- The port the
ComputeEngine is bound in the Registry.
- IRMI_Defs.CLASS_SERVER_PORT_SERVER --
The class server the server uses.
- IRMI_Defs.REGISTRY_PORT -- The port the
Registry uses on the server.
- In-bound on Client:
- IRemoteTaskViewAdapter.BOUND_PORT_CLIENT
-- Used by IRemoteTaskViewAdapter sent from
client to server to display back on client's view.
- IRMI_Defs.CLASS_SERVER_PORT_CLIENT --
The class server the client uses.
Click for full-size image

Features
- Via the remote ICompute interface, the
server will execute any ITask implementation
sent to it, returning its results in a type-safe manner.
- When a task arrives at the server, it's
setTaskViewAdapter() method is called to attach it to the server's
view, so that any status output from the task is displayed on the server's
view.
- Not only are the tasks sent from the client to the server, but also, the
ICompute interface provides a
setTextAdapter() method enables the client to send a stub of a view
adapter to the server so that the server can display information on the
client's view plus that same method will return a stub of a view adapter
that will enable the client to display information on the server's view.
- Object serialization:
- Serializable interface tells the
compiler that this object can be serialized, i.e. its data (not its
code!) can be turned into a byte stream and sent over the network.
- Code, if needed, is transmitted separately and automatically.
The client's java.rmi.server.codebase
value is imbedded in the serialized byte stream. The
receiver's Java class loader will look at this value and find the
class file server on the sender and then issue an http-type request
to download the associated class file.
- Note that the class file server does not have to be co-located
with the serialized object's sender. The class file
server can be a separate machine altogether, e.g. a central class
file repository.
- transient fields are not serialized.
- Optional readObject method in
Pi2 and GetInfo is used for
custom deserialization processes, here to reinitialize the
transient taskView
field. The server will attach its own ITaskView adapter so the transmitted task can communicate to the
server.
- IRMIUtils:
- Has services for creating and/or locating the Registry for the
client and server use, plus to obtain the local IP address in a
consistent manner across multiple operating systems.
- Has services to start and stop the RMI sub-system with minimal
effort and maximum reliability.
- Abstracts and encapsulates the Registry obtainment process.
- Uses techniques for composing lambdas to enable the methods to send
multiple messages to multiple output targets.
- Note: There are some typos still running
around where "IRMIUtils" (or its concrete
implementation, RMIUtils) are still referred
to by their old name, "RegistryFactory"
Important concepts:
Stubs retrieved from remote Registries
-- The ICompute stub that the client retrieves via
the Registry delegates its calls back to its
ComputeEngine implementation on the server.
Stubs sent and returned by stubs (stubs as factories)
-- IRemoteTaskViewAdapter stubs are both sent to the
server via a method in the ICompute stub in the
client as well as returned by the ICompute stub as a
return value. Thus a single stub can serve as a factory for all the other
stubs that are needed, eliminating the need for multitudes of objects bound in
the Registry--only a single factory needs to be
bound.
Entire objects being serialized and sent via stubs
-- the ITask objects are being completely serialized
and sent over the network from the client to the server. They are not sent
as stubs.
Automatic remote dynamic class loading of
serialized objects -- If the server does not have the code for the
concrete ITask sent to it, the RMI system settings
that the client and server set up automatically cause the code for the task to
be dynamically loaded from across the network, from the client's class server to
the server. Likewise, this is done for the stubs that are sent back and
forth.
Requirements:
- Special note for teams where the members are running a mix of
32-bit and 64-bit Java computers: You will need to use a
special "svn:ignore" property to enable the
different computers to separately and properly compile your code.
Please see the following directions on
how to set the
svn:ignore parameter to ignore
the .classpath file.
You will need to create your OWN client package,
including its controller, view and model. You can start by simply
copying the existing client package code to your own packages (be sure to rename
the package internally!) and modifying from there.
You may NOT change any of the provided code
-- you will receive a commit error if you do so!
- You are to create 3 new ITasks that can be
sent across the network from a client to a remote server to be executed.
- You may copy and modify the given view client code (in your own
packages) to accommodate your new tasks. You should not need to
modify the server code.
- You must be able to run both the client and the server on your and your
partner's machines:
- Connecting client to server on the same machine
- CConnecting client to server on different machines (either way on
your and your partner's machines).
Note that the provided.compute
package contains all the interfaces that BOTH the client and the server need to
talk to each other.
Testing
Testing RMI programs can be tricky. You can
easily be fooled into thinking that your code runs properly if you test
insufficiently. In particular, if both ends of your test contain all
the code, the remote dynamic class loading will not be tested. Here's a
more complete test:
- Create a separate project with the
unmodified demo code in it. Run
the demo code's server and test your client
against it.
- Be sure to do the above test across different machines! This
will test all aspects of your code.
Most Common Errors
- Firewall ports not open
- Launch configurations not set properly -- working directory not set.
- Editing the provided code
Grading Guidelines
- The tasks must return a value whose type is NOT
BigDecimal. The tasks should return at least 2 different
types of results. - 30 pts
- The tasks' results should be displayed on the client. - 15 pts
- The task must display some sort of status message on the server when it
is run. - 15 pts
- The task should run properly when both the client and server are on the
same machine. - 15 pts
- The task should run properly when the client and server are on different
machines. Test this between your and your partner's machines!
Your code will be tested against a course staff machine. - 15 pts
- List, in your
Readme.txt
file, the NetID's of 10 people
(individuals, not groups) with whom you have successfully tested
both your client and server (i.e. can
successfully send and process all tasks). You must test with that
person's personal computer, i.e. in the end, you must have tested against at
least 10 different computers. Different people in the same group do count
as separate individuals, except one's own partner(s) which are to be tested
as part of #5 above. - 10 pts
Note that the above requirements mean that you cannot change
anything in provided.compute package!
© 2016 by Stephen Wong