
CISC 370 Lecture Notes for Class No. 22 April 27, 2000

| Course Home | Prev Lect | Next Lect | Example Progs | Exercise Solns | CoreJava Progs Documentation |
Gen'l Docs | Java 2 APIs | Java Glossary | Term Proj Info |
- see Horstmann & Cornell,vol I, pp. 603-621 for some valuable hints on how to debug your java code.
- include lots of debugging print statements and pay attention to any output that looks fishy or that you do not understand. You can catch many bugs this way. It is a temptation to leave out debugging statements, but you it is usually a mistake to do so.
- restrict your paintComponent() methods to drawing only
- And finally an important reminder about attribution. If you are using code that you did not write, be sure to properly acknowledge its source. Failure to do this is plagiarism and could cost you dearly.
The Echo Server program discussed on pp. 156-9 of H&C vol II opens a server on port 8189 and listens indefinitely until a client connects to it. Once we compile the server code and start it running, we can then connect to it via telnet on the same machine by typing
telnet 127.0.0.1 8189
Anything that we then type in will be echoed back by the server.
If the client (telnet) and server are running on different machines, we would type
telnet strauss.udel.edu 8189
if the server were running on strauss, for example.
We can also connect to the server (from the same machine) via the SocketOpenerTest program that we discussed last time by doing
java SocketOpenerTest 127.0.0.1 8189
In this case, the SocketOpenTest will print the initial string sent to it by the server, namely the string "Hello! Enter BYE to exit." The client sends no response to the server, but waits to print more lines from the server. But the server is waiting for the client. The client then times out (after 2 secs), closes the connection, and the server then gracefully terminates.
What happens if we try to open more than one client simultaneously to the server? The server just ignores every connection after the first and when the first connection is closed, the other connections are also closed. To remedy this, we use a separate thread for each connection.
The Threaded Echo Server discussed on pp. 159-62 of H&C vol II shows how to do this.
Creating Code:
1. Design and Implement your WhateverYouWantToNameIt
class
2. Turn the WhateverYouWantToNameIt class into
a remote class as follows:
> 2.1 Create a WhateverYouWantToNameIt
interface that extends java.rmi.Remote.
> 2.1.1 Put a prototype into the interface
for each public method, from the original WhateverYouWantToNameIt class,
that is to be called remotely.
2.1.2 Each "prototype" must
have a "throws RemoteException" clause.
2.2 Change original WhateverYouWantToNameIt
class, developed in Step 1 and rename it WhateverYouWantToNameItImpl.
2.2.1 WhateverYouWantToNameItImpl
must implement WhateverYouWantToNameIt Interface created in Step 2.1.
2.2.2 Normally should extend
java.rmiserver.UnicastRemoteObject and have code for interacting with
Stubs and Skeletons.
2.2.3 Each method that implements
a method from the WhateverYouWantToNameIt class must have a "throws RemoteException"
as must each constructor including a default constructor, if any.
3. Set up the server application code - call this class
WhateverYouWantToNameItServer
3.1 Set up a Security Manager
3.2 Create remote objects i.e. instances
of the WhateverYouWantToNameItImpl class.
3.3 Register the objects with the
static method Naming.rebind(String name, Object rObj)
name = a unique name registered with the rmi registry
rObj = reference to the object being registered that is passed to WhateverYouWantToNameItImpl
4. Set up the client application with class WhateverYouWantToNameItClient
as
follows:
4.1 Set Security Manager
4.2 Get reference(s) to remote object(s)
via Naming.lookup(String name). This name is the same as the one
used in Step 3.3
4.3 Invoke remote methods on the server
via references obtained in Step 4.2
4.4 Supply a client.policy file to
the Client.
To Generate and Setup Compiled Code:
1. Compile all the *.java files with :
javac *.java or with
javac -d . *.java,
if the classes belong to a package.
2. Create stubs and skeletons with rmic:
rmic -v1.2 WhateverYouWantToNameItImpl
(i.e., use rmic on ALL *Impl files)
If your client uses(most
likely over the web) JDK 1.1, then use
rmic
WhateverYouWantToNameItImpl (i.e., use rmic on ALL *Impl files)
3. Get the server running
3.1 Start rmiregistry
rmiregistry &
Only one rmiregistry can be started at a time.
The rmiregistry is very flaky, it should be started in a directory with
no .class files and the CLASSPATH set to nothing for the time-being on
the fly. Do not change your CLASSPATH in .cshrc or autoexec.bat to do it
- simply do it from command-line. Also you cannot start more than one
rmiregistry
on one server(e.g. strauss.udel.edu)
Exception: Often a first step in checking out the code is to put
all the client, server, and stub .class files in a single directory. In
this case, you can start the RMI registry in the same directory without
resetting the CLASSPATH.
3.2 Start server application
java WhateverYouWantToNameItServer &
3.3 java ShowBindings
You can use the class
file in the directory
$CISC370HOME/CoreJavaBook/v2ch5/ShowBindings/ShowBindings.class
for this purpose. To make it easy to use from any directory add the
following alias to your .cshrc or .aliases file
alias showbindings 'java -cp $CISC370HOME/CoreJavaBook/v2ch5/ShowBindings/ ShowBindings'
Then it will only be necessary to type showbindings.
4. Move the following code to the Client Machine.
4.1 WhateverYouWantToNameItClient
4.2 All interface code
4.3 All stub classes (We can set codebase
in rmiserver to tell the client where stubs are located)
5. Start Client: java -Djava.security.policy=client.policy
WhateverYouWantToNameItClient. Of course, for this to work, you should
have a security policy file called client.policy in the directory where
you execute this command.
Acknowledgement and Limitation
The list of instructions given above for creating an RMI client/server application in Java 1.2 (aka Java 2.0) was first given in my course in 1999 Spring for Java 1.1. Vikas Agrawal, a CIS grad student, revised the instructions for use with Java 1.2. Because there have been some changes in the RMI mechanisms between Java 1.1 and Java 1.2, the above instructions are not accurate for use with Java 1.1 (although the overall approach is still much the same).
Back to the
CISC 370 homepage.
This page has been accessed
times since 25 April 2000.
Corrections, suggestions and comments to Bob Caviness
Copyright
2000 B. F. Caviness